Blame | Last modification | View Log | RSS feed
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("dijit._Widget");dojo.require("dijit._Container");dojo.require("dijit._Templated");dojo.declare("dijit.Menu",[dijit._Widget, dijit._Templated, dijit._KeyNavContainer],{constructor: function() {this._bindings = [];},templateString:'<table class="dijit dijitMenu dijitReset dijitMenuTable" waiRole="menu" dojoAttachEvent="onkeypress:_onKeyPress">' +'<tbody class="dijitReset" dojoAttachPoint="containerNode"></tbody>'+'</table>',// targetNodeIds: 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: Boolean// if true, right clicking anywhere on the window will cause this context menu to open;// if false, must specify targetNodeIdscontextMenuForWindow: false,// parentMenu: Widget// pointer to menu that displayed meparentMenu: null,// popupDelay: Integer// number of milliseconds before hovering (without clicking) causes the popup to automatically openpopupDelay: 500,// _contextMenuWithMouse: Boolean// used to record mouse and keyboard events to determine if a context// menu is being opened with the keyboard or the mouse_contextMenuWithMouse: false,postCreate: function(){if(this.contextMenuForWindow){this.bindDomNode(dojo.body());}else{dojo.forEach(this.targetNodeIds, this.bindDomNode, this);}this.connectKeyNavHandlers([dojo.keys.UP_ARROW], [dojo.keys.DOWN_ARROW]);},startup: function(){dojo.forEach(this.getChildren(), function(child){ child.startup(); });this.startupKeyNavChildren();},onExecute: function(){// summary: attach point for notification about when a menu item has been executed},onCancel: function(/*Boolean*/ closeAll){// summary: attach point for notification about when the user cancels the current menu},_moveToPopup: function(/*Event*/ evt){if(this.focusedChild && this.focusedChild.popup && !this.focusedChild.disabled){this.focusedChild._onClick(evt);}},_onKeyPress: function(/*Event*/ evt){// summary// Handle keyboard based menu navigation.if(evt.ctrlKey || evt.altKey){ return; }switch(evt.keyCode){case dojo.keys.RIGHT_ARROW:this._moveToPopup(evt);dojo.stopEvent(evt);break;case dojo.keys.LEFT_ARROW:if(this.parentMenu){this.onCancel(false);}else{dojo.stopEvent(evt);}break;}},onItemHover: function(/*MenuItem*/ item){this.focusChild(item);if(this.focusedChild.popup && !this.focusedChild.disabled && !this.hover_timer){this.hover_timer = setTimeout(dojo.hitch(this, "_openPopup"), this.popupDelay);}},_onChildBlur: function(item){// Close all popups that are open and descendants of this menudijit.popup.close(item.popup);item._blur();this._stopPopupTimer();},onItemUnhover: function(/*MenuItem*/ item){},_stopPopupTimer: function(){if(this.hover_timer){clearTimeout(this.hover_timer);this.hover_timer = null;}},_getTopMenu: function(){for(var top=this; top.parentMenu; top=top.parentMenu);return top;},onItemClick: function(/*Widget*/ item){// summary: user defined function to handle clicks on an item// summary: internal function for clicksif(item.disabled){ return false; }if(item.popup){if(!this.is_open){this._openPopup();}}else{// before calling user defined handler, close hierarchy of menus// and restore focus to place it was when menu was openedthis.onExecute();// user defined handler for clickitem.onClick();}},// thanks burstlib!_iframeContentWindow: function(/* HTMLIFrameElement */iframe_el) {// summary// returns the window reference of the passed iframevar win = dijit.getDocumentWindow(dijit.Menu._iframeContentDocument(iframe_el)) ||// Moz. TODO: is this available when defaultView isn't?dijit.Menu._iframeContentDocument(iframe_el)['__parent__'] ||(iframe_el.name && document.frames[iframe_el.name]) || null;return win; // Window},_iframeContentDocument: function(/* HTMLIFrameElement */iframe_el){// summary// returns a reference to the document object inside iframe_elvar doc = iframe_el.contentDocument // W3|| (iframe_el.contentWindow && iframe_el.contentWindow.document) // IE|| (iframe_el.name && document.frames[iframe_el.name] && document.frames[iframe_el.name].document)|| null;return doc; // HTMLDocument},bindDomNode: function(/*String|DomNode*/ node){// summary: attach menu to given nodenode = dojo.byId(node);//TODO: this is to support context popups in Editor. Maybe this shouldn't be in dijit.Menuvar win = dijit.getDocumentWindow(node.ownerDocument);if(node.tagName.toLowerCase()=="iframe"){win = this._iframeContentWindow(node);node = dojo.withGlobal(win, dojo.body);}// to capture these events at the top level,// attach to document, not bodyvar cn = (node == dojo.body() ? dojo.doc : node);node[this.id] = this._bindings.push([dojo.connect(cn, "oncontextmenu", this, "_openMyself"),dojo.connect(cn, "onkeydown", this, "_contextKey"),dojo.connect(cn, "onmousedown", this, "_contextMouse")]);},unBindDomNode: function(/*String|DomNode*/ nodeName){// summary: detach menu from given nodevar node = dojo.byId(nodeName);var bid = node[this.id]-1, b = this._bindings[bid];dojo.forEach(b, dojo.disconnect);delete this._bindings[bid];},_contextKey: function(e){this._contextMenuWithMouse = false;if (e.keyCode == dojo.keys.F10) {dojo.stopEvent(e);if (e.shiftKey && e.type=="keydown") {// FF: copying the wrong property from e will cause the system// context menu to appear in spite of stopEvent. Don't know// exactly which properties cause this effect.var _e = { target: e.target, pageX: e.pageX, pageY: e.pageY };_e.preventDefault = _e.stopPropagation = function(){};// IE: without the delay, focus work in "open" causes the system// context menu to appear in spite of stopEvent.window.setTimeout(dojo.hitch(this, function(){ this._openMyself(_e); }), 1);}}},_contextMouse: function(e){this._contextMenuWithMouse = true;},_openMyself: function(/*Event*/ e){// summary:// Internal function for opening myself when the user// does a right-click or something similardojo.stopEvent(e);// Get coordinates.// if we are opening the menu with the mouse or on safari open// the menu at the mouse cursor// (Safari does not have a keyboard command to open the context menu// and we don't currently have a reliable way to determine// _contextMenuWithMouse on Safari)var x,y;if(dojo.isSafari || this._contextMenuWithMouse){x=e.pageX;y=e.pageY;}else{// otherwise open near e.targetvar coords = dojo.coords(e.target, true);x = coords.x + 10;y = coords.y + 10;}var self=this;var savedFocus = dijit.getFocus(this);function closeAndRestoreFocus(){// user has clicked on a menu or popupdijit.focus(savedFocus);dijit.popup.close(self);}dijit.popup.open({popup: this,x: x,y: y,onExecute: closeAndRestoreFocus,onCancel: closeAndRestoreFocus,orient: this.isLeftToRight() ? 'L' : 'R'});this.focus();this._onBlur = function(){// Usually the parent closes the child widget but if this is a context// menu then there is no parentdijit.popup.close(this);// don't try to restore focus; user has clicked another part of the screen// and set focus there}},onOpen: function(/*Event*/ e){// summary// Open menu relative to the mousethis.isShowingNow = true;},onClose: function(){// summary: callback when this menu is closedthis._stopPopupTimer();this.parentMenu = null;this.isShowingNow = false;this.currentPopup = null;if(this.focusedChild){this._onChildBlur(this.focusedChild);this.focusedChild = null;}},_openPopup: function(){// summary: open the popup to the side of the current menu itemthis._stopPopupTimer();var from_item = this.focusedChild;var popup = from_item.popup;if(popup.isShowingNow){ return; }popup.parentMenu = this;var self = this;dijit.popup.open({parent: this,popup: popup,around: from_item.arrowCell,orient: this.isLeftToRight() ? {'TR': 'TL', 'TL': 'TR'} : {'TL': 'TR', 'TR': 'TL'},onCancel: function(){// called when the child menu is canceleddijit.popup.close(popup);from_item.focus(); // put focus back on my nodeself.currentPopup = null;}});this.currentPopup = popup;if(popup.focus){popup.focus();}}});dojo.declare("dijit.MenuItem",[dijit._Widget, dijit._Templated, dijit._Contained],{// summary// A line item in a Menu2// Make 3 columns// icon, label, and expand arrow (BiDi-dependent) indicating sub-menutemplateString:'<tr class="dijitReset dijitMenuItem"'+'dojoAttachEvent="onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick">'+'<td class="dijitReset"><div class="dijitMenuItemIcon ${iconClass}" dojoAttachPoint="iconNode" ></div></td>'+'<td tabIndex="-1" class="dijitReset dijitMenuItemLabel" dojoAttachPoint="containerNode" waiRole="menuitem"></td>'+'<td class="dijitReset" dojoAttachPoint="arrowCell">'+'<div class="dijitMenuExpand" dojoAttachPoint="expand" style="display:none">'+'<span class="dijitInline dijitArrowNode dijitMenuExpandInner">+</span>'+'</div>'+'</td>'+'</tr>',// label: String// menu textlabel: '',// iconClass: String// class to apply to div in button to make it display an iconiconClass: "",// disabled: Boolean// if true, the menu item is disabled// if false, the menu item is enableddisabled: false,postCreate: function(){dojo.setSelectable(this.domNode, false);this.setDisabled(this.disabled);if(this.label){this.containerNode.innerHTML=this.label;}},_onHover: function(){// summary: callback when mouse is moved onto menu itemthis.getParent().onItemHover(this);},_onUnhover: function(){// summary: callback when mouse is moved off of menu item// if we are unhovering the currently selected item// then unselect itthis.getParent().onItemUnhover(this);},_onClick: function(evt){this.getParent().onItemClick(this);dojo.stopEvent(evt);},onClick: function() {// summary// User defined function to handle clicks},focus: function(){dojo.addClass(this.domNode, 'dijitMenuItemHover');try{dijit.focus(this.containerNode);}catch(e){// this throws on IE (at least) in some scenarios}},_blur: function(){dojo.removeClass(this.domNode, 'dijitMenuItemHover');},setDisabled: function(/*Boolean*/ value){// summary: enable or disable this menu itemthis.disabled = value;dojo[value ? "addClass" : "removeClass"](this.domNode, 'dijitMenuItemDisabled');dijit.setWaiState(this.containerNode, 'disabled', value ? 'true' : 'false');}});dojo.declare("dijit.PopupMenuItem",dijit.MenuItem,{_fillContent: function(){// my inner HTML contains both the menu item text and a popup widget, like// <div dojoType="dijit.PopupMenuItem">// <span>pick me</span>// <popup> ... </popup>// </div>// the first part holds the menu item text and the second part is the popupif(this.srcNodeRef){var nodes = dojo.query("*", this.srcNodeRef);dijit.PopupMenuItem.superclass._fillContent.call(this, nodes[0]);// save pointer to srcNode so we can grab the drop down widget after it's instantiatedthis.dropDownContainer = this.srcNodeRef;}},startup: function(){// we didn't copy the dropdown widget from the this.srcNodeRef, so it's in no-man's// land now. move it to document.body.if(!this.popup){var node = dojo.query("[widgetId]", this.dropDownContainer)[0];this.popup = dijit.byNode(node);}dojo.body().appendChild(this.popup.domNode);this.popup.domNode.style.display="none";dojo.addClass(this.expand, "dijitMenuExpandEnabled");dojo.style(this.expand, "display", "");dijit.setWaiState(this.containerNode, "haspopup", "true");}});dojo.declare("dijit.MenuSeparator",[dijit._Widget, dijit._Templated, dijit._Contained],{// summary// A line between two menu itemstemplateString: '<tr class="dijitMenuSeparator"><td colspan=3>'+'<div class="dijitMenuSeparatorTop"></div>'+'<div class="dijitMenuSeparatorBottom"></div>'+'</td></tr>',postCreate: function(){dojo.setSelectable(this.domNode, false);},isFocusable: function(){// summary:// over ride to always return falsereturn false;}});}