[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 YUI.add('moodle-core-widget-focusafterclose', function (Y, NAME) { 2 3 /** 4 * Provides support for focusing on different nodes after the Widget is 5 * hidden. 6 * 7 * If the focusOnPreviousTargetAfterHide attribute is true, then the module hooks 8 * into the show function for that Widget to try and determine which Node 9 * caused the Widget to be shown. 10 * 11 * Alternatively, the focusAfterHide attribute can be passed a Node. 12 * 13 * @module moodle-core-widget-focusafterhide 14 */ 15 16 var CAN_RECEIVE_FOCUS_SELECTOR = 'input:not([type="hidden"]), ' + 17 'a[href], button, textarea, select, ' + 18 '[tabindex], [contenteditable="true"]'; 19 20 /** 21 * Provides support for focusing on different nodes after the Widget is 22 * hidden. 23 * 24 * @class M.core.WidgetFocusAfterHide 25 */ 26 function WidgetFocusAfterHide() { 27 Y.after(this._bindUIFocusAfterHide, this, 'bindUI'); 28 if (this.get('rendered')) { 29 this._bindUIFocusAfterHide(); 30 } 31 } 32 33 WidgetFocusAfterHide.ATTRS = { 34 /** 35 * Whether to focus on the target that caused the Widget to be shown. 36 * 37 * <em>If this is true, and a valid Node is found, any Node specified to focusAfterHide 38 * will be ignored.</em> 39 * 40 * @attribute focusOnPreviousTargetAfterHide 41 * @default false 42 * @type boolean 43 */ 44 focusOnPreviousTargetAfterHide: { 45 value: false 46 }, 47 48 /** 49 * The Node to focus on after hiding the Widget. 50 * 51 * <em>Note: If focusOnPreviousTargetAfterHide is true, and a valid Node is found, then this 52 * value will be ignored. If it is true and not found, then this value will be used as 53 * a fallback.</em> 54 * 55 * @attribute focusAfterHide 56 * @default null 57 * @type Node 58 */ 59 focusAfterHide: { 60 value: null, 61 type: Y.Node 62 } 63 }; 64 65 WidgetFocusAfterHide.prototype = { 66 /** 67 * The list of Event Handles which we should cancel when the dialogue is destroyed. 68 * 69 * @property uiHandleFocusAfterHide 70 * @type array 71 * @protected 72 */ 73 _uiHandlesFocusAfterHide: [], 74 75 /** 76 * A reference to the real show method which is being overwritten. 77 * 78 * @property _showFocusAfterHide 79 * @type function 80 * @default null 81 * @protected 82 */ 83 _showFocusAfterHide: null, 84 85 /** 86 * A reference to the detected previous target. 87 * 88 * @property _previousTargetFocusAfterHide 89 * @type function 90 * @default null 91 * @protected 92 */ 93 _previousTargetFocusAfterHide: null, 94 95 initializer: function() { 96 97 if (this.get('focusOnPreviousTargetAfterHide') && this.show) { 98 // Overwrite the parent method so that we can get the focused 99 // target. 100 this._showFocusAfterHide = this.show; 101 this.show = function(e) { 102 this._showFocusAfterHide.apply(this, arguments); 103 104 // We use a property rather than overriding the focusAfterHide parameter in 105 // case the target cannot be found at hide time. 106 this._previousTargetFocusAfterHide = null; 107 if (e && e.currentTarget) { 108 Y.log("Determined a Node which caused the Widget to be shown", 109 'debug', 'moodle-core-widget-focusafterhide'); 110 this._previousTargetFocusAfterHide = e.currentTarget; 111 } 112 }; 113 } 114 }, 115 116 destructor: function() { 117 new Y.EventHandle(this.uiHandleFocusAfterHide).detach(); 118 }, 119 120 /** 121 * Set up the event handling required for this module to work. 122 * 123 * @method _bindUIFocusAfterHide 124 * @private 125 */ 126 _bindUIFocusAfterHide: function() { 127 // Detach the old handles first. 128 new Y.EventHandle(this.uiHandleFocusAfterHide).detach(); 129 this.uiHandleFocusAfterHide = [ 130 this.after('visibleChange', this._afterHostVisibleChangeFocusAfterHide) 131 ]; 132 }, 133 134 /** 135 * Handle the change in UI visibility. 136 * 137 * This method changes the focus after the hide has taken place. 138 * 139 * @method _afterHostVisibleChangeFocusAfterHide 140 * @private 141 */ 142 _afterHostVisibleChangeFocusAfterHide: function() { 143 if (!this.get('visible')) { 144 if (this._attemptFocus(this._previousTargetFocusAfterHide)) { 145 Y.log("Focusing on the target automatically determined when the Widget was opened", 146 'debug', 'moodle-core-widget-focusafterhide'); 147 148 } else if (this._attemptFocus(this.get('focusAfterHide'))) { 149 // Fall back to the focusAfterHide value if one was specified. 150 Y.log("Focusing on the target provided to focusAfterHide", 151 'debug', 'moodle-core-widget-focusafterhide'); 152 153 } else { 154 Y.log("No valid focus target found - not returning focus.", 155 'debug', 'moodle-core-widget-focusafterhide'); 156 157 } 158 } 159 }, 160 161 _attemptFocus: function(node) { 162 var focusTarget = Y.one(node); 163 if (focusTarget) { 164 focusTarget = focusTarget.ancestor(CAN_RECEIVE_FOCUS_SELECTOR, true); 165 if (focusTarget) { 166 focusTarget.focus(); 167 return true; 168 } 169 } 170 return false; 171 } 172 }; 173 174 var NS = Y.namespace('M.core'); 175 NS.WidgetFocusAfterHide = WidgetFocusAfterHide; 176 177 178 }, '@VERSION@', {"requires": ["base-build", "widget"]});
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |