- /**
- * <p>The Focus Manager Node Plugin makes it easy to manage focus among
- * a Node's descendants. Primarily intended to help with widget development,
- * the Focus Manager Node Plugin can be used to improve the keyboard
- * accessibility of widgets.</p>
- *
- * <p>
- * When designing widgets that manage a set of descendant controls (i.e. buttons
- * in a toolbar, tabs in a tablist, menuitems in a menu, etc.) it is important to
- * limit the number of descendants in the browser's default tab flow. The fewer
- * number of descendants in the default tab flow, the easier it is for keyboard
- * users to navigate between widgets by pressing the tab key. When a widget has
- * focus it should provide a set of shortcut keys (typically the arrow keys)
- * to move focus among its descendants.
- * </p>
- *
- * <p>
- * To this end, the Focus Manager Node Plugin makes it easy to define a Node's
- * focusable descendants, define which descendant should be in the default tab
- * flow, and define the keys that move focus among each descendant.
- * Additionally, as the CSS
- * <a href="http://www.w3.org/TR/CSS21/selector.html#x38"><code>:focus</code></a>
- * pseudo class is not supported on all elements in all
- * <a href="http://developer.yahoo.com/yui/articles/gbs/">A-Grade browsers</a>,
- * the Focus Manager Node Plugin provides an easy, cross-browser means of
- * styling focus.
- * </p>
- *
-
- DEPRECATED: The FocusManager Node Plugin has been deprecated as of YUI 3.9.0. This module will be removed from the library in a future version. If you require functionality similar to the one provided by this module, consider taking a look at the various modules in the YUI Gallery <http://yuilibrary.com/gallery/>.
-
- * @module node-focusmanager
- * @deprecated 3.9.0
- */
-
- // Frequently used strings
-
- var ACTIVE_DESCENDANT = "activeDescendant",
- ID = "id",
- DISABLED = "disabled",
- TAB_INDEX = "tabIndex",
- FOCUSED = "focused",
- FOCUS_CLASS = "focusClass",
- CIRCULAR = "circular",
- UI = "UI",
- KEY = "key",
- ACTIVE_DESCENDANT_CHANGE = ACTIVE_DESCENDANT + "Change",
- HOST = "host",
-
- // Collection of keys that, when pressed, cause the browser viewport
- // to scroll.
- scrollKeys = {
- 37: true,
- 38: true,
- 39: true,
- 40: true
- },
-
- clickableElements = {
- "a": true,
- "button": true,
- "input": true,
- "object": true
- },
-
- // Library shortcuts
-
- Lang = Y.Lang,
- UA = Y.UA,
-
- /**
- * The NodeFocusManager class is a plugin for a Node instance. The class is used
- * via the <a href="Node.html#method_plug"><code>plug</code></a> method of Node
- * and should not be instantiated directly.
- * @namespace plugin
- * @class NodeFocusManager
- */
- NodeFocusManager = function () {
-
- NodeFocusManager.superclass.constructor.apply(this, arguments);
-
- };
-
-
- NodeFocusManager.ATTRS = {
-
- /**
- * Boolean indicating that one of the descendants is focused.
- *
- * @attribute focused
- * @readOnly
- * @default false
- * @type boolean
- */
- focused: {
-
- value: false,
- readOnly: true
-
- },
-
-
- /**
- * String representing the CSS selector used to define the descendant Nodes
- * whose focus should be managed.
- *
- * @attribute descendants
- * @type Y.NodeList
- */
- descendants: {
-
- getter: function (value) {
-
- return this.get(HOST).all(value);
-
- }
-
- },
-
-
- /**
- * <p>Node, or index of the Node, representing the descendant that is either
- * focused or is focusable (<code>tabIndex</code> attribute is set to 0).
- * The value cannot represent a disabled descendant Node. Use a value of -1
- * to remove all descendant Nodes from the default tab flow.
- * If no value is specified, the active descendant will be inferred using
- * the following criteria:</p>
- * <ol>
- * <li>Examining the <code>tabIndex</code> attribute of each descendant and
- * using the first descendant whose <code>tabIndex</code> attribute is set
- * to 0</li>
- * <li>If no default can be inferred then the value is set to either 0 or
- * the index of the first enabled descendant.</li>
- * </ol>
- *
- * @attribute activeDescendant
- * @type Number
- */
- activeDescendant: {
-
- setter: function (value) {
-
- var isNumber = Lang.isNumber,
- INVALID_VALUE = Y.Attribute.INVALID_VALUE,
- descendantsMap = this._descendantsMap,
- descendants = this._descendants,
- nodeIndex,
- returnValue,
- oNode;
-
-
- if (isNumber(value)) {
- nodeIndex = value;
- returnValue = nodeIndex;
- }
- else if ((value instanceof Y.Node) && descendantsMap) {
-
- nodeIndex = descendantsMap[value.get(ID)];
-
- if (isNumber(nodeIndex)) {
- returnValue = nodeIndex;
- }
- else {
-
- // The user passed a reference to a Node that wasn't one
- // of the descendants.
- returnValue = INVALID_VALUE;
-
- }
-
- }
- else {
- returnValue = INVALID_VALUE;
- }
-
-
- if (descendants) {
-
- oNode = descendants.item(nodeIndex);
-
- if (oNode && oNode.get("disabled")) {
-
- // Setting the "activeDescendant" attribute to the index
- // of a disabled descendant is invalid.
- returnValue = INVALID_VALUE;
-
- }
-
- }
-
-
- return returnValue;
-
- }
-
- },
-
-
- /**
- * Object literal representing the keys to be used to navigate between the
- * next/previous descendant. The format for the attribute's value is
- * <code>{ next: "down:40", previous: "down:38" }</code>. The value for the
- * "next" and "previous" properties are used to attach
- * <a href="event/#keylistener"><code>key</code></a> event listeners. See
- * the <a href="event/#keylistener">Using the key Event</a> section of
- * the Event documentation for more information on "key" event listeners.
- *
- * @attribute keys
- * @type Object
- */
- keys: {
-
- value: {
-
- next: null,
- previous: null
-
- }
-
-
- },
-
-
- /**
- * String representing the name of class applied to the focused active
- * descendant Node. Can also be an object literal used to define both the
- * class name, and the Node to which the class should be applied. If using
- * an object literal, the format is:
- * <code>{ className: "focus", fn: myFunction }</code>. The function
- * referenced by the <code>fn</code> property in the object literal will be
- * passed a reference to the currently focused active descendant Node.
- *
- * @attribute focusClass
- * @type String|Object
- */
- focusClass: { },
-
-
- /**
- * Boolean indicating if focus should be set to the first/last descendant
- * when the end or beginning of the descendants has been reached.
- *
- * @attribute circular
- * @type Boolean
- * @default true
- */
- circular: {
- value: true
- }
-
- };
-
- Y.extend(NodeFocusManager, Y.Plugin.Base, {
-
- // Protected properties
-
- // Boolean indicating if the NodeFocusManager is active.
- _stopped: true,
-
- // NodeList representing the descendants selected via the
- // "descendants" attribute.
- _descendants: null,
-
- // Object literal mapping the IDs of each descendant to its index in the
- // "_descendants" NodeList.
- _descendantsMap: null,
-
- // Reference to the Node instance to which the focused class (defined
- // by the "focusClass" attribute) is currently applied.
- _focusedNode: null,
-
- // Number representing the index of the last descendant Node.
- _lastNodeIndex: 0,
-
- // Array of handles for event handlers used for a NodeFocusManager instance.
- _eventHandlers: null,
-
-
-
- // Protected methods
-
- /**
- * @method _initDescendants
- * @description Sets the <code>tabIndex</code> attribute of all of the
- * descendants to -1, except the active descendant, whose
- * <code>tabIndex</code> attribute is set to 0.
- * @protected
- */
- _initDescendants: function () {
-
- var descendants = this.get("descendants"),
- descendantsMap = {},
- nFirstEnabled = -1,
- nDescendants,
- nActiveDescendant = this.get(ACTIVE_DESCENDANT),
- oNode,
- sID,
- i = 0;
-
-
-
- if (Lang.isUndefined(nActiveDescendant)) {
- nActiveDescendant = -1;
- }
-
-
- if (descendants) {
-
- nDescendants = descendants.size();
-
-
- for (i = 0; i < nDescendants; i++) {
-
- oNode = descendants.item(i);
-
- if (nFirstEnabled === -1 && !oNode.get(DISABLED)) {
- nFirstEnabled = i;
- }
-
-
- // If the user didn't specify a value for the
- // "activeDescendant" attribute try to infer it from
- // the markup.
-
- // Need to pass "2" when using "getAttribute" for IE to get
- // the attribute value as it is set in the markup.
- // Need to use "parseInt" because IE always returns the
- // value as a number, whereas all other browsers return
- // the attribute as a string when accessed
- // via "getAttribute".
-
- if (nActiveDescendant < 0 &&
- parseInt(oNode.getAttribute(TAB_INDEX, 2), 10) === 0) {
-
- nActiveDescendant = i;
-
- }
-
- if (oNode) {
- oNode.set(TAB_INDEX, -1);
- }
-
- sID = oNode.get(ID);
-
- if (!sID) {
- sID = Y.guid();
- oNode.set(ID, sID);
- }
-
- descendantsMap[sID] = i;
-
- }
-
-
- // If the user didn't specify a value for the
- // "activeDescendant" attribute and no default value could be
- // determined from the markup, then default to 0.
-
- if (nActiveDescendant < 0) {
- nActiveDescendant = 0;
- }
-
-
- oNode = descendants.item(nActiveDescendant);
-
- // Check to make sure the active descendant isn't disabled,
- // and fall back to the first enabled descendant if it is.
-
- if (!oNode || oNode.get(DISABLED)) {
- oNode = descendants.item(nFirstEnabled);
- nActiveDescendant = nFirstEnabled;
- }
-
- this._lastNodeIndex = nDescendants - 1;
- this._descendants = descendants;
- this._descendantsMap = descendantsMap;
-
- this.set(ACTIVE_DESCENDANT, nActiveDescendant);
-
- // Need to set the "tabIndex" attribute here, since the
- // "activeDescendantChange" event handler used to manage
- // the setting of the "tabIndex" attribute isn't wired up yet.
-
- if (oNode) {
- oNode.set(TAB_INDEX, 0);
- }
-
- }
-
- },
-
-
- /**
- * @method _isDescendant
- * @description Determines if the specified Node instance is a descendant
- * managed by the Focus Manager.
- * @param node {Node} Node instance to be checked.
- * @return {Boolean} Boolean indicating if the specified Node instance is a
- * descendant managed by the Focus Manager.
- * @protected
- */
- _isDescendant: function (node) {
-
- return (node.get(ID) in this._descendantsMap);
-
- },
-
-
- /**
- * @method _removeFocusClass
- * @description Removes the class name representing focus (as specified by
- * the "focusClass" attribute) from the Node instance to which it is
- * currently applied.
- * @protected
- */
- _removeFocusClass: function () {
-
- var oFocusedNode = this._focusedNode,
- focusClass = this.get(FOCUS_CLASS),
- sClassName;
-
- if (focusClass) {
- sClassName = Lang.isString(focusClass) ?
- focusClass : focusClass.className;
- }
-
- if (oFocusedNode && sClassName) {
- oFocusedNode.removeClass(sClassName);
- }
-
- },
-
-
- /**
- * @method _detachKeyHandler
- * @description Detaches the "key" event handlers used to support the "keys"
- * attribute.
- * @protected
- */
- _detachKeyHandler: function () {
-
- var prevKeyHandler = this._prevKeyHandler,
- nextKeyHandler = this._nextKeyHandler;
-
- if (prevKeyHandler) {
- prevKeyHandler.detach();
- }
-
- if (nextKeyHandler) {
- nextKeyHandler.detach();
- }
-
- },
-
-
- /**
- * @method _preventScroll
- * @description Prevents the viewport from scolling when the user presses
- * the up, down, left, or right key.
- * @protected
- */
- _preventScroll: function (event) {
-
- if (scrollKeys[event.keyCode] && this._isDescendant(event.target)) {
- event.preventDefault();
- }
-
- },
-
-
- /**
- * @method _fireClick
- * @description Fires the click event if the enter key is pressed while
- * focused on an HTML element that is not natively clickable.
- * @protected
- */
- _fireClick: function (event) {
-
- var oTarget = event.target,
- sNodeName = oTarget.get("nodeName").toLowerCase();
-
- if (event.keyCode === 13 && (!clickableElements[sNodeName] ||
- (sNodeName === "a" && !oTarget.getAttribute("href")))) {
-
- Y.log(("Firing click event for node:" + oTarget.get("id")), "info", "nodeFocusManager");
-
- oTarget.simulate("click");
-
- }
-
- },
-
-
- /**
- * @method _attachKeyHandler
- * @description Attaches the "key" event handlers used to support the "keys"
- * attribute.
- * @protected
- */
- _attachKeyHandler: function () {
-
- this._detachKeyHandler();
-
- var sNextKey = this.get("keys.next"),
- sPrevKey = this.get("keys.previous"),
- oNode = this.get(HOST),
- aHandlers = this._eventHandlers;
-
- if (sPrevKey) {
- this._prevKeyHandler =
- Y.on(KEY, Y.bind(this._focusPrevious, this), oNode, sPrevKey);
- }
-
- if (sNextKey) {
- this._nextKeyHandler =
- Y.on(KEY, Y.bind(this._focusNext, this), oNode, sNextKey);
- }
-
-
- // In Opera it is necessary to call the "preventDefault" method in
- // response to the user pressing the arrow keys in order to prevent
- // the viewport from scrolling when the user is moving focus among
- // the focusable descendants.
-
- if (UA.opera) {
- aHandlers.push(oNode.on("keypress", this._preventScroll, this));
- }
-
-
- // For all browsers except Opera: HTML elements that are not natively
- // focusable but made focusable via the tabIndex attribute don't
- // fire a click event when the user presses the enter key. It is
- // possible to work around this problem by simplying dispatching a
- // click event in response to the user pressing the enter key.
-
- if (!UA.opera) {
- aHandlers.push(oNode.on("keypress", this._fireClick, this));
- }
-
- },
-
-
- /**
- * @method _detachEventHandlers
- * @description Detaches all event handlers used by the Focus Manager.
- * @protected
- */
- _detachEventHandlers: function () {
-
- this._detachKeyHandler();
-
- var aHandlers = this._eventHandlers;
-
- if (aHandlers) {
-
- Y.Array.each(aHandlers, function (handle) {
- handle.detach();
- });
-
- this._eventHandlers = null;
-
- }
-
- },
-
-
- /**
- * @method _detachEventHandlers
- * @description Attaches all event handlers used by the Focus Manager.
- * @protected
- */
- _attachEventHandlers: function () {
-
- var descendants = this._descendants,
- aHandlers,
- oDocument,
- handle;
-
- if (descendants && descendants.size()) {
-
- aHandlers = this._eventHandlers || [];
- oDocument = this.get(HOST).get("ownerDocument");
-
-
- if (aHandlers.length === 0) {
-
- Y.log("Attaching base set of event handlers.", "info", "nodeFocusManager");
-
- aHandlers.push(oDocument.on("focus", this._onDocFocus, this));
-
- aHandlers.push(oDocument.on("mousedown",
- this._onDocMouseDown, this));
-
- aHandlers.push(
- this.after("keysChange", this._attachKeyHandler));
-
- aHandlers.push(
- this.after("descendantsChange", this._initDescendants));
-
- aHandlers.push(
- this.after(ACTIVE_DESCENDANT_CHANGE,
- this._afterActiveDescendantChange));
-
-
- // For performance: defer attaching all key-related event
- // handlers until the first time one of the specified
- // descendants receives focus.
-
- handle = this.after("focusedChange", Y.bind(function (event) {
-
- if (event.newVal) {
-
- Y.log("Attaching key event handlers.", "info", "nodeFocusManager");
-
- this._attachKeyHandler();
-
- // Detach this "focusedChange" handler so that the
- // key-related handlers only get attached once.
-
- handle.detach();
-
- }
-
- }, this));
-
- aHandlers.push(handle);
-
- }
-
-
- this._eventHandlers = aHandlers;
-
- }
-
- },
-
-
- // Protected event handlers
-
- /**
- * @method _onDocMouseDown
- * @description "mousedown" event handler for the owner document of the
- * Focus Manager's Node.
- * @protected
- * @param event {Object} Object representing the DOM event.
- */
- _onDocMouseDown: function (event) {
-
- var oHost = this.get(HOST),
- oTarget = event.target,
- bChildNode = oHost.contains(oTarget),
- node,
-
- getFocusable = function (node) {
-
- var returnVal = false;
-
- if (!node.compareTo(oHost)) {
-
- returnVal = this._isDescendant(node) ? node :
- getFocusable.call(this, node.get("parentNode"));
-
- }
-
- return returnVal;
-
- };
-
-
- if (bChildNode) {
-
- // Check to make sure that the target isn't a child node of one
- // of the focusable descendants.
-
- node = getFocusable.call(this, oTarget);
-
- if (node) {
- oTarget = node;
- }
- else if (!node && this.get(FOCUSED)) {
-
- // The target was a non-focusable descendant of the root
- // node, so the "focused" attribute should be set to false.
-
- this._set(FOCUSED, false);
- this._onDocFocus(event);
-
- }
-
- }
-
-
- if (bChildNode && this._isDescendant(oTarget)) {
-
- // Fix general problem in Webkit: mousing down on a button or an
- // anchor element doesn't focus it.
-
- // For all browsers: makes sure that the descendant that
- // was the target of the mousedown event is now considered the
- // active descendant.
-
- this.focus(oTarget);
- }
- else if (UA.webkit && this.get(FOCUSED) &&
- (!bChildNode || (bChildNode && !this._isDescendant(oTarget)))) {
-
- // Fix for Webkit:
-
- // Document doesn't receive focus in Webkit when the user mouses
- // down on it, so the "focused" attribute won't get set to the
- // correct value.
-
- // The goal is to force a blur if the user moused down on
- // either: 1) A descendant node, but not one that managed by
- // the FocusManager, or 2) an element outside of the
- // FocusManager
-
- this._set(FOCUSED, false);
- this._onDocFocus(event);
-
- }
-
- },
-
-
- /**
- * @method _onDocFocus
- * @description "focus" event handler for the owner document of the
- * Focus Manager's Node.
- * @protected
- * @param event {Object} Object representing the DOM event.
- */
- _onDocFocus: function (event) {
-
- var oTarget = this._focusTarget || event.target,
- bFocused = this.get(FOCUSED),
- focusClass = this.get(FOCUS_CLASS),
- oFocusedNode = this._focusedNode,
- bInCollection;
-
- if (this._focusTarget) {
- this._focusTarget = null;
- }
-
-
- if (this.get(HOST).contains(oTarget)) {
-
- // The target is a descendant of the root Node.
-
- bInCollection = this._isDescendant(oTarget);
-
- if (!bFocused && bInCollection) {
-
- // The user has focused a focusable descendant.
-
- bFocused = true;
-
- }
- else if (bFocused && !bInCollection) {
-
- // The user has focused a child of the root Node that is
- // not one of the descendants managed by this Focus Manager
- // so clear the currently focused descendant.
-
- bFocused = false;
-
- }
-
- }
- else {
-
- // The target is some other node in the document.
-
- bFocused = false;
-
- }
-
-
- if (focusClass) {
-
- if (oFocusedNode && (!oFocusedNode.compareTo(oTarget) || !bFocused)) {
- this._removeFocusClass();
- }
-
- if (bInCollection && bFocused) {
-
- if (focusClass.fn) {
- oTarget = focusClass.fn(oTarget);
- oTarget.addClass(focusClass.className);
- }
- else {
- oTarget.addClass(focusClass);
- }
-
- this._focusedNode = oTarget;
-
- }
-
- }
-
-
- this._set(FOCUSED, bFocused);
-
- },
-
-
- /**
- * @method _focusNext
- * @description Keydown event handler that moves focus to the next
- * enabled descendant.
- * @protected
- * @param event {Object} Object representing the DOM event.
- * @param activeDescendant {Number} Number representing the index of the
- * next descendant to be focused
- */
- _focusNext: function (event, activeDescendant) {
-
- var nActiveDescendant = activeDescendant || this.get(ACTIVE_DESCENDANT),
- oNode;
-
-
- if (this._isDescendant(event.target) &&
- (nActiveDescendant <= this._lastNodeIndex)) {
-
- nActiveDescendant = nActiveDescendant + 1;
-
- if (nActiveDescendant === (this._lastNodeIndex + 1) &&
- this.get(CIRCULAR)) {
-
- nActiveDescendant = 0;
-
- }
-
- oNode = this._descendants.item(nActiveDescendant);
-
- if (oNode) {
-
- if (oNode.get("disabled")) {
- this._focusNext(event, nActiveDescendant);
- }
- else {
- this.focus(nActiveDescendant);
- }
-
- }
-
- }
-
- this._preventScroll(event);
-
- },
-
-
- /**
- * @method _focusPrevious
- * @description Keydown event handler that moves focus to the previous
- * enabled descendant.
- * @protected
- * @param event {Object} Object representing the DOM event.
- * @param activeDescendant {Number} Number representing the index of the
- * next descendant to be focused.
- */
- _focusPrevious: function (event, activeDescendant) {
-
- var nActiveDescendant = activeDescendant || this.get(ACTIVE_DESCENDANT),
- oNode;
-
- if (this._isDescendant(event.target) && nActiveDescendant >= 0) {
-
- nActiveDescendant = nActiveDescendant - 1;
-
- if (nActiveDescendant === -1 && this.get(CIRCULAR)) {
- nActiveDescendant = this._lastNodeIndex;
- }
-
- oNode = this._descendants.item(nActiveDescendant);
-
- if (oNode) {
-
- if (oNode.get("disabled")) {
- this._focusPrevious(event, nActiveDescendant);
- }
- else {
- this.focus(nActiveDescendant);
- }
-
- }
-
- }
-
- this._preventScroll(event);
-
- },
-
-
- /**
- * @method _afterActiveDescendantChange
- * @description afterChange event handler for the
- * "activeDescendant" attribute.
- * @protected
- * @param event {Object} Object representing the change event.
- */
- _afterActiveDescendantChange: function (event) {
-
- var oNode = this._descendants.item(event.prevVal);
-
- if (oNode) {
- oNode.set(TAB_INDEX, -1);
- }
-
- oNode = this._descendants.item(event.newVal);
-
- if (oNode) {
- oNode.set(TAB_INDEX, 0);
- }
-
- },
-
-
-
- // Public methods
-
- initializer: function (config) {
- Y.log("WARNING: node-focusmanager is a deprecated module as of YUI 3.9.0. This module will be removed from a later version of the library.", "warn");
- this.start();
-
- },
-
- destructor: function () {
-
- this.stop();
- this.get(HOST).focusManager = null;
-
- },
-
-
- /**
- * @method focus
- * @description Focuses the active descendant and sets the
- * <code>focused</code> attribute to true.
- * @param index {Number} Optional. Number representing the index of the
- * descendant to be set as the active descendant.
- * @param index {Node} Optional. Node instance representing the
- * descendant to be set as the active descendant.
- */
- focus: function (index) {
-
- if (Lang.isUndefined(index)) {
- index = this.get(ACTIVE_DESCENDANT);
- }
-
- this.set(ACTIVE_DESCENDANT, index, { src: UI });
-
- var oNode = this._descendants.item(this.get(ACTIVE_DESCENDANT));
-
- if (oNode) {
-
- oNode.focus();
-
- // In Opera focusing a <BUTTON> element programmatically
- // will result in the document-level focus event handler
- // "_onDocFocus" being called, resulting in the handler
- // incorrectly setting the "focused" Attribute to false. To fix
- // this, set a flag ("_focusTarget") that the "_onDocFocus" method
- // can look for to properly handle this edge case.
-
- if (UA.opera && oNode.get("nodeName").toLowerCase() === "button") {
- this._focusTarget = oNode;
- }
-
- }
-
- },
-
-
- /**
- * @method blur
- * @description Blurs the current active descendant and sets the
- * <code>focused</code> attribute to false.
- */
- blur: function () {
-
- var oNode;
-
- if (this.get(FOCUSED)) {
-
- oNode = this._descendants.item(this.get(ACTIVE_DESCENDANT));
-
- if (oNode) {
-
- oNode.blur();
-
- // For Opera and Webkit: Blurring an element in either browser
- // doesn't result in another element (such as the document)
- // being focused. Therefore, the "_onDocFocus" method
- // responsible for managing the application and removal of the
- // focus indicator class name is never called.
-
- this._removeFocusClass();
-
- }
-
- this._set(FOCUSED, false, { src: UI });
- }
-
- },
-
-
- /**
- * @method start
- * @description Enables the Focus Manager.
- */
- start: function () {
-
- if (this._stopped) {
-
- this._initDescendants();
- this._attachEventHandlers();
-
- this._stopped = false;
-
- }
-
- },
-
-
- /**
- * @method stop
- * @description Disables the Focus Manager by detaching all event handlers.
- */
- stop: function () {
-
- if (!this._stopped) {
-
- this._detachEventHandlers();
-
- this._descendants = null;
- this._focusedNode = null;
- this._lastNodeIndex = 0;
- this._stopped = true;
-
- }
-
- },
-
-
- /**
- * @method refresh
- * @description Refreshes the Focus Manager's descendants by re-executing the
- * CSS selector query specified by the <code>descendants</code> attribute.
- */
- refresh: function () {
-
- this._initDescendants();
-
- if (!this._eventHandlers) {
- this._attachEventHandlers();
- }
-
- }
-
- });
-
-
- NodeFocusManager.NAME = "nodeFocusManager";
- NodeFocusManager.NS = "focusManager";
-
- Y.namespace("Plugin");
- Y.Plugin.NodeFocusManager = NodeFocusManager;
-
-