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