[483] | 1 | define([ |
---|
| 2 | "dojo/_base/array", // array.forEach |
---|
| 3 | "dojo/_base/declare", // declare |
---|
| 4 | "dojo/dom-attr", // domAttr.set |
---|
| 5 | "dojo/_base/kernel", // kernel.deprecated |
---|
| 6 | "dojo/keys", // keys.END keys.HOME |
---|
| 7 | "dojo/_base/lang", // lang.hitch |
---|
| 8 | "./registry", |
---|
| 9 | "./_Container", |
---|
| 10 | "./_FocusMixin", |
---|
| 11 | "./_KeyNavMixin" |
---|
| 12 | ], function(array, declare, domAttr, kernel, keys, lang, registry, _Container, _FocusMixin, _KeyNavMixin){ |
---|
| 13 | |
---|
| 14 | |
---|
| 15 | // module: |
---|
| 16 | // dijit/_KeyNavContainer |
---|
| 17 | |
---|
| 18 | return declare("dijit._KeyNavContainer", [_FocusMixin, _KeyNavMixin, _Container], { |
---|
| 19 | // summary: |
---|
| 20 | // A _Container with keyboard navigation of its children. |
---|
| 21 | // description: |
---|
| 22 | // Provides normalized keyboard and focusing code for Container widgets. |
---|
| 23 | // To use this mixin, call connectKeyNavHandlers() in postCreate(). |
---|
| 24 | // Also, child widgets must implement a focus() method. |
---|
| 25 | |
---|
| 26 | connectKeyNavHandlers: function(/*keys[]*/ prevKeyCodes, /*keys[]*/ nextKeyCodes){ |
---|
| 27 | // summary: |
---|
| 28 | // Deprecated. You can call this in postCreate() to attach the keyboard handlers to the container, |
---|
| 29 | // but the preferred method is to override _onLeftArrow() and _onRightArrow(), or |
---|
| 30 | // _onUpArrow() and _onDownArrow(), to call focusPrev() and focusNext(). |
---|
| 31 | // prevKeyCodes: keys[] |
---|
| 32 | // Key codes for navigating to the previous child. |
---|
| 33 | // nextKeyCodes: keys[] |
---|
| 34 | // Key codes for navigating to the next child. |
---|
| 35 | // tags: |
---|
| 36 | // protected |
---|
| 37 | |
---|
| 38 | // TODO: remove for 2.0, and make subclasses override _onLeftArrow, _onRightArrow etc. instead. |
---|
| 39 | |
---|
| 40 | var keyCodes = (this._keyNavCodes = {}); |
---|
| 41 | var prev = lang.hitch(this, "focusPrev"); |
---|
| 42 | var next = lang.hitch(this, "focusNext"); |
---|
| 43 | array.forEach(prevKeyCodes, function(code){ |
---|
| 44 | keyCodes[code] = prev; |
---|
| 45 | }); |
---|
| 46 | array.forEach(nextKeyCodes, function(code){ |
---|
| 47 | keyCodes[code] = next; |
---|
| 48 | }); |
---|
| 49 | keyCodes[keys.HOME] = lang.hitch(this, "focusFirstChild"); |
---|
| 50 | keyCodes[keys.END] = lang.hitch(this, "focusLastChild"); |
---|
| 51 | }, |
---|
| 52 | |
---|
| 53 | startupKeyNavChildren: function(){ |
---|
| 54 | kernel.deprecated("startupKeyNavChildren() call no longer needed", "", "2.0"); |
---|
| 55 | }, |
---|
| 56 | |
---|
| 57 | startup: function(){ |
---|
| 58 | this.inherited(arguments); |
---|
| 59 | array.forEach(this.getChildren(), lang.hitch(this, "_startupChild")); |
---|
| 60 | }, |
---|
| 61 | |
---|
| 62 | addChild: function(/*dijit/_WidgetBase*/ widget, /*int?*/ insertIndex){ |
---|
| 63 | this.inherited(arguments); |
---|
| 64 | this._startupChild(widget); |
---|
| 65 | }, |
---|
| 66 | |
---|
| 67 | _startupChild: function(/*dijit/_WidgetBase*/ widget){ |
---|
| 68 | // summary: |
---|
| 69 | // Setup for each child widget. |
---|
| 70 | // description: |
---|
| 71 | // Sets tabIndex=-1 on each child, so that the tab key will |
---|
| 72 | // leave the container rather than visiting each child. |
---|
| 73 | // |
---|
| 74 | // Note: if you add children by a different method than addChild(), then need to call this manually |
---|
| 75 | // or at least make sure the child's tabIndex is -1. |
---|
| 76 | // |
---|
| 77 | // Note: see also _LayoutWidget.setupChild(), which is also called for each child widget. |
---|
| 78 | // tags: |
---|
| 79 | // private |
---|
| 80 | |
---|
| 81 | widget.set("tabIndex", "-1"); |
---|
| 82 | }, |
---|
| 83 | |
---|
| 84 | _getFirst: function(){ |
---|
| 85 | // summary: |
---|
| 86 | // Returns the first child. |
---|
| 87 | // tags: |
---|
| 88 | // abstract extension |
---|
| 89 | var children = this.getChildren(); |
---|
| 90 | return children.length ? children[0] : null; |
---|
| 91 | }, |
---|
| 92 | |
---|
| 93 | _getLast: function(){ |
---|
| 94 | // summary: |
---|
| 95 | // Returns the last descendant. |
---|
| 96 | // tags: |
---|
| 97 | // abstract extension |
---|
| 98 | var children = this.getChildren(); |
---|
| 99 | return children.length ? children[children.length - 1] : null; |
---|
| 100 | }, |
---|
| 101 | |
---|
| 102 | focusNext: function(){ |
---|
| 103 | // summary: |
---|
| 104 | // Focus the next widget |
---|
| 105 | // tags: |
---|
| 106 | // protected |
---|
| 107 | this.focusChild(this._getNextFocusableChild(this.focusedChild, 1)); |
---|
| 108 | }, |
---|
| 109 | |
---|
| 110 | focusPrev: function(){ |
---|
| 111 | // summary: |
---|
| 112 | // Focus the last focusable node in the previous widget |
---|
| 113 | // (ex: go to the ComboButton icon section rather than button section) |
---|
| 114 | // tags: |
---|
| 115 | // protected |
---|
| 116 | this.focusChild(this._getNextFocusableChild(this.focusedChild, -1), true); |
---|
| 117 | }, |
---|
| 118 | |
---|
| 119 | childSelector: function(/*DOMNode*/ node){ |
---|
| 120 | // Implement _KeyNavMixin.childSelector, to identify focusable child nodes. |
---|
| 121 | // If we allowed a dojo/query dependency from this module this could more simply be a string "> *" |
---|
| 122 | // instead of this function. |
---|
| 123 | |
---|
| 124 | var node = registry.byNode(node); |
---|
| 125 | return node && node.getParent() == this; |
---|
| 126 | } |
---|
| 127 | }); |
---|
| 128 | }); |
---|