summaryrefslogtreecommitdiff
path: root/lib/dijit/_HasDropDown.js.uncompressed.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dijit/_HasDropDown.js.uncompressed.js')
-rw-r--r--lib/dijit/_HasDropDown.js.uncompressed.js509
1 files changed, 0 insertions, 509 deletions
diff --git a/lib/dijit/_HasDropDown.js.uncompressed.js b/lib/dijit/_HasDropDown.js.uncompressed.js
deleted file mode 100644
index 6cc6b8731..000000000
--- a/lib/dijit/_HasDropDown.js.uncompressed.js
+++ /dev/null
@@ -1,509 +0,0 @@
-define("dijit/_HasDropDown", [
- "dojo/_base/declare", // declare
- "dojo/_base/Deferred",
- "dojo/_base/event", // event.stop
- "dojo/dom", // dom.isDescendant
- "dojo/dom-attr", // domAttr.set
- "dojo/dom-class", // domClass.add domClass.contains domClass.remove
- "dojo/dom-geometry", // domGeometry.marginBox domGeometry.position
- "dojo/dom-style", // domStyle.set
- "dojo/has", // has("touch")
- "dojo/keys", // keys.DOWN_ARROW keys.ENTER keys.ESCAPE
- "dojo/_base/lang", // lang.hitch lang.isFunction
- "dojo/on",
- "dojo/window", // winUtils.getBox
- "./registry", // registry.byNode()
- "./focus",
- "./popup",
- "./_FocusMixin"
-], function(declare, Deferred, event,dom, domAttr, domClass, domGeometry, domStyle, has, keys, lang, on,
- winUtils, registry, focus, popup, _FocusMixin){
-
-
- // module:
- // dijit/_HasDropDown
-
- return declare("dijit._HasDropDown", _FocusMixin, {
- // summary:
- // Mixin for widgets that need drop down ability.
-
- // _buttonNode: [protected] DomNode
- // The button/icon/node to click to display the drop down.
- // Can be set via a data-dojo-attach-point assignment.
- // If missing, then either focusNode or domNode (if focusNode is also missing) will be used.
- _buttonNode: null,
-
- // _arrowWrapperNode: [protected] DomNode
- // Will set CSS class dijitUpArrow, dijitDownArrow, dijitRightArrow etc. on this node depending
- // on where the drop down is set to be positioned.
- // Can be set via a data-dojo-attach-point assignment.
- // If missing, then _buttonNode will be used.
- _arrowWrapperNode: null,
-
- // _popupStateNode: [protected] DomNode
- // The node to set the popupActive class on.
- // Can be set via a data-dojo-attach-point assignment.
- // If missing, then focusNode or _buttonNode (if focusNode is missing) will be used.
- _popupStateNode: null,
-
- // _aroundNode: [protected] DomNode
- // The node to display the popup around.
- // Can be set via a data-dojo-attach-point assignment.
- // If missing, then domNode will be used.
- _aroundNode: null,
-
- // dropDown: [protected] Widget
- // The widget to display as a popup. This widget *must* be
- // defined before the startup function is called.
- dropDown: null,
-
- // autoWidth: [protected] Boolean
- // Set to true to make the drop down at least as wide as this
- // widget. Set to false if the drop down should just be its
- // default width
- autoWidth: true,
-
- // forceWidth: [protected] Boolean
- // Set to true to make the drop down exactly as wide as this
- // widget. Overrides autoWidth.
- forceWidth: false,
-
- // maxHeight: [protected] Integer
- // The max height for our dropdown.
- // Any dropdown taller than this will have scrollbars.
- // Set to 0 for no max height, or -1 to limit height to available space in viewport
- maxHeight: 0,
-
- // dropDownPosition: [const] String[]
- // This variable controls the position of the drop down.
- // It's an array of strings with the following values:
- //
- // - before: places drop down to the left of the target node/widget, or to the right in
- // the case of RTL scripts like Hebrew and Arabic
- // - after: places drop down to the right of the target node/widget, or to the left in
- // the case of RTL scripts like Hebrew and Arabic
- // - above: drop down goes above target node
- // - below: drop down goes below target node
- //
- // The list is positions is tried, in order, until a position is found where the drop down fits
- // within the viewport.
- //
- dropDownPosition: ["below","above"],
-
- // _stopClickEvents: Boolean
- // When set to false, the click events will not be stopped, in
- // case you want to use them in your subclass
- _stopClickEvents: true,
-
- _onDropDownMouseDown: function(/*Event*/ e){
- // summary:
- // Callback when the user mousedown's on the arrow icon
- if(this.disabled || this.readOnly){ return; }
-
- // Prevent default to stop things like text selection, but don't stop propagation, so that:
- // 1. TimeTextBox etc. can focus the <input> on mousedown
- // 2. dropDownButtonActive class applied by _CssStateMixin (on button depress)
- // 3. user defined onMouseDown handler fires
- e.preventDefault();
-
- this._docHandler = this.connect(this.ownerDocument, "mouseup", "_onDropDownMouseUp");
-
- this.toggleDropDown();
- },
-
- _onDropDownMouseUp: function(/*Event?*/ e){
- // summary:
- // Callback when the user lifts their mouse after mouse down on the arrow icon.
- // If the drop down is a simple menu and the mouse is over the menu, we execute it, otherwise, we focus our
- // drop down widget. If the event is missing, then we are not
- // a mouseup event.
- //
- // This is useful for the common mouse movement pattern
- // with native browser `<select>` nodes:
- //
- // 1. mouse down on the select node (probably on the arrow)
- // 2. move mouse to a menu item while holding down the mouse button
- // 3. mouse up. this selects the menu item as though the user had clicked it.
- if(e && this._docHandler){
- this.disconnect(this._docHandler);
- }
- var dropDown = this.dropDown, overMenu = false;
-
- if(e && this._opened){
- // This code deals with the corner-case when the drop down covers the original widget,
- // because it's so large. In that case mouse-up shouldn't select a value from the menu.
- // Find out if our target is somewhere in our dropdown widget,
- // but not over our _buttonNode (the clickable node)
- var c = domGeometry.position(this._buttonNode, true);
- if(!(e.pageX >= c.x && e.pageX <= c.x + c.w) ||
- !(e.pageY >= c.y && e.pageY <= c.y + c.h)){
- var t = e.target;
- while(t && !overMenu){
- if(domClass.contains(t, "dijitPopup")){
- overMenu = true;
- }else{
- t = t.parentNode;
- }
- }
- if(overMenu){
- t = e.target;
- if(dropDown.onItemClick){
- var menuItem;
- while(t && !(menuItem = registry.byNode(t))){
- t = t.parentNode;
- }
- if(menuItem && menuItem.onClick && menuItem.getParent){
- menuItem.getParent().onItemClick(menuItem, e);
- }
- }
- return;
- }
- }
- }
- if(this._opened){
- if(dropDown.focus && dropDown.autoFocus !== false){
- // Focus the dropdown widget - do it on a delay so that we
- // don't steal back focus from the dropdown.
- this._focusDropDownTimer = this.defer(function(){
- dropDown.focus();
- delete this._focusDropDownTimer;
- });
- }
- }else{
- // The drop down arrow icon probably can't receive focus, but widget itself should get focus.
- // defer() needed to make it work on IE (test DateTextBox)
- this.defer("focus");
- }
-
- if(has("touch")){
- this._justGotMouseUp = true;
- this.defer(function(){
- this._justGotMouseUp = false;
- });
- }
- },
-
- _onDropDownClick: function(/*Event*/ e){
- if(has("touch") && !this._justGotMouseUp){
- // If there was no preceding mousedown/mouseup (like on android), then simulate them to
- // toggle the drop down.
- //
- // The if(has("touch") is necessary since IE and desktop safari get spurious onclick events
- // when there are nested tables (specifically, clicking on a table that holds a dijit/form/Select,
- // but not on the Select itself, causes an onclick event on the Select)
- this._onDropDownMouseDown(e);
- this._onDropDownMouseUp(e);
- }
-
- // The drop down was already opened on mousedown/keydown; just need to call stopEvent().
- if(this._stopClickEvents){
- event.stop(e);
- }
- },
-
- buildRendering: function(){
- this.inherited(arguments);
-
- this._buttonNode = this._buttonNode || this.focusNode || this.domNode;
- this._popupStateNode = this._popupStateNode || this.focusNode || this._buttonNode;
-
- // Add a class to the "dijitDownArrowButton" type class to _buttonNode so theme can set direction of arrow
- // based on where drop down will normally appear
- var defaultPos = {
- "after" : this.isLeftToRight() ? "Right" : "Left",
- "before" : this.isLeftToRight() ? "Left" : "Right",
- "above" : "Up",
- "below" : "Down",
- "left" : "Left",
- "right" : "Right"
- }[this.dropDownPosition[0]] || this.dropDownPosition[0] || "Down";
- domClass.add(this._arrowWrapperNode || this._buttonNode, "dijit" + defaultPos + "ArrowButton");
- },
-
- postCreate: function(){
- // summary:
- // set up nodes and connect our mouse and keyboard events
-
- this.inherited(arguments);
-
- var keyboardEventNode = this.focusNode || this.domNode;
- this.own(
- on(this._buttonNode, "mousedown", lang.hitch(this, "_onDropDownMouseDown")),
- on(this._buttonNode, "click", lang.hitch(this, "_onDropDownClick")),
- on(keyboardEventNode, "keydown", lang.hitch(this, "_onKey")),
- on(keyboardEventNode, "keyup", lang.hitch(this, "_onKeyUp"))
- );
- },
-
- destroy: function(){
- if(this.dropDown){
- // Destroy the drop down, unless it's already been destroyed. This can happen because
- // the drop down is a direct child of <body> even though it's logically my child.
- if(!this.dropDown._destroyed){
- this.dropDown.destroyRecursive();
- }
- delete this.dropDown;
- }
- this.inherited(arguments);
- },
-
- _onKey: function(/*Event*/ e){
- // summary:
- // Callback when the user presses a key while focused on the button node
-
- if(this.disabled || this.readOnly){ return; }
- var d = this.dropDown, target = e.target;
- if(d && this._opened && d.handleKey){
- if(d.handleKey(e) === false){
- /* false return code means that the drop down handled the key */
- event.stop(e);
- return;
- }
- }
- if(d && this._opened && e.keyCode == keys.ESCAPE){
- this.closeDropDown();
- event.stop(e);
- }else if(!this._opened &&
- (e.keyCode == keys.DOWN_ARROW ||
- ( (e.keyCode == keys.ENTER || e.keyCode == keys.SPACE) &&
- //ignore enter and space if the event is for a text input
- ((target.tagName || "").toLowerCase() !== 'input' ||
- (target.type && target.type.toLowerCase() !== 'text'))))){
- // Toggle the drop down, but wait until keyup so that the drop down doesn't
- // get a stray keyup event, or in the case of key-repeat (because user held
- // down key for too long), stray keydown events
- this._toggleOnKeyUp = true;
- event.stop(e);
- }
- },
-
- _onKeyUp: function(){
- if(this._toggleOnKeyUp){
- delete this._toggleOnKeyUp;
- this.toggleDropDown();
- var d = this.dropDown; // drop down may not exist until toggleDropDown() call
- if(d && d.focus){
- this.defer(lang.hitch(d, "focus"), 1);
- }
- }
- },
-
- _onBlur: function(){
- // summary:
- // Called magically when focus has shifted away from this widget and it's dropdown
-
- // Don't focus on button if the user has explicitly focused on something else (happens
- // when user clicks another control causing the current popup to close)..
- // But if focus is inside of the drop down then reset focus to me, because IE doesn't like
- // it when you display:none a node with focus.
- var focusMe = focus.curNode && this.dropDown && dom.isDescendant(focus.curNode, this.dropDown.domNode);
-
- this.closeDropDown(focusMe);
-
- this.inherited(arguments);
- },
-
- isLoaded: function(){
- // summary:
- // Returns true if the dropdown exists and it's data is loaded. This can
- // be overridden in order to force a call to loadDropDown().
- // tags:
- // protected
-
- return true;
- },
-
- loadDropDown: function(/*Function*/ loadCallback){
- // summary:
- // Creates the drop down if it doesn't exist, loads the data
- // if there's an href and it hasn't been loaded yet, and then calls
- // the given callback.
- // tags:
- // protected
-
- // TODO: for 2.0, change API to return a Deferred, instead of calling loadCallback?
- loadCallback();
- },
-
- loadAndOpenDropDown: function(){
- // summary:
- // Creates the drop down if it doesn't exist, loads the data
- // if there's an href and it hasn't been loaded yet, and
- // then opens the drop down. This is basically a callback when the
- // user presses the down arrow button to open the drop down.
- // returns: Deferred
- // Deferred for the drop down widget that
- // fires when drop down is created and loaded
- // tags:
- // protected
- var d = new Deferred(),
- afterLoad = lang.hitch(this, function(){
- this.openDropDown();
- d.resolve(this.dropDown);
- });
- if(!this.isLoaded()){
- this.loadDropDown(afterLoad);
- }else{
- afterLoad();
- }
- return d;
- },
-
- toggleDropDown: function(){
- // summary:
- // Callback when the user presses the down arrow button or presses
- // the down arrow key to open/close the drop down.
- // Toggle the drop-down widget; if it is up, close it, if not, open it
- // tags:
- // protected
-
- if(this.disabled || this.readOnly){ return; }
- if(!this._opened){
- this.loadAndOpenDropDown();
- }else{
- this.closeDropDown();
- }
- },
-
- openDropDown: function(){
- // summary:
- // Opens the dropdown for this widget. To be called only when this.dropDown
- // has been created and is ready to display (ie, it's data is loaded).
- // returns:
- // return value of dijit/popup.open()
- // tags:
- // protected
-
- var dropDown = this.dropDown,
- ddNode = dropDown.domNode,
- aroundNode = this._aroundNode || this.domNode,
- self = this;
-
- // Prepare our popup's height and honor maxHeight if it exists.
-
- // TODO: isn't maxHeight dependent on the return value from dijit/popup.open(),
- // ie, dependent on how much space is available (BK)
-
- if(!this._preparedNode){
- this._preparedNode = true;
- // Check if we have explicitly set width and height on the dropdown widget dom node
- if(ddNode.style.width){
- this._explicitDDWidth = true;
- }
- if(ddNode.style.height){
- this._explicitDDHeight = true;
- }
- }
-
- // Code for resizing dropdown (height limitation, or increasing width to match my width)
- if(this.maxHeight || this.forceWidth || this.autoWidth){
- var myStyle = {
- display: "",
- visibility: "hidden"
- };
- if(!this._explicitDDWidth){
- myStyle.width = "";
- }
- if(!this._explicitDDHeight){
- myStyle.height = "";
- }
- domStyle.set(ddNode, myStyle);
-
- // Figure out maximum height allowed (if there is a height restriction)
- var maxHeight = this.maxHeight;
- if(maxHeight == -1){
- // limit height to space available in viewport either above or below my domNode
- // (whichever side has more room)
- var viewport = winUtils.getBox(this.ownerDocument),
- position = domGeometry.position(aroundNode, false);
- maxHeight = Math.floor(Math.max(position.y, viewport.h - (position.y + position.h)));
- }
-
- // Attach dropDown to DOM and make make visibility:hidden rather than display:none
- // so we call startup() and also get the size
- popup.moveOffScreen(dropDown);
-
- if(dropDown.startup && !dropDown._started){
- dropDown.startup(); // this has to be done after being added to the DOM
- }
- // Get size of drop down, and determine if vertical scroll bar needed. If no scroll bar needed,
- // use overflow:visible rather than overflow:hidden so off-by-one errors don't hide drop down border.
- var mb = domGeometry.getMarginSize(ddNode);
- var overHeight = (maxHeight && mb.h > maxHeight);
- domStyle.set(ddNode, {
- overflowX: "visible",
- overflowY: overHeight ? "auto" : "visible"
- });
- if(overHeight){
- mb.h = maxHeight;
- if("w" in mb){
- mb.w += 16; // room for vertical scrollbar
- }
- }else{
- delete mb.h;
- }
-
- // Adjust dropdown width to match or be larger than my width
- if(this.forceWidth){
- mb.w = aroundNode.offsetWidth;
- }else if(this.autoWidth){
- mb.w = Math.max(mb.w, aroundNode.offsetWidth);
- }else{
- delete mb.w;
- }
-
- // And finally, resize the dropdown to calculated height and width
- if(lang.isFunction(dropDown.resize)){
- dropDown.resize(mb);
- }else{
- domGeometry.setMarginBox(ddNode, mb);
- }
- }
-
- var retVal = popup.open({
- parent: this,
- popup: dropDown,
- around: aroundNode,
- orient: this.dropDownPosition,
- onExecute: function(){
- self.closeDropDown(true);
- },
- onCancel: function(){
- self.closeDropDown(true);
- },
- onClose: function(){
- domAttr.set(self._popupStateNode, "popupActive", false);
- domClass.remove(self._popupStateNode, "dijitHasDropDownOpen");
- self._set("_opened", false); // use set() because _CssStateMixin is watching
- }
- });
- domAttr.set(this._popupStateNode, "popupActive", "true");
- domClass.add(this._popupStateNode, "dijitHasDropDownOpen");
- this._set("_opened", true); // use set() because _CssStateMixin is watching
- this.domNode.setAttribute("aria-expanded", "true");
-
- return retVal;
- },
-
- closeDropDown: function(/*Boolean*/ focus){
- // summary:
- // Closes the drop down on this widget
- // focus:
- // If true, refocuses the button widget
- // tags:
- // protected
-
- if(this._focusDropDownTimer){
- this._focusDropDownTimer.remove();
- delete this._focusDropDownTimer;
- }
- if(this._opened){
- this.domNode.setAttribute("aria-expanded", "false");
- if(focus){ this.focus(); }
- popup.close(this.dropDown);
- this._opened = false;
- }
- }
-
- });
-});