|
525
|
1 |
/* |
|
|
2 |
YUI 3.10.3 (build 2fb5187) |
|
|
3 |
Copyright 2013 Yahoo! Inc. All rights reserved. |
|
|
4 |
Licensed under the BSD License. |
|
|
5 |
http://yuilibrary.com/license/ |
|
|
6 |
*/ |
|
|
7 |
|
|
|
8 |
YUI.add('widget-modality', function (Y, NAME) { |
|
|
9 |
|
|
|
10 |
/** |
|
|
11 |
* Provides modality support for Widgets, though an extension |
|
|
12 |
* |
|
|
13 |
* @module widget-modality |
|
|
14 |
*/ |
|
|
15 |
|
|
|
16 |
var WIDGET = 'widget', |
|
|
17 |
RENDER_UI = 'renderUI', |
|
|
18 |
BIND_UI = 'bindUI', |
|
|
19 |
SYNC_UI = 'syncUI', |
|
|
20 |
BOUNDING_BOX = 'boundingBox', |
|
|
21 |
CONTENT_BOX = 'contentBox', |
|
|
22 |
VISIBLE = 'visible', |
|
|
23 |
Z_INDEX = 'zIndex', |
|
|
24 |
CHANGE = 'Change', |
|
|
25 |
isBoolean = Y.Lang.isBoolean, |
|
|
26 |
getCN = Y.ClassNameManager.getClassName, |
|
|
27 |
MaskShow = "maskShow", |
|
|
28 |
MaskHide = "maskHide", |
|
|
29 |
ClickOutside = "clickoutside", |
|
|
30 |
FocusOutside = "focusoutside", |
|
|
31 |
|
|
|
32 |
supportsPosFixed = (function(){ |
|
|
33 |
|
|
|
34 |
/*! IS_POSITION_FIXED_SUPPORTED - Juriy Zaytsev (kangax) - http://yura.thinkweb2.com/cft/ */ |
|
|
35 |
|
|
|
36 |
var doc = Y.config.doc, |
|
|
37 |
isSupported = null, |
|
|
38 |
el, root; |
|
|
39 |
|
|
|
40 |
if (doc.createElement) { |
|
|
41 |
el = doc.createElement('div'); |
|
|
42 |
if (el && el.style) { |
|
|
43 |
el.style.position = 'fixed'; |
|
|
44 |
el.style.top = '10px'; |
|
|
45 |
root = doc.body; |
|
|
46 |
if (root && root.appendChild && root.removeChild) { |
|
|
47 |
root.appendChild(el); |
|
|
48 |
isSupported = (el.offsetTop === 10); |
|
|
49 |
root.removeChild(el); |
|
|
50 |
} |
|
|
51 |
} |
|
|
52 |
} |
|
|
53 |
|
|
|
54 |
return isSupported; |
|
|
55 |
}()); |
|
|
56 |
|
|
|
57 |
/** |
|
|
58 |
* Widget extension, which can be used to add modality support to the base Widget class, |
|
|
59 |
* through the Base.create method. |
|
|
60 |
* |
|
|
61 |
* @class WidgetModality |
|
|
62 |
* @param {Object} config User configuration object |
|
|
63 |
*/ |
|
|
64 |
function WidgetModal(config) {} |
|
|
65 |
|
|
|
66 |
var MODAL = 'modal', |
|
|
67 |
MASK = 'mask', |
|
|
68 |
MODAL_CLASSES = { |
|
|
69 |
modal : getCN(WIDGET, MODAL), |
|
|
70 |
mask : getCN(WIDGET, MASK) |
|
|
71 |
}; |
|
|
72 |
|
|
|
73 |
/** |
|
|
74 |
* Static property used to define the default attribute |
|
|
75 |
* configuration introduced by WidgetModality. |
|
|
76 |
* |
|
|
77 |
* @property ATTRS |
|
|
78 |
* @static |
|
|
79 |
* @type Object |
|
|
80 |
*/ |
|
|
81 |
WidgetModal.ATTRS = { |
|
|
82 |
/** |
|
|
83 |
* @attribute maskNode |
|
|
84 |
* @type Y.Node |
|
|
85 |
* |
|
|
86 |
* @description Returns a Y.Node instance of the node being used as the mask. |
|
|
87 |
*/ |
|
|
88 |
maskNode : { |
|
|
89 |
getter : '_getMaskNode', |
|
|
90 |
readOnly : true |
|
|
91 |
}, |
|
|
92 |
|
|
|
93 |
|
|
|
94 |
/** |
|
|
95 |
* @attribute modal |
|
|
96 |
* @type boolean |
|
|
97 |
* |
|
|
98 |
* @description Whether the widget should be modal or not. |
|
|
99 |
*/ |
|
|
100 |
modal: { |
|
|
101 |
value:false, |
|
|
102 |
validator: isBoolean |
|
|
103 |
}, |
|
|
104 |
|
|
|
105 |
/** |
|
|
106 |
* @attribute focusOn |
|
|
107 |
* @type array |
|
|
108 |
* |
|
|
109 |
* @description An array of objects corresponding to the nodes and events that will trigger a re-focus back on the widget. |
|
|
110 |
* The implementer can supply an array of objects, with each object having the following properties: |
|
|
111 |
* <p>eventName: (string, required): The eventName to listen to.</p> |
|
|
112 |
* <p>node: (Y.Node, optional): The Y.Node that will fire the event (defaults to the boundingBox of the widget)</p> |
|
|
113 |
* <p>By default, this attribute consists of two objects which will cause the widget to re-focus if anything |
|
|
114 |
* outside the widget is clicked on or focussed upon.</p> |
|
|
115 |
*/ |
|
|
116 |
focusOn: { |
|
|
117 |
valueFn: function() { |
|
|
118 |
return [ |
|
|
119 |
{ |
|
|
120 |
// node: this.get(BOUNDING_BOX), |
|
|
121 |
eventName: ClickOutside |
|
|
122 |
}, |
|
|
123 |
{ |
|
|
124 |
//node: this.get(BOUNDING_BOX), |
|
|
125 |
eventName: FocusOutside |
|
|
126 |
} |
|
|
127 |
]; |
|
|
128 |
}, |
|
|
129 |
|
|
|
130 |
validator: Y.Lang.isArray |
|
|
131 |
} |
|
|
132 |
|
|
|
133 |
}; |
|
|
134 |
|
|
|
135 |
|
|
|
136 |
WidgetModal.CLASSES = MODAL_CLASSES; |
|
|
137 |
|
|
|
138 |
|
|
|
139 |
/** |
|
|
140 |
* Returns the mask if it exists on the page - otherwise creates a mask. There's only |
|
|
141 |
* one mask on a page at a given time. |
|
|
142 |
* <p> |
|
|
143 |
* This method in invoked internally by the getter of the maskNode ATTR. |
|
|
144 |
* </p> |
|
|
145 |
* @method _GET_MASK |
|
|
146 |
* @static |
|
|
147 |
*/ |
|
|
148 |
WidgetModal._GET_MASK = function() { |
|
|
149 |
|
|
|
150 |
var mask = Y.one('.' + MODAL_CLASSES.mask), |
|
|
151 |
win = Y.one('win'); |
|
|
152 |
|
|
|
153 |
if (mask) { |
|
|
154 |
return mask; |
|
|
155 |
} |
|
|
156 |
|
|
|
157 |
mask = Y.Node.create('<div></div>').addClass(MODAL_CLASSES.mask); |
|
|
158 |
|
|
|
159 |
if (supportsPosFixed) { |
|
|
160 |
mask.setStyles({ |
|
|
161 |
position: 'fixed', |
|
|
162 |
width : '100%', |
|
|
163 |
height : '100%', |
|
|
164 |
top : '0', |
|
|
165 |
left : '0', |
|
|
166 |
display : 'block' |
|
|
167 |
}); |
|
|
168 |
} else { |
|
|
169 |
mask.setStyles({ |
|
|
170 |
position: 'absolute', |
|
|
171 |
width : win.get('winWidth') +'px', |
|
|
172 |
height : win.get('winHeight') + 'px', |
|
|
173 |
top : '0', |
|
|
174 |
left : '0', |
|
|
175 |
display : 'block' |
|
|
176 |
}); |
|
|
177 |
} |
|
|
178 |
|
|
|
179 |
return mask; |
|
|
180 |
}; |
|
|
181 |
|
|
|
182 |
/** |
|
|
183 |
* A stack of Y.Widget objects representing the current hierarchy of modal widgets presently displayed on the screen |
|
|
184 |
* @property STACK |
|
|
185 |
*/ |
|
|
186 |
WidgetModal.STACK = []; |
|
|
187 |
|
|
|
188 |
|
|
|
189 |
WidgetModal.prototype = { |
|
|
190 |
|
|
|
191 |
initializer: function () { |
|
|
192 |
Y.after(this._renderUIModal, this, RENDER_UI); |
|
|
193 |
Y.after(this._syncUIModal, this, SYNC_UI); |
|
|
194 |
Y.after(this._bindUIModal, this, BIND_UI); |
|
|
195 |
}, |
|
|
196 |
|
|
|
197 |
destructor: function () { |
|
|
198 |
// Hack to remove this thing from the STACK. |
|
|
199 |
this._uiSetHostVisibleModal(false); |
|
|
200 |
}, |
|
|
201 |
|
|
|
202 |
// *** Instance Members *** // |
|
|
203 |
|
|
|
204 |
_uiHandlesModal: null, |
|
|
205 |
|
|
|
206 |
|
|
|
207 |
/** |
|
|
208 |
* Adds modal class to the bounding box of the widget |
|
|
209 |
* <p> |
|
|
210 |
* This method in invoked after renderUI is invoked for the Widget class |
|
|
211 |
* using YUI's aop infrastructure. |
|
|
212 |
* </p> |
|
|
213 |
* @method _renderUIModal |
|
|
214 |
* @protected |
|
|
215 |
*/ |
|
|
216 |
_renderUIModal : function () { |
|
|
217 |
|
|
|
218 |
var bb = this.get(BOUNDING_BOX); |
|
|
219 |
//cb = this.get(CONTENT_BOX); |
|
|
220 |
|
|
|
221 |
//this makes the content box content appear over the mask |
|
|
222 |
// cb.setStyles({ |
|
|
223 |
// position: "" |
|
|
224 |
// }); |
|
|
225 |
|
|
|
226 |
this._repositionMask(this); |
|
|
227 |
bb.addClass(MODAL_CLASSES.modal); |
|
|
228 |
|
|
|
229 |
}, |
|
|
230 |
|
|
|
231 |
|
|
|
232 |
/** |
|
|
233 |
* Hooks up methods to be executed when the widget's visibility or z-index changes |
|
|
234 |
* <p> |
|
|
235 |
* This method in invoked after bindUI is invoked for the Widget class |
|
|
236 |
* using YUI's aop infrastructure. |
|
|
237 |
* </p> |
|
|
238 |
* @method _bindUIModal |
|
|
239 |
* @protected |
|
|
240 |
*/ |
|
|
241 |
_bindUIModal : function () { |
|
|
242 |
|
|
|
243 |
this.after(VISIBLE+CHANGE, this._afterHostVisibleChangeModal); |
|
|
244 |
this.after(Z_INDEX+CHANGE, this._afterHostZIndexChangeModal); |
|
|
245 |
this.after("focusOnChange", this._afterFocusOnChange); |
|
|
246 |
|
|
|
247 |
// Re-align the mask in the viewport if `position: fixed;` is not |
|
|
248 |
// supported. iOS < 5 and Android < 3 don't actually support it even |
|
|
249 |
// though they both pass the feature test; the UA sniff is here to |
|
|
250 |
// account for that. Ideally this should be replaced with a better |
|
|
251 |
// feature test. |
|
|
252 |
if (!supportsPosFixed || |
|
|
253 |
(Y.UA.ios && Y.UA.ios < 5) || |
|
|
254 |
(Y.UA.android && Y.UA.android < 3)) { |
|
|
255 |
|
|
|
256 |
Y.one('win').on('scroll', this._resyncMask, this); |
|
|
257 |
} |
|
|
258 |
}, |
|
|
259 |
|
|
|
260 |
/** |
|
|
261 |
* Syncs the mask with the widget's current state, namely the visibility and z-index of the widget |
|
|
262 |
* <p> |
|
|
263 |
* This method in invoked after syncUI is invoked for the Widget class |
|
|
264 |
* using YUI's aop infrastructure. |
|
|
265 |
* </p> |
|
|
266 |
* @method _syncUIModal |
|
|
267 |
* @protected |
|
|
268 |
*/ |
|
|
269 |
_syncUIModal : function () { |
|
|
270 |
|
|
|
271 |
//var host = this.get(HOST); |
|
|
272 |
|
|
|
273 |
this._uiSetHostVisibleModal(this.get(VISIBLE)); |
|
|
274 |
|
|
|
275 |
}, |
|
|
276 |
|
|
|
277 |
/** |
|
|
278 |
* Provides mouse and tab focus to the widget's bounding box. |
|
|
279 |
* |
|
|
280 |
* @method _focus |
|
|
281 |
*/ |
|
|
282 |
_focus : function (e) { |
|
|
283 |
|
|
|
284 |
var bb = this.get(BOUNDING_BOX), |
|
|
285 |
oldTI = bb.get('tabIndex'); |
|
|
286 |
|
|
|
287 |
bb.set('tabIndex', oldTI >= 0 ? oldTI : 0); |
|
|
288 |
this.focus(); |
|
|
289 |
}, |
|
|
290 |
/** |
|
|
291 |
* Blurs the widget. |
|
|
292 |
* |
|
|
293 |
* @method _blur |
|
|
294 |
*/ |
|
|
295 |
_blur : function () { |
|
|
296 |
|
|
|
297 |
this.blur(); |
|
|
298 |
}, |
|
|
299 |
|
|
|
300 |
/** |
|
|
301 |
* Returns the Y.Node instance of the maskNode |
|
|
302 |
* |
|
|
303 |
* @method _getMaskNode |
|
|
304 |
* @return {Node} The Y.Node instance of the mask, as returned from WidgetModal._GET_MASK |
|
|
305 |
*/ |
|
|
306 |
_getMaskNode : function () { |
|
|
307 |
|
|
|
308 |
return WidgetModal._GET_MASK(); |
|
|
309 |
}, |
|
|
310 |
|
|
|
311 |
/** |
|
|
312 |
* Performs events attaching/detaching, stack shifting and mask repositioning based on the visibility of the widget |
|
|
313 |
* |
|
|
314 |
* @method _uiSetHostVisibleModal |
|
|
315 |
* @param {boolean} Whether the widget is visible or not |
|
|
316 |
*/ |
|
|
317 |
_uiSetHostVisibleModal : function (visible) { |
|
|
318 |
var stack = WidgetModal.STACK, |
|
|
319 |
maskNode = this.get('maskNode'), |
|
|
320 |
isModal = this.get('modal'), |
|
|
321 |
topModal, index; |
|
|
322 |
|
|
|
323 |
if (visible) { |
|
|
324 |
|
|
|
325 |
Y.Array.each(stack, function(modal){ |
|
|
326 |
modal._detachUIHandlesModal(); |
|
|
327 |
modal._blur(); |
|
|
328 |
}); |
|
|
329 |
|
|
|
330 |
// push on top of stack |
|
|
331 |
stack.unshift(this); |
|
|
332 |
|
|
|
333 |
this._repositionMask(this); |
|
|
334 |
this._uiSetHostZIndexModal(this.get(Z_INDEX)); |
|
|
335 |
|
|
|
336 |
if (isModal) { |
|
|
337 |
maskNode.show(); |
|
|
338 |
Y.later(1, this, '_attachUIHandlesModal'); |
|
|
339 |
this._focus(); |
|
|
340 |
} |
|
|
341 |
|
|
|
342 |
|
|
|
343 |
} else { |
|
|
344 |
|
|
|
345 |
index = Y.Array.indexOf(stack, this); |
|
|
346 |
if (index >= 0) { |
|
|
347 |
// Remove modal widget from global stack. |
|
|
348 |
stack.splice(index, 1); |
|
|
349 |
} |
|
|
350 |
|
|
|
351 |
this._detachUIHandlesModal(); |
|
|
352 |
this._blur(); |
|
|
353 |
|
|
|
354 |
if (stack.length) { |
|
|
355 |
topModal = stack[0]; |
|
|
356 |
this._repositionMask(topModal); |
|
|
357 |
//topModal._attachUIHandlesModal(); |
|
|
358 |
topModal._uiSetHostZIndexModal(topModal.get(Z_INDEX)); |
|
|
359 |
|
|
|
360 |
if (topModal.get('modal')) { |
|
|
361 |
//topModal._attachUIHandlesModal(); |
|
|
362 |
Y.later(1, topModal, '_attachUIHandlesModal'); |
|
|
363 |
topModal._focus(); |
|
|
364 |
} |
|
|
365 |
|
|
|
366 |
} else { |
|
|
367 |
|
|
|
368 |
if (maskNode.getStyle('display') === 'block') { |
|
|
369 |
maskNode.hide(); |
|
|
370 |
} |
|
|
371 |
|
|
|
372 |
} |
|
|
373 |
|
|
|
374 |
} |
|
|
375 |
}, |
|
|
376 |
|
|
|
377 |
/** |
|
|
378 |
* Sets the z-index of the mask node. |
|
|
379 |
* |
|
|
380 |
* @method _uiSetHostZIndexModal |
|
|
381 |
* @param {Number} Z-Index of the widget |
|
|
382 |
*/ |
|
|
383 |
_uiSetHostZIndexModal : function (zIndex) { |
|
|
384 |
|
|
|
385 |
if (this.get('modal')) { |
|
|
386 |
this.get('maskNode').setStyle(Z_INDEX, zIndex || 0); |
|
|
387 |
} |
|
|
388 |
|
|
|
389 |
}, |
|
|
390 |
|
|
|
391 |
/** |
|
|
392 |
* Attaches UI Listeners for "clickoutside" and "focusoutside" on the |
|
|
393 |
* widget. When these events occur, and the widget is modal, focus is |
|
|
394 |
* shifted back onto the widget. |
|
|
395 |
* |
|
|
396 |
* @method _attachUIHandlesModal |
|
|
397 |
*/ |
|
|
398 |
_attachUIHandlesModal : function () { |
|
|
399 |
|
|
|
400 |
if (this._uiHandlesModal || WidgetModal.STACK[0] !== this) { |
|
|
401 |
// Quit early if we have ui handles, or if we not at the top |
|
|
402 |
// of the global stack. |
|
|
403 |
return; |
|
|
404 |
} |
|
|
405 |
|
|
|
406 |
var bb = this.get(BOUNDING_BOX), |
|
|
407 |
maskNode = this.get('maskNode'), |
|
|
408 |
focusOn = this.get('focusOn'), |
|
|
409 |
focus = Y.bind(this._focus, this), |
|
|
410 |
uiHandles = [], |
|
|
411 |
i, len, o; |
|
|
412 |
|
|
|
413 |
for (i = 0, len = focusOn.length; i < len; i++) { |
|
|
414 |
|
|
|
415 |
o = {}; |
|
|
416 |
o.node = focusOn[i].node; |
|
|
417 |
o.ev = focusOn[i].eventName; |
|
|
418 |
o.keyCode = focusOn[i].keyCode; |
|
|
419 |
|
|
|
420 |
//no keycode or node defined |
|
|
421 |
if (!o.node && !o.keyCode && o.ev) { |
|
|
422 |
uiHandles.push(bb.on(o.ev, focus)); |
|
|
423 |
} |
|
|
424 |
|
|
|
425 |
//node defined, no keycode (not a keypress) |
|
|
426 |
else if (o.node && !o.keyCode && o.ev) { |
|
|
427 |
uiHandles.push(o.node.on(o.ev, focus)); |
|
|
428 |
} |
|
|
429 |
|
|
|
430 |
//node defined, keycode defined, event defined (its a key press) |
|
|
431 |
else if (o.node && o.keyCode && o.ev) { |
|
|
432 |
uiHandles.push(o.node.on(o.ev, focus, o.keyCode)); |
|
|
433 |
} |
|
|
434 |
|
|
|
435 |
else { |
|
|
436 |
Y.Log('focusOn ATTR Error: The event with name "'+o.ev+'" could not be attached.'); |
|
|
437 |
} |
|
|
438 |
|
|
|
439 |
} |
|
|
440 |
|
|
|
441 |
if ( ! supportsPosFixed) { |
|
|
442 |
uiHandles.push(Y.one('win').on('scroll', Y.bind(function(e){ |
|
|
443 |
maskNode.setStyle('top', maskNode.get('docScrollY')); |
|
|
444 |
}, this))); |
|
|
445 |
} |
|
|
446 |
|
|
|
447 |
this._uiHandlesModal = uiHandles; |
|
|
448 |
}, |
|
|
449 |
|
|
|
450 |
/** |
|
|
451 |
* Detaches all UI Listeners that were set in _attachUIHandlesModal from the widget. |
|
|
452 |
* |
|
|
453 |
* @method _detachUIHandlesModal |
|
|
454 |
*/ |
|
|
455 |
_detachUIHandlesModal : function () { |
|
|
456 |
Y.each(this._uiHandlesModal, function(h){ |
|
|
457 |
h.detach(); |
|
|
458 |
}); |
|
|
459 |
this._uiHandlesModal = null; |
|
|
460 |
}, |
|
|
461 |
|
|
|
462 |
/** |
|
|
463 |
* Default function that is called when visibility is changed on the widget. |
|
|
464 |
* |
|
|
465 |
* @method _afterHostVisibleChangeModal |
|
|
466 |
* @param {EventFacade} e The event facade of the change |
|
|
467 |
*/ |
|
|
468 |
_afterHostVisibleChangeModal : function (e) { |
|
|
469 |
|
|
|
470 |
this._uiSetHostVisibleModal(e.newVal); |
|
|
471 |
}, |
|
|
472 |
|
|
|
473 |
/** |
|
|
474 |
* Default function that is called when z-index is changed on the widget. |
|
|
475 |
* |
|
|
476 |
* @method _afterHostZIndexChangeModal |
|
|
477 |
* @param {EventFacade} e The event facade of the change |
|
|
478 |
*/ |
|
|
479 |
_afterHostZIndexChangeModal : function (e) { |
|
|
480 |
|
|
|
481 |
this._uiSetHostZIndexModal(e.newVal); |
|
|
482 |
}, |
|
|
483 |
|
|
|
484 |
/** |
|
|
485 |
* Returns a boolean representing whether the current widget is in a "nested modality" state. |
|
|
486 |
* This is done by checking the number of widgets currently on the stack. |
|
|
487 |
* |
|
|
488 |
* @method isNested |
|
|
489 |
* @public |
|
|
490 |
*/ |
|
|
491 |
isNested: function() { |
|
|
492 |
var length = WidgetModal.STACK.length, |
|
|
493 |
retval = (length > 1) ? true : false; |
|
|
494 |
return retval; |
|
|
495 |
}, |
|
|
496 |
|
|
|
497 |
/** |
|
|
498 |
* Repositions the mask in the DOM for nested modality cases. |
|
|
499 |
* |
|
|
500 |
* @method _repositionMask |
|
|
501 |
* @param {Widget} nextElem The Y.Widget instance that will be visible in the stack once the current widget is closed. |
|
|
502 |
*/ |
|
|
503 |
_repositionMask: function(nextElem) { |
|
|
504 |
|
|
|
505 |
var currentModal = this.get('modal'), |
|
|
506 |
nextModal = nextElem.get('modal'), |
|
|
507 |
maskNode = this.get('maskNode'), |
|
|
508 |
bb, bbParent; |
|
|
509 |
|
|
|
510 |
//if this is modal and host is not modal |
|
|
511 |
if (currentModal && !nextModal) { |
|
|
512 |
//leave the mask where it is, since the host is not modal. |
|
|
513 |
maskNode.remove(); |
|
|
514 |
this.fire(MaskHide); |
|
|
515 |
} |
|
|
516 |
|
|
|
517 |
//if the main widget is not modal but the host is modal, or both of them are modal |
|
|
518 |
else if ((!currentModal && nextModal) || (currentModal && nextModal)) { |
|
|
519 |
|
|
|
520 |
//then remove the mask off DOM, reposition it, and reinsert it into the DOM |
|
|
521 |
maskNode.remove(); |
|
|
522 |
this.fire(MaskHide); |
|
|
523 |
bb = nextElem.get(BOUNDING_BOX); |
|
|
524 |
bbParent = bb.get('parentNode') || Y.one('body'); |
|
|
525 |
bbParent.insert(maskNode, bbParent.get('firstChild')); |
|
|
526 |
this.fire(MaskShow); |
|
|
527 |
} |
|
|
528 |
|
|
|
529 |
}, |
|
|
530 |
|
|
|
531 |
/** |
|
|
532 |
* Resyncs the mask in the viewport for browsers that don't support fixed positioning |
|
|
533 |
* |
|
|
534 |
* @method _resyncMask |
|
|
535 |
* @param {Y.Widget} nextElem The Y.Widget instance that will be visible in the stack once the current widget is closed. |
|
|
536 |
* @private |
|
|
537 |
*/ |
|
|
538 |
_resyncMask: function (e) { |
|
|
539 |
var o = e.currentTarget, |
|
|
540 |
offsetX = o.get('docScrollX'), |
|
|
541 |
offsetY = o.get('docScrollY'), |
|
|
542 |
w = o.get('innerWidth') || o.get('winWidth'), |
|
|
543 |
h = o.get('innerHeight') || o.get('winHeight'), |
|
|
544 |
mask = this.get('maskNode'); |
|
|
545 |
|
|
|
546 |
mask.setStyles({ |
|
|
547 |
"top": offsetY + "px", |
|
|
548 |
"left": offsetX + "px", |
|
|
549 |
"width": w + 'px', |
|
|
550 |
"height": h + 'px' |
|
|
551 |
}); |
|
|
552 |
}, |
|
|
553 |
|
|
|
554 |
/** |
|
|
555 |
* Default function called when focusOn Attribute is changed. Remove existing listeners and create new listeners. |
|
|
556 |
* |
|
|
557 |
* @method _afterFocusOnChange |
|
|
558 |
*/ |
|
|
559 |
_afterFocusOnChange : function(e) { |
|
|
560 |
this._detachUIHandlesModal(); |
|
|
561 |
|
|
|
562 |
if (this.get(VISIBLE)) { |
|
|
563 |
this._attachUIHandlesModal(); |
|
|
564 |
} |
|
|
565 |
} |
|
|
566 |
}; |
|
|
567 |
|
|
|
568 |
Y.WidgetModality = WidgetModal; |
|
|
569 |
|
|
|
570 |
|
|
|
571 |
|
|
|
572 |
}, '3.10.3', {"requires": ["base-build", "event-outside", "widget"], "skinnable": true}); |