diff options
Diffstat (limited to 'lib/dijit/Menu.js')
-rw-r--r-- | lib/dijit/Menu.js | 718 |
1 files changed, 2 insertions, 716 deletions
diff --git a/lib/dijit/Menu.js b/lib/dijit/Menu.js index c5a48660e..a576da5c3 100644 --- a/lib/dijit/Menu.js +++ b/lib/dijit/Menu.js @@ -1,716 +1,2 @@ -/* - Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved. - Available via Academic Free License >= 2.1 OR the modified BSD license. - see: http://dojotoolkit.org/license for details -*/ - - -if(!dojo._hasResource["dijit.Menu"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. -dojo._hasResource["dijit.Menu"] = true; -dojo.provide("dijit.Menu"); -dojo.require("dojo.window"); -dojo.require("dijit._Widget"); -dojo.require("dijit._KeyNavContainer"); -dojo.require("dijit._Templated"); -dojo.require("dijit.MenuItem"); -dojo.require("dijit.PopupMenuItem"); -dojo.require("dijit.CheckedMenuItem"); -dojo.require("dijit.MenuSeparator"); - - -// "dijit/MenuItem", "dijit/PopupMenuItem", "dijit/CheckedMenuItem", "dijit/MenuSeparator" for Back-compat (TODO: remove in 2.0) - -dojo.declare("dijit._MenuBase", - [dijit._Widget, dijit._Templated, dijit._KeyNavContainer], -{ - // summary: - // Base class for Menu and MenuBar - - // parentMenu: [readonly] Widget - // pointer to menu that displayed me - parentMenu: null, - - // popupDelay: Integer - // number of milliseconds before hovering (without clicking) causes the popup to automatically open. - popupDelay: 500, - - startup: function(){ - if(this._started){ return; } - - dojo.forEach(this.getChildren(), function(child){ child.startup(); }); - this.startupKeyNavChildren(); - - this.inherited(arguments); - }, - - onExecute: function(){ - // summary: - // Attach point for notification about when a menu item has been executed. - // This is an internal mechanism used for Menus to signal to their parent to - // close them, because they are about to execute the onClick handler. In - // general developers should not attach to or override this method. - // tags: - // protected - }, - - onCancel: function(/*Boolean*/ closeAll){ - // summary: - // Attach point for notification about when the user cancels the current menu - // This is an internal mechanism used for Menus to signal to their parent to - // close them. In general developers should not attach to or override this method. - // tags: - // protected - }, - - _moveToPopup: function(/*Event*/ evt){ - // summary: - // This handles the right arrow key (left arrow key on RTL systems), - // which will either open a submenu, or move to the next item in the - // ancestor MenuBar - // tags: - // private - - if(this.focusedChild && this.focusedChild.popup && !this.focusedChild.disabled){ - this.focusedChild._onClick(evt); - }else{ - var topMenu = this._getTopMenu(); - if(topMenu && topMenu._isMenuBar){ - topMenu.focusNext(); - } - } - }, - - _onPopupHover: function(/*Event*/ evt){ - // summary: - // This handler is called when the mouse moves over the popup. - // tags: - // private - - // if the mouse hovers over a menu popup that is in pending-close state, - // then stop the close operation. - // This can't be done in onItemHover since some popup targets don't have MenuItems (e.g. ColorPicker) - if(this.currentPopup && this.currentPopup._pendingClose_timer){ - var parentMenu = this.currentPopup.parentMenu; - // highlight the parent menu item pointing to this popup - if(parentMenu.focusedChild){ - parentMenu.focusedChild._setSelected(false); - } - parentMenu.focusedChild = this.currentPopup.from_item; - parentMenu.focusedChild._setSelected(true); - // cancel the pending close - this._stopPendingCloseTimer(this.currentPopup); - } - }, - - onItemHover: function(/*MenuItem*/ item){ - // summary: - // Called when cursor is over a MenuItem. - // tags: - // protected - - // Don't do anything unless user has "activated" the menu by: - // 1) clicking it - // 2) opening it from a parent menu (which automatically focuses it) - if(this.isActive){ - this.focusChild(item); - if(this.focusedChild.popup && !this.focusedChild.disabled && !this.hover_timer){ - this.hover_timer = setTimeout(dojo.hitch(this, "_openPopup"), this.popupDelay); - } - } - // if the user is mixing mouse and keyboard navigation, - // then the menu may not be active but a menu item has focus, - // but it's not the item that the mouse just hovered over. - // To avoid both keyboard and mouse selections, use the latest. - if(this.focusedChild){ - this.focusChild(item); - } - this._hoveredChild = item; - }, - - _onChildBlur: function(item){ - // summary: - // Called when a child MenuItem becomes inactive because focus - // has been removed from the MenuItem *and* it's descendant menus. - // tags: - // private - this._stopPopupTimer(); - item._setSelected(false); - // Close all popups that are open and descendants of this menu - var itemPopup = item.popup; - if(itemPopup){ - this._stopPendingCloseTimer(itemPopup); - itemPopup._pendingClose_timer = setTimeout(function(){ - itemPopup._pendingClose_timer = null; - if(itemPopup.parentMenu){ - itemPopup.parentMenu.currentPopup = null; - } - dijit.popup.close(itemPopup); // this calls onClose - }, this.popupDelay); - } - }, - - onItemUnhover: function(/*MenuItem*/ item){ - // summary: - // Callback fires when mouse exits a MenuItem - // tags: - // protected - - if(this.isActive){ - this._stopPopupTimer(); - } - if(this._hoveredChild == item){ this._hoveredChild = null; } - }, - - _stopPopupTimer: function(){ - // summary: - // Cancels the popup timer because the user has stop hovering - // on the MenuItem, etc. - // tags: - // private - if(this.hover_timer){ - clearTimeout(this.hover_timer); - this.hover_timer = null; - } - }, - - _stopPendingCloseTimer: function(/*dijit._Widget*/ popup){ - // summary: - // Cancels the pending-close timer because the close has been preempted - // tags: - // private - if(popup._pendingClose_timer){ - clearTimeout(popup._pendingClose_timer); - popup._pendingClose_timer = null; - } - }, - - _stopFocusTimer: function(){ - // summary: - // Cancels the pending-focus timer because the menu was closed before focus occured - // tags: - // private - if(this._focus_timer){ - clearTimeout(this._focus_timer); - this._focus_timer = null; - } - }, - - _getTopMenu: function(){ - // summary: - // Returns the top menu in this chain of Menus - // tags: - // private - for(var top=this; top.parentMenu; top=top.parentMenu); - return top; - }, - - onItemClick: function(/*dijit._Widget*/ item, /*Event*/ evt){ - // summary: - // Handle clicks on an item. - // tags: - // private - - // this can't be done in _onFocus since the _onFocus events occurs asynchronously - if(typeof this.isShowingNow == 'undefined'){ // non-popup menu - this._markActive(); - } - - this.focusChild(item); - - if(item.disabled){ return false; } - - if(item.popup){ - this._openPopup(); - }else{ - // before calling user defined handler, close hierarchy of menus - // and restore focus to place it was when menu was opened - this.onExecute(); - - // user defined handler for click - item.onClick(evt); - } - }, - - _openPopup: function(){ - // summary: - // Open the popup to the side of/underneath the current menu item - // tags: - // protected - - this._stopPopupTimer(); - var from_item = this.focusedChild; - if(!from_item){ return; } // the focused child lost focus since the timer was started - var popup = from_item.popup; - if(popup.isShowingNow){ return; } - if(this.currentPopup){ - this._stopPendingCloseTimer(this.currentPopup); - dijit.popup.close(this.currentPopup); - } - popup.parentMenu = this; - popup.from_item = from_item; // helps finding the parent item that should be focused for this popup - var self = this; - dijit.popup.open({ - parent: this, - popup: popup, - around: from_item.domNode, - orient: this._orient || (this.isLeftToRight() ? - {'TR': 'TL', 'TL': 'TR', 'BR': 'BL', 'BL': 'BR'} : - {'TL': 'TR', 'TR': 'TL', 'BL': 'BR', 'BR': 'BL'}), - onCancel: function(){ // called when the child menu is canceled - // set isActive=false (_closeChild vs _cleanUp) so that subsequent hovering will NOT open child menus - // which seems aligned with the UX of most applications (e.g. notepad, wordpad, paint shop pro) - self.focusChild(from_item); // put focus back on my node - self._cleanUp(); // close the submenu (be sure this is done _after_ focus is moved) - from_item._setSelected(true); // oops, _cleanUp() deselected the item - self.focusedChild = from_item; // and unset focusedChild - }, - onExecute: dojo.hitch(this, "_cleanUp") - }); - - this.currentPopup = popup; - // detect mouseovers to handle lazy mouse movements that temporarily focus other menu items - popup.connect(popup.domNode, "onmouseenter", dojo.hitch(self, "_onPopupHover")); // cleaned up when the popped-up widget is destroyed on close - - if(popup.focus){ - // If user is opening the popup via keyboard (right arrow, or down arrow for MenuBar), - // if the cursor happens to collide with the popup, it will generate an onmouseover event - // even though the mouse wasn't moved. Use a setTimeout() to call popup.focus so that - // our focus() call overrides the onmouseover event, rather than vice-versa. (#8742) - popup._focus_timer = setTimeout(dojo.hitch(popup, function(){ - this._focus_timer = null; - this.focus(); - }), 0); - } - }, - - _markActive: function(){ - // summary: - // Mark this menu's state as active. - // Called when this Menu gets focus from: - // 1) clicking it (mouse or via space/arrow key) - // 2) being opened by a parent menu. - // This is not called just from mouse hover. - // Focusing a menu via TAB does NOT automatically set isActive - // since TAB is a navigation operation and not a selection one. - // For Windows apps, pressing the ALT key focuses the menubar - // menus (similar to TAB navigation) but the menu is not active - // (ie no dropdown) until an item is clicked. - this.isActive = true; - dojo.replaceClass(this.domNode, "dijitMenuActive", "dijitMenuPassive"); - }, - - onOpen: function(/*Event*/ e){ - // summary: - // Callback when this menu is opened. - // This is called by the popup manager as notification that the menu - // was opened. - // tags: - // private - - this.isShowingNow = true; - this._markActive(); - }, - - _markInactive: function(){ - // summary: - // Mark this menu's state as inactive. - this.isActive = false; // don't do this in _onBlur since the state is pending-close until we get here - dojo.replaceClass(this.domNode, "dijitMenuPassive", "dijitMenuActive"); - }, - - onClose: function(){ - // summary: - // Callback when this menu is closed. - // This is called by the popup manager as notification that the menu - // was closed. - // tags: - // private - - this._stopFocusTimer(); - this._markInactive(); - this.isShowingNow = false; - this.parentMenu = null; - }, - - _closeChild: function(){ - // summary: - // Called when submenu is clicked or focus is lost. Close hierarchy of menus. - // tags: - // private - this._stopPopupTimer(); - - var fromItem = this.focusedChild && this.focusedChild.from_item; - - if(this.currentPopup){ - // If focus is on my child menu then move focus to me, - // because IE doesn't like it when you display:none a node with focus - if(dijit._curFocus && dojo.isDescendant(dijit._curFocus, this.currentPopup.domNode)){ - this.focusedChild.focusNode.focus(); - } - // Close all popups that are open and descendants of this menu - dijit.popup.close(this.currentPopup); - this.currentPopup = null; - } - - if(this.focusedChild){ // unhighlight the focused item - this.focusedChild._setSelected(false); - this.focusedChild._onUnhover(); - this.focusedChild = null; - } - }, - - _onItemFocus: function(/*MenuItem*/ item){ - // summary: - // Called when child of this Menu gets focus from: - // 1) clicking it - // 2) tabbing into it - // 3) being opened by a parent menu. - // This is not called just from mouse hover. - if(this._hoveredChild && this._hoveredChild != item){ - this._hoveredChild._onUnhover(); // any previous mouse movement is trumped by focus selection - } - }, - - _onBlur: function(){ - // summary: - // Called when focus is moved away from this Menu and it's submenus. - // tags: - // protected - this._cleanUp(); - this.inherited(arguments); - }, - - _cleanUp: function(){ - // summary: - // Called when the user is done with this menu. Closes hierarchy of menus. - // tags: - // private - - this._closeChild(); // don't call this.onClose since that's incorrect for MenuBar's that never close - if(typeof this.isShowingNow == 'undefined'){ // non-popup menu doesn't call onClose - this._markInactive(); - } - } -}); - -dojo.declare("dijit.Menu", - dijit._MenuBase, - { - // summary - // A context menu you can assign to multiple elements - - // TODO: most of the code in here is just for context menu (right-click menu) - // support. In retrospect that should have been a separate class (dijit.ContextMenu). - // Split them for 2.0 - - constructor: function(){ - this._bindings = []; - }, - - templateString: dojo.cache("dijit", "templates/Menu.html", "<table class=\"dijit dijitMenu dijitMenuPassive dijitReset dijitMenuTable\" role=\"menu\" tabIndex=\"${tabIndex}\" dojoAttachEvent=\"onkeypress:_onKeyPress\" cellspacing=\"0\">\n\t<tbody class=\"dijitReset\" dojoAttachPoint=\"containerNode\"></tbody>\n</table>\n"), - - baseClass: "dijitMenu", - - // targetNodeIds: [const] String[] - // Array of dom node ids of nodes to attach to. - // Fill this with nodeIds upon widget creation and it becomes context menu for those nodes. - targetNodeIds: [], - - // contextMenuForWindow: [const] Boolean - // If true, right clicking anywhere on the window will cause this context menu to open. - // If false, must specify targetNodeIds. - contextMenuForWindow: false, - - // leftClickToOpen: [const] Boolean - // If true, menu will open on left click instead of right click, similiar to a file menu. - leftClickToOpen: false, - - // refocus: Boolean - // When this menu closes, re-focus the element which had focus before it was opened. - refocus: true, - - postCreate: function(){ - if(this.contextMenuForWindow){ - this.bindDomNode(dojo.body()); - }else{ - // TODO: should have _setTargetNodeIds() method to handle initialization and a possible - // later set('targetNodeIds', ...) call. There's also a problem that targetNodeIds[] - // gets stale after calls to bindDomNode()/unBindDomNode() as it still is just the original list (see #9610) - dojo.forEach(this.targetNodeIds, this.bindDomNode, this); - } - var k = dojo.keys, l = this.isLeftToRight(); - this._openSubMenuKey = l ? k.RIGHT_ARROW : k.LEFT_ARROW; - this._closeSubMenuKey = l ? k.LEFT_ARROW : k.RIGHT_ARROW; - this.connectKeyNavHandlers([k.UP_ARROW], [k.DOWN_ARROW]); - }, - - _onKeyPress: function(/*Event*/ evt){ - // summary: - // Handle keyboard based menu navigation. - // tags: - // protected - - if(evt.ctrlKey || evt.altKey){ return; } - - switch(evt.charOrCode){ - case this._openSubMenuKey: - this._moveToPopup(evt); - dojo.stopEvent(evt); - break; - case this._closeSubMenuKey: - if(this.parentMenu){ - if(this.parentMenu._isMenuBar){ - this.parentMenu.focusPrev(); - }else{ - this.onCancel(false); - } - }else{ - dojo.stopEvent(evt); - } - break; - } - }, - - // thanks burstlib! - _iframeContentWindow: function(/* HTMLIFrameElement */iframe_el){ - // summary: - // Returns the window reference of the passed iframe - // tags: - // private - var win = dojo.window.get(this._iframeContentDocument(iframe_el)) || - // Moz. TODO: is this available when defaultView isn't? - this._iframeContentDocument(iframe_el)['__parent__'] || - (iframe_el.name && dojo.doc.frames[iframe_el.name]) || null; - return win; // Window - }, - - _iframeContentDocument: function(/* HTMLIFrameElement */iframe_el){ - // summary: - // Returns a reference to the document object inside iframe_el - // tags: - // protected - var doc = iframe_el.contentDocument // W3 - || (iframe_el.contentWindow && iframe_el.contentWindow.document) // IE - || (iframe_el.name && dojo.doc.frames[iframe_el.name] && dojo.doc.frames[iframe_el.name].document) - || null; - return doc; // HTMLDocument - }, - - bindDomNode: function(/*String|DomNode*/ node){ - // summary: - // Attach menu to given node - node = dojo.byId(node); - - var cn; // Connect node - - // Support context menus on iframes. Rather than binding to the iframe itself we need - // to bind to the <body> node inside the iframe. - if(node.tagName.toLowerCase() == "iframe"){ - var iframe = node, - win = this._iframeContentWindow(iframe); - cn = dojo.withGlobal(win, dojo.body); - }else{ - - // To capture these events at the top level, attach to <html>, not <body>. - // Otherwise right-click context menu just doesn't work. - cn = (node == dojo.body() ? dojo.doc.documentElement : node); - } - - - // "binding" is the object to track our connection to the node (ie, the parameter to bindDomNode()) - var binding = { - node: node, - iframe: iframe - }; - - // Save info about binding in _bindings[], and make node itself record index(+1) into - // _bindings[] array. Prefix w/_dijitMenu to avoid setting an attribute that may - // start with a number, which fails on FF/safari. - dojo.attr(node, "_dijitMenu" + this.id, this._bindings.push(binding)); - - // Setup the connections to monitor click etc., unless we are connecting to an iframe which hasn't finished - // loading yet, in which case we need to wait for the onload event first, and then connect - // On linux Shift-F10 produces the oncontextmenu event, but on Windows it doesn't, so - // we need to monitor keyboard events in addition to the oncontextmenu event. - var doConnects = dojo.hitch(this, function(cn){ - return [ - // TODO: when leftClickToOpen is true then shouldn't space/enter key trigger the menu, - // rather than shift-F10? - dojo.connect(cn, this.leftClickToOpen ? "onclick" : "oncontextmenu", this, function(evt){ - // Schedule context menu to be opened unless it's already been scheduled from onkeydown handler - dojo.stopEvent(evt); - this._scheduleOpen(evt.target, iframe, {x: evt.pageX, y: evt.pageY}); - }), - dojo.connect(cn, "onkeydown", this, function(evt){ - if(evt.shiftKey && evt.keyCode == dojo.keys.F10){ - dojo.stopEvent(evt); - this._scheduleOpen(evt.target, iframe); // no coords - open near target node - } - }) - ]; - }); - binding.connects = cn ? doConnects(cn) : []; - - if(iframe){ - // Setup handler to [re]bind to the iframe when the contents are initially loaded, - // and every time the contents change. - // Need to do this b/c we are actually binding to the iframe's <body> node. - // Note: can't use dojo.connect(), see #9609. - - binding.onloadHandler = dojo.hitch(this, function(){ - // want to remove old connections, but IE throws exceptions when trying to - // access the <body> node because it's already gone, or at least in a state of limbo - - var win = this._iframeContentWindow(iframe); - cn = dojo.withGlobal(win, dojo.body); - binding.connects = doConnects(cn); - }); - if(iframe.addEventListener){ - iframe.addEventListener("load", binding.onloadHandler, false); - }else{ - iframe.attachEvent("onload", binding.onloadHandler); - } - } - }, - - unBindDomNode: function(/*String|DomNode*/ nodeName){ - // summary: - // Detach menu from given node - - var node; - try{ - node = dojo.byId(nodeName); - }catch(e){ - // On IE the dojo.byId() call will get an exception if the attach point was - // the <body> node of an <iframe> that has since been reloaded (and thus the - // <body> node is in a limbo state of destruction. - return; - } - - // node["_dijitMenu" + this.id] contains index(+1) into my _bindings[] array - var attrName = "_dijitMenu" + this.id; - if(node && dojo.hasAttr(node, attrName)){ - var bid = dojo.attr(node, attrName)-1, b = this._bindings[bid]; - dojo.forEach(b.connects, dojo.disconnect); - - // Remove listener for iframe onload events - var iframe = b.iframe; - if(iframe){ - if(iframe.removeEventListener){ - iframe.removeEventListener("load", b.onloadHandler, false); - }else{ - iframe.detachEvent("onload", b.onloadHandler); - } - } - - dojo.removeAttr(node, attrName); - delete this._bindings[bid]; - } - }, - - _scheduleOpen: function(/*DomNode?*/ target, /*DomNode?*/ iframe, /*Object?*/ coords){ - // summary: - // Set timer to display myself. Using a timer rather than displaying immediately solves - // two problems: - // - // 1. IE: without the delay, focus work in "open" causes the system - // context menu to appear in spite of stopEvent. - // - // 2. Avoid double-shows on linux, where shift-F10 generates an oncontextmenu event - // even after a dojo.stopEvent(e). (Shift-F10 on windows doesn't generate the - // oncontextmenu event.) - - if(!this._openTimer){ - this._openTimer = setTimeout(dojo.hitch(this, function(){ - delete this._openTimer; - this._openMyself({ - target: target, - iframe: iframe, - coords: coords - }); - }), 1); - } - }, - - _openMyself: function(args){ - // summary: - // Internal function for opening myself when the user does a right-click or something similar. - // args: - // This is an Object containing: - // * target: - // The node that is being clicked - // * iframe: - // If an <iframe> is being clicked, iframe points to that iframe - // * coords: - // Put menu at specified x/y position in viewport, or if iframe is - // specified, then relative to iframe. - // - // _openMyself() formerly took the event object, and since various code references - // evt.target (after connecting to _openMyself()), using an Object for parameters - // (so that old code still works). - - var target = args.target, - iframe = args.iframe, - coords = args.coords; - - // Get coordinates to open menu, either at specified (mouse) position or (if triggered via keyboard) - // then near the node the menu is assigned to. - if(coords){ - if(iframe){ - // Specified coordinates are on <body> node of an <iframe>, convert to match main document - var od = target.ownerDocument, - ifc = dojo.position(iframe, true), - win = this._iframeContentWindow(iframe), - scroll = dojo.withGlobal(win, "_docScroll", dojo); - - var cs = dojo.getComputedStyle(iframe), - tp = dojo._toPixelValue, - left = (dojo.isIE && dojo.isQuirks ? 0 : tp(iframe, cs.paddingLeft)) + (dojo.isIE && dojo.isQuirks ? tp(iframe, cs.borderLeftWidth) : 0), - top = (dojo.isIE && dojo.isQuirks ? 0 : tp(iframe, cs.paddingTop)) + (dojo.isIE && dojo.isQuirks ? tp(iframe, cs.borderTopWidth) : 0); - - coords.x += ifc.x + left - scroll.x; - coords.y += ifc.y + top - scroll.y; - } - }else{ - coords = dojo.position(target, true); - coords.x += 10; - coords.y += 10; - } - - var self=this; - var savedFocus = dijit.getFocus(this); - function closeAndRestoreFocus(){ - // user has clicked on a menu or popup - if(self.refocus){ - dijit.focus(savedFocus); - } - dijit.popup.close(self); - } - dijit.popup.open({ - popup: this, - x: coords.x, - y: coords.y, - onExecute: closeAndRestoreFocus, - onCancel: closeAndRestoreFocus, - orient: this.isLeftToRight() ? 'L' : 'R' - }); - this.focus(); - - this._onBlur = function(){ - this.inherited('_onBlur', arguments); - // Usually the parent closes the child widget but if this is a context - // menu then there is no parent - dijit.popup.close(this); - // don't try to restore focus; user has clicked another part of the screen - // and set focus there - }; - }, - - uninitialize: function(){ - dojo.forEach(this._bindings, function(b){ if(b){ this.unBindDomNode(b.node); } }, this); - this.inherited(arguments); - } -} -); - -} +//>>built +define("dijit/Menu",["require","dojo/_base/array","dojo/_base/declare","dojo/_base/event","dojo/dom","dojo/dom-attr","dojo/dom-geometry","dojo/dom-style","dojo/_base/kernel","dojo/keys","dojo/_base/lang","dojo/on","dojo/_base/sniff","dojo/_base/window","dojo/window","./popup","./DropDownMenu","dojo/ready"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,on,_c,_d,_e,pm,_f,_10){if(!_9.isAsync){_10(0,function(){var _11=["dijit/MenuItem","dijit/PopupMenuItem","dijit/CheckedMenuItem","dijit/MenuSeparator"];_1(_11);});}return _3("dijit.Menu",_f,{constructor:function(){this._bindings=[];},targetNodeIds:[],contextMenuForWindow:false,leftClickToOpen:false,refocus:true,postCreate:function(){if(this.contextMenuForWindow){this.bindDomNode(_d.body());}else{_2.forEach(this.targetNodeIds,this.bindDomNode,this);}this.inherited(arguments);},_iframeContentWindow:function(_12){return _e.get(this._iframeContentDocument(_12))||this._iframeContentDocument(_12)["__parent__"]||(_12.name&&_d.doc.frames[_12.name])||null;},_iframeContentDocument:function(_13){return _13.contentDocument||(_13.contentWindow&&_13.contentWindow.document)||(_13.name&&_d.doc.frames[_13.name]&&_d.doc.frames[_13.name].document)||null;},bindDomNode:function(_14){_14=_5.byId(_14);var cn;if(_14.tagName.toLowerCase()=="iframe"){var _15=_14,_16=this._iframeContentWindow(_15);cn=_d.withGlobal(_16,_d.body);}else{cn=(_14==_d.body()?_d.doc.documentElement:_14);}var _17={node:_14,iframe:_15};_6.set(_14,"_dijitMenu"+this.id,this._bindings.push(_17));var _18=_b.hitch(this,function(cn){return [on(cn,this.leftClickToOpen?"click":"contextmenu",_b.hitch(this,function(evt){_4.stop(evt);this._scheduleOpen(evt.target,_15,{x:evt.pageX,y:evt.pageY});})),on(cn,"keydown",_b.hitch(this,function(evt){if(evt.shiftKey&&evt.keyCode==_a.F10){_4.stop(evt);this._scheduleOpen(evt.target,_15);}}))];});_17.connects=cn?_18(cn):[];if(_15){_17.onloadHandler=_b.hitch(this,function(){var _19=this._iframeContentWindow(_15);cn=_d.withGlobal(_19,_d.body);_17.connects=_18(cn);});if(_15.addEventListener){_15.addEventListener("load",_17.onloadHandler,false);}else{_15.attachEvent("onload",_17.onloadHandler);}}},unBindDomNode:function(_1a){var _1b;try{_1b=_5.byId(_1a);}catch(e){return;}var _1c="_dijitMenu"+this.id;if(_1b&&_6.has(_1b,_1c)){var bid=_6.get(_1b,_1c)-1,b=this._bindings[bid],h;while(h=b.connects.pop()){h.remove();}var _1d=b.iframe;if(_1d){if(_1d.removeEventListener){_1d.removeEventListener("load",b.onloadHandler,false);}else{_1d.detachEvent("onload",b.onloadHandler);}}_6.remove(_1b,_1c);delete this._bindings[bid];}},_scheduleOpen:function(_1e,_1f,_20){if(!this._openTimer){this._openTimer=setTimeout(_b.hitch(this,function(){delete this._openTimer;this._openMyself({target:_1e,iframe:_1f,coords:_20});}),1);}},_openMyself:function(_21){var _22=_21.target,_23=_21.iframe,_24=_21.coords;if(_24){if(_23){var ifc=_7.position(_23,true),_25=this._iframeContentWindow(_23),_26=_d.withGlobal(_25,"_docScroll",dojo);var cs=_8.getComputedStyle(_23),tp=_8.toPixelValue,_27=(_c("ie")&&_c("quirks")?0:tp(_23,cs.paddingLeft))+(_c("ie")&&_c("quirks")?tp(_23,cs.borderLeftWidth):0),top=(_c("ie")&&_c("quirks")?0:tp(_23,cs.paddingTop))+(_c("ie")&&_c("quirks")?tp(_23,cs.borderTopWidth):0);_24.x+=ifc.x+_27-_26.x;_24.y+=ifc.y+top-_26.y;}}else{_24=_7.position(_22,true);_24.x+=10;_24.y+=10;}var _28=this;var _29=this._focusManager.get("prevNode");var _2a=this._focusManager.get("curNode");var _2b=!_2a||(_5.isDescendant(_2a,this.domNode))?_29:_2a;function _2c(){if(_28.refocus&&_2b){_2b.focus();}pm.close(_28);};pm.open({popup:this,x:_24.x,y:_24.y,onExecute:_2c,onCancel:_2c,orient:this.isLeftToRight()?"L":"R"});this.focus();this._onBlur=function(){this.inherited("_onBlur",arguments);pm.close(this);};},uninitialize:function(){_2.forEach(this._bindings,function(b){if(b){this.unBindDomNode(b.node);}},this);this.inherited(arguments);}});});
\ No newline at end of file |