mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
New build scripts
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5282 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
476
source/web/scripts/ajax/dojo/src/widget/PopupContainer.js
Normal file
476
source/web/scripts/ajax/dojo/src/widget/PopupContainer.js
Normal file
@@ -0,0 +1,476 @@
|
||||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.PopupContainer");
|
||||
|
||||
dojo.require("dojo.html.style");
|
||||
dojo.require("dojo.html.layout");
|
||||
dojo.require("dojo.html.selection");
|
||||
dojo.require("dojo.html.iframe");
|
||||
dojo.require("dojo.event.*");
|
||||
dojo.require("dojo.widget.*");
|
||||
dojo.require("dojo.widget.HtmlWidget");
|
||||
|
||||
dojo.declare(
|
||||
"dojo.widget.PopupContainerBase",
|
||||
null,
|
||||
function(){
|
||||
this.queueOnAnimationFinish = [];
|
||||
},
|
||||
{
|
||||
// summary:
|
||||
// PopupContainerBase is the mixin class which provide popup behaviors:
|
||||
// it can open in a given position x,y or around a given node.
|
||||
// In addition, it handles animation and IE bleed through workaround.
|
||||
// description:
|
||||
// This class can not be used standalone: it should be mixed-in to a
|
||||
// dojo.widget.HtmlWidget. Use PopupContainer instead if you want a
|
||||
// a standalone popup widget
|
||||
|
||||
isContainer: true,
|
||||
templateString: '<div dojoAttachPoint="containerNode" style="display:none;position:absolute;" class="dojoPopupContainer" ></div>',
|
||||
|
||||
// isShowingNow: Boolean: whether this popup is shown
|
||||
isShowingNow: false,
|
||||
|
||||
// currentSubpopup: Widget: the shown sub popup if any
|
||||
currentSubpopup: null,
|
||||
|
||||
// beginZIndex: Integer: the minimal popup zIndex
|
||||
beginZIndex: 1000,
|
||||
|
||||
// parentPopup: Widget: parent popup widget
|
||||
parentPopup: null,
|
||||
|
||||
// parent: Widget: the widget that caused me to be displayed; the logical parent.
|
||||
parent: null,
|
||||
|
||||
// popupIndex: Integer: level of sub popup
|
||||
popupIndex: 0,
|
||||
|
||||
// aroundBox: dojo.html.boxSizing: which bounding box to use for open aroundNode. By default use BORDER box of the aroundNode
|
||||
aroundBox: dojo.html.boxSizing.BORDER_BOX,
|
||||
|
||||
// openedForWindow: Object: in which window the open() is triggered
|
||||
openedForWindow: null,
|
||||
|
||||
processKey: function(/*Event*/evt){
|
||||
// summary: key event handler
|
||||
return false;
|
||||
},
|
||||
|
||||
applyPopupBasicStyle: function(){
|
||||
// summary: apply necessary css rules to the top domNode
|
||||
// description:
|
||||
// this function should be called in sub class where a custom
|
||||
// templateString/templateStringPath is used (see Tooltip widget)
|
||||
with(this.domNode.style){
|
||||
display = 'none';
|
||||
position = 'absolute';
|
||||
}
|
||||
},
|
||||
|
||||
aboutToShow: function() {
|
||||
// summary: connect to this stub to modify the content of the popup
|
||||
},
|
||||
|
||||
open: function(/*Integer*/x, /*Integer*/y, /*DomNode*/parent, /*Object*/explodeSrc, /*String?*/orient, /*Array?*/padding){
|
||||
// summary:
|
||||
// Open the popup at position (x,y), relative to dojo.body()
|
||||
// Or open(node, parent, explodeSrc, aroundOrient) to open
|
||||
// around node
|
||||
if (this.isShowingNow){ return; }
|
||||
|
||||
// if I click right button and menu is opened, then it gets 2 commands: close -> open
|
||||
// so close enables animation and next "open" is put to queue to occur at new location
|
||||
if(this.animationInProgress){
|
||||
this.queueOnAnimationFinish.push(this.open, arguments);
|
||||
return;
|
||||
}
|
||||
|
||||
this.aboutToShow();
|
||||
|
||||
var around = false, node, aroundOrient;
|
||||
if(typeof x == 'object'){
|
||||
node = x;
|
||||
aroundOrient = explodeSrc;
|
||||
explodeSrc = parent;
|
||||
parent = y;
|
||||
around = true;
|
||||
}
|
||||
|
||||
// save this so that the focus can be returned
|
||||
this.parent = parent;
|
||||
|
||||
// for unknown reasons even if the domNode is attached to the body in postCreate(),
|
||||
// it's not attached here, so have to attach it here.
|
||||
dojo.body().appendChild(this.domNode);
|
||||
|
||||
// if explodeSrc isn't specified then explode from my parent widget
|
||||
explodeSrc = explodeSrc || parent["domNode"] || [];
|
||||
|
||||
//keep track of parent popup to decided whether this is a top level popup
|
||||
var parentPopup = null;
|
||||
this.isTopLevel = true;
|
||||
while(parent){
|
||||
if(parent !== this && (parent.setOpenedSubpopup != undefined && parent.applyPopupBasicStyle != undefined)){
|
||||
parentPopup = parent;
|
||||
this.isTopLevel = false;
|
||||
parentPopup.setOpenedSubpopup(this);
|
||||
break;
|
||||
}
|
||||
parent = parent.parent;
|
||||
}
|
||||
|
||||
this.parentPopup = parentPopup;
|
||||
this.popupIndex = parentPopup ? parentPopup.popupIndex + 1 : 1;
|
||||
|
||||
if(this.isTopLevel){
|
||||
var button = dojo.html.isNode(explodeSrc) ? explodeSrc : null;
|
||||
dojo.widget.PopupManager.opened(this, button);
|
||||
}
|
||||
|
||||
//Store the current selection and restore it before the action for a menu item
|
||||
//is executed. This is required as clicking on an menu item deselects current selection
|
||||
if(this.isTopLevel && !dojo.withGlobal(this.openedForWindow||dojo.global(), dojo.html.selection.isCollapsed)){
|
||||
this._bookmark = dojo.withGlobal(this.openedForWindow||dojo.global(), dojo.html.selection.getBookmark);
|
||||
}else{
|
||||
this._bookmark = null;
|
||||
}
|
||||
|
||||
//convert explodeSrc from format [x, y] to
|
||||
//{left: x, top: y, width: 0, height: 0} which is the new
|
||||
//format required by dojo.html.toCoordinateObject
|
||||
if(explodeSrc instanceof Array){
|
||||
explodeSrc = {left: explodeSrc[0], top: explodeSrc[1], width: 0, height: 0};
|
||||
}
|
||||
|
||||
// display temporarily, and move into position, then hide again
|
||||
with(this.domNode.style){
|
||||
display="";
|
||||
zIndex = this.beginZIndex + this.popupIndex;
|
||||
}
|
||||
|
||||
if(around){
|
||||
this.move(node, padding, aroundOrient);
|
||||
}else{
|
||||
this.move(x, y, padding, orient);
|
||||
}
|
||||
this.domNode.style.display="none";
|
||||
|
||||
this.explodeSrc = explodeSrc;
|
||||
|
||||
// then use the user defined method to display it
|
||||
this.show();
|
||||
|
||||
this.isShowingNow = true;
|
||||
},
|
||||
|
||||
// TODOC: move(node, padding, aroundOrient) how to do this?
|
||||
move: function(/*Int*/x, /*Int*/y, /*Integer?*/padding, /*String?*/orient){
|
||||
// summary: calculate where to place the popup
|
||||
|
||||
var around = (typeof x == "object");
|
||||
if(around){
|
||||
var aroundOrient=padding;
|
||||
var node=x;
|
||||
padding=y;
|
||||
if(!aroundOrient){ //By default, attempt to open above the aroundNode, or below
|
||||
aroundOrient = {'BL': 'TL', 'TL': 'BL'};
|
||||
}
|
||||
dojo.html.placeOnScreenAroundElement(this.domNode, node, padding, this.aroundBox, aroundOrient);
|
||||
}else{
|
||||
if(!orient){ orient = 'TL,TR,BL,BR';}
|
||||
dojo.html.placeOnScreen(this.domNode, x, y, padding, true, orient);
|
||||
}
|
||||
},
|
||||
|
||||
close: function(/*Boolean?*/force){
|
||||
// summary: hide the popup
|
||||
if(force){
|
||||
this.domNode.style.display="none";
|
||||
}
|
||||
|
||||
// If we are in the process of opening the menu and we are asked to close it
|
||||
if(this.animationInProgress){
|
||||
this.queueOnAnimationFinish.push(this.close, []);
|
||||
return;
|
||||
}
|
||||
|
||||
this.closeSubpopup(force);
|
||||
this.hide();
|
||||
if(this.bgIframe){
|
||||
this.bgIframe.hide();
|
||||
this.bgIframe.size({left: 0, top: 0, width: 0, height: 0});
|
||||
}
|
||||
if(this.isTopLevel){
|
||||
dojo.widget.PopupManager.closed(this);
|
||||
}
|
||||
this.isShowingNow = false;
|
||||
// return focus to the widget that opened the menu
|
||||
|
||||
if(this.parent){
|
||||
setTimeout(
|
||||
dojo.lang.hitch(this,
|
||||
function(){
|
||||
try{
|
||||
if(this.parent['focus']){
|
||||
this.parent.focus();
|
||||
}else{
|
||||
this.parent.domNode.focus();
|
||||
}
|
||||
}catch(e){dojo.debug("No idea how to focus to parent", e);}
|
||||
}
|
||||
),
|
||||
10
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//do not need to restore if current selection is not empty
|
||||
//(use keyboard to select a menu item)
|
||||
if(this._bookmark && dojo.withGlobal(this.openedForWindow||dojo.global(), dojo.html.selection.isCollapsed)){
|
||||
if(this.openedForWindow){
|
||||
this.openedForWindow.focus()
|
||||
}
|
||||
try{
|
||||
dojo.withGlobal(this.openedForWindow||dojo.global(), "moveToBookmark", dojo.html.selection, [this._bookmark]);
|
||||
}catch(e){
|
||||
/*squelch IE internal error, see http://trac.dojotoolkit.org/ticket/1984 */
|
||||
}
|
||||
}
|
||||
this._bookmark = null;
|
||||
},
|
||||
|
||||
closeAll: function(/*Boolean?*/force){
|
||||
// summary: hide all popups including sub ones
|
||||
if (this.parentPopup){
|
||||
this.parentPopup.closeAll(force);
|
||||
}else{
|
||||
this.close(force);
|
||||
}
|
||||
},
|
||||
|
||||
setOpenedSubpopup: function(/*Widget*/popup) {
|
||||
// summary: used by sub popup to set currentSubpopup in the parent popup
|
||||
this.currentSubpopup = popup;
|
||||
},
|
||||
|
||||
closeSubpopup: function(/*Boolean?*/force) {
|
||||
// summary: close opened sub popup
|
||||
if(this.currentSubpopup == null){ return; }
|
||||
|
||||
this.currentSubpopup.close(force);
|
||||
this.currentSubpopup = null;
|
||||
},
|
||||
|
||||
onShow: function() {
|
||||
dojo.widget.PopupContainer.superclass.onShow.apply(this, arguments);
|
||||
// With some animation (wipe), after close, the size of the domnode is 0
|
||||
// and next time when shown, the open() function can not determine
|
||||
// the correct place to popup, so we store the opened size here and
|
||||
// set it after close (in function onHide())
|
||||
this.openedSize={w: this.domNode.style.width, h: this.domNode.style.height};
|
||||
// prevent IE bleed through
|
||||
if(dojo.render.html.ie){
|
||||
if(!this.bgIframe){
|
||||
this.bgIframe = new dojo.html.BackgroundIframe();
|
||||
this.bgIframe.setZIndex(this.domNode);
|
||||
}
|
||||
|
||||
this.bgIframe.size(this.domNode);
|
||||
this.bgIframe.show();
|
||||
}
|
||||
this.processQueue();
|
||||
},
|
||||
|
||||
processQueue: function() {
|
||||
// summary: do events from queue
|
||||
if (!this.queueOnAnimationFinish.length) return;
|
||||
|
||||
var func = this.queueOnAnimationFinish.shift();
|
||||
var args = this.queueOnAnimationFinish.shift();
|
||||
|
||||
func.apply(this, args);
|
||||
},
|
||||
|
||||
onHide: function() {
|
||||
dojo.widget.HtmlWidget.prototype.onHide.call(this);
|
||||
|
||||
//restore size of the domnode, see comment in
|
||||
//function onShow()
|
||||
if(this.openedSize){
|
||||
with(this.domNode.style){
|
||||
width=this.openedSize.w;
|
||||
height=this.openedSize.h;
|
||||
}
|
||||
}
|
||||
|
||||
this.processQueue();
|
||||
}
|
||||
});
|
||||
|
||||
dojo.widget.defineWidget(
|
||||
"dojo.widget.PopupContainer",
|
||||
[dojo.widget.HtmlWidget, dojo.widget.PopupContainerBase], {
|
||||
// summary: dojo.widget.PopupContainer is the widget version of dojo.widget.PopupContainerBase
|
||||
});
|
||||
|
||||
|
||||
dojo.widget.PopupManager = new function(){
|
||||
// summary:
|
||||
// the popup manager makes sure we don't have several popups
|
||||
// open at once. the root popup in an opening sequence calls
|
||||
// opened(). when a root menu closes it calls closed(). then
|
||||
// everything works. lovely.
|
||||
|
||||
this.currentMenu = null;
|
||||
this.currentButton = null; // button that opened current menu (if any)
|
||||
this.currentFocusMenu = null; // the (sub)menu which receives key events
|
||||
this.focusNode = null;
|
||||
this.registeredWindows = [];
|
||||
|
||||
this.registerWin = function(/*Window*/win){
|
||||
// summary: register a window so that when clicks/scroll in it, the popup can be closed automatically
|
||||
if(!win.__PopupManagerRegistered)
|
||||
{
|
||||
dojo.event.connect(win.document, 'onmousedown', this, 'onClick');
|
||||
dojo.event.connect(win, "onscroll", this, "onClick");
|
||||
dojo.event.connect(win.document, "onkey", this, 'onKey');
|
||||
win.__PopupManagerRegistered = true;
|
||||
this.registeredWindows.push(win);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
*/
|
||||
this.registerAllWindows = function(/*Window*/targetWindow){
|
||||
// summary:
|
||||
// This function register all the iframes and the top window,
|
||||
// so that whereever the user clicks in the page, the popup
|
||||
// menu will be closed
|
||||
// In case you add an iframe after onload event, please call
|
||||
// dojo.widget.PopupManager.registerWin manually
|
||||
|
||||
//starting from window.top, clicking everywhere in this page
|
||||
//should close popup menus
|
||||
if(!targetWindow) { //see comment below
|
||||
targetWindow = dojo.html.getDocumentWindow(window.top && window.top.document || window.document);
|
||||
}
|
||||
|
||||
this.registerWin(targetWindow);
|
||||
|
||||
for (var i = 0; i < targetWindow.frames.length; i++){
|
||||
try{
|
||||
//do not remove dojo.html.getDocumentWindow, see comment in it
|
||||
var win = dojo.html.getDocumentWindow(targetWindow.frames[i].document);
|
||||
if(win){
|
||||
this.registerAllWindows(win);
|
||||
}
|
||||
}catch(e){ /* squelch error for cross domain iframes */ }
|
||||
}
|
||||
};
|
||||
|
||||
this.unRegisterWin = function(/*Window*/win){
|
||||
// summary: remove listeners on the registered window
|
||||
if(win.__PopupManagerRegistered)
|
||||
{
|
||||
dojo.event.disconnect(win.document, 'onmousedown', this, 'onClick');
|
||||
dojo.event.disconnect(win, "onscroll", this, "onClick");
|
||||
dojo.event.disconnect(win.document, "onkey", this, 'onKey');
|
||||
win.__PopupManagerRegistered = false;
|
||||
}
|
||||
};
|
||||
|
||||
this.unRegisterAllWindows = function(){
|
||||
// summary: remove listeners on all the registered windows
|
||||
for(var i=0;i<this.registeredWindows.length;++i){
|
||||
this.unRegisterWin(this.registeredWindows[i]);
|
||||
}
|
||||
this.registeredWindows = [];
|
||||
};
|
||||
|
||||
dojo.addOnLoad(this, "registerAllWindows");
|
||||
dojo.addOnUnload(this, "unRegisterAllWindows");
|
||||
|
||||
this.closed = function(/*Widget*/menu){
|
||||
// summary: notify the manager that menu is closed
|
||||
if (this.currentMenu == menu){
|
||||
this.currentMenu = null;
|
||||
this.currentButton = null;
|
||||
this.currentFocusMenu = null;
|
||||
}
|
||||
};
|
||||
|
||||
this.opened = function(/*Widget*/menu, /*DomNode*/button){
|
||||
// summary: sets the current opened popup
|
||||
if (menu == this.currentMenu){ return; }
|
||||
|
||||
if (this.currentMenu){
|
||||
this.currentMenu.close();
|
||||
}
|
||||
|
||||
this.currentMenu = menu;
|
||||
this.currentFocusMenu = menu;
|
||||
this.currentButton = button;
|
||||
};
|
||||
|
||||
this.setFocusedMenu = function(/*Widget*/menu){
|
||||
// summary:
|
||||
// Set the current focused popup, This is used by popups which supports keyboard navigation
|
||||
this.currentFocusMenu = menu;
|
||||
};
|
||||
|
||||
this.onKey = function(/*Event*/e){
|
||||
if (!e.key) { return; }
|
||||
if(!this.currentMenu || !this.currentMenu.isShowingNow){ return; }
|
||||
|
||||
var m = this.currentFocusMenu;
|
||||
while (m){
|
||||
if(m.processKey(e)){
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
break;
|
||||
}
|
||||
m = m.parentPopup;
|
||||
}
|
||||
},
|
||||
|
||||
this.onClick = function(/*Event*/e){
|
||||
if (!this.currentMenu){ return; }
|
||||
|
||||
var scrolloffset = dojo.html.getScroll().offset;
|
||||
|
||||
// starting from the base menu, perform a hit test
|
||||
// and exit when one succeeds
|
||||
|
||||
var m = this.currentMenu;
|
||||
|
||||
while (m){
|
||||
if(dojo.html.overElement(m.domNode, e) || dojo.html.isDescendantOf(e.target, m.domNode)){
|
||||
return;
|
||||
}
|
||||
m = m.currentSubpopup;
|
||||
}
|
||||
|
||||
// Also, if user clicked the button that opened this menu, then
|
||||
// that button will send the menu a close() command, so this code
|
||||
// shouldn't try to close the menu. Closing twice messes up animation.
|
||||
if (this.currentButton && dojo.html.overElement(this.currentButton, e)){
|
||||
return;
|
||||
}
|
||||
|
||||
// the click didn't fall within the open menu tree
|
||||
// so close it
|
||||
|
||||
this.currentMenu.close();
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user