//>>built define("dijit/Menu", [ "require", "dojo/_base/array", // array.forEach "dojo/_base/declare", // declare "dojo/_base/event", // event.stop "dojo/dom", // dom.byId dom.isDescendant "dojo/dom-attr", // domAttr.get domAttr.set domAttr.has domAttr.remove "dojo/dom-geometry", // domStyle.getComputedStyle domGeometry.position "dojo/dom-style", // domStyle.getComputedStyle "dojo/_base/kernel", "dojo/keys", // keys.F10 "dojo/_base/lang", // lang.hitch "dojo/on", "dojo/_base/sniff", // has("ie"), has("quirks") "dojo/_base/window", // win.body win.doc.documentElement win.doc.frames win.withGlobal "dojo/window", // winUtils.get "./popup", "./DropDownMenu", "dojo/ready" ], function(require, array, declare, event, dom, domAttr, domGeometry, domStyle, kernel, keys, lang, on, has, win, winUtils, pm, DropDownMenu, ready){ /*===== var DropDownMenu = dijit.DropDownMenu; =====*/ // module: // dijit/Menu // summary: // Includes dijit.Menu widget and base class dijit._MenuBase // Back compat w/1.6, remove for 2.0 if(!kernel.isAsync){ ready(0, function(){ var requires = ["dijit/MenuItem", "dijit/PopupMenuItem", "dijit/CheckedMenuItem", "dijit/MenuSeparator"]; require(requires); // use indirection so modules not rolled into a build }); } return declare("dijit.Menu", DropDownMenu, { // summary: // A context menu you can assign to multiple elements constructor: function(){ this._bindings = []; }, // 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, similar 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(win.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) array.forEach(this.targetNodeIds, this.bindDomNode, this); } this.inherited(arguments); }, // thanks burstlib! _iframeContentWindow: function(/* HTMLIFrameElement */iframe_el){ // summary: // Returns the window reference of the passed iframe // tags: // private return winUtils.get(this._iframeContentDocument(iframe_el)) || // Moz. TODO: is this available when defaultView isn't? this._iframeContentDocument(iframe_el)['__parent__'] || (iframe_el.name && win.doc.frames[iframe_el.name]) || null; // Window }, _iframeContentDocument: function(/* HTMLIFrameElement */iframe_el){ // summary: // Returns a reference to the document object inside iframe_el // tags: // protected return iframe_el.contentDocument // W3 || (iframe_el.contentWindow && iframe_el.contentWindow.document) // IE || (iframe_el.name && win.doc.frames[iframe_el.name] && win.doc.frames[iframe_el.name].document) || null; // HTMLDocument }, bindDomNode: function(/*String|DomNode*/ node){ // summary: // Attach menu to given node node = dom.byId(node); var cn; // Connect node // Support context menus on iframes. Rather than binding to the iframe itself we need // to bind to the
node inside the iframe. if(node.tagName.toLowerCase() == "iframe"){ var iframe = node, window = this._iframeContentWindow(iframe); cn = win.withGlobal(window, win.body); }else{ // To capture these events at the top level, attach to , not . // Otherwise right-click context menu just doesn't work. cn = (node == win.body() ? win.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. domAttr.set(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 = lang.hitch(this, function(cn){ return [ // TODO: when leftClickToOpen is true then shouldn't space/enter key trigger the menu, // rather than shift-F10? on(cn, this.leftClickToOpen ? "click" : "contextmenu", lang.hitch(this, function(evt){ // Schedule context menu to be opened unless it's already been scheduled from onkeydown handler event.stop(evt); this._scheduleOpen(evt.target, iframe, {x: evt.pageX, y: evt.pageY}); })), on(cn, "keydown", lang.hitch(this, function(evt){ if(evt.shiftKey && evt.keyCode == keys.F10){ event.stop(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 node. // Note: can't use connect.connect(), see #9609. binding.onloadHandler = lang.hitch(this, function(){ // want to remove old connections, but IE throws exceptions when trying to // access the node because it's already gone, or at least in a state of limbo var window = this._iframeContentWindow(iframe); cn = win.withGlobal(window, win.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 = dom.byId(nodeName); }catch(e){ // On IE the dom.byId() call will get an exception if the attach point was // the node of an