3 Copyright 2012 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
7 if (typeof _yuitest_coverage == "undefined"){
8 _yuitest_coverage = {};
9 _yuitest_coverline = function(src, line){
10 var coverage = _yuitest_coverage[src];
11 if (!coverage.lines[line]){
12 coverage.calledLines++;
14 coverage.lines[line]++;
16 _yuitest_coverfunc = function(src, name, line){
17 var coverage = _yuitest_coverage[src],
18 funcId = name + ":" + line;
19 if (!coverage.functions[funcId]){
20 coverage.calledFunctions++;
22 coverage.functions[funcId]++;
25 _yuitest_coverage["build/widget-modality/widget-modality.js"] = {
32 path: "build/widget-modality/widget-modality.js",
35 _yuitest_coverage["build/widget-modality/widget-modality.js"].code=["YUI.add('widget-modality', function (Y, NAME) {","","/**"," * Provides modality support for Widgets, though an extension"," *"," * @module widget-modality"," */","","var WIDGET = 'widget',"," RENDER_UI = 'renderUI',"," BIND_UI = 'bindUI',"," SYNC_UI = 'syncUI',"," BOUNDING_BOX = 'boundingBox',"," CONTENT_BOX = 'contentBox',"," VISIBLE = 'visible',"," Z_INDEX = 'zIndex',"," CHANGE = 'Change',"," isBoolean = Y.Lang.isBoolean,"," getCN = Y.ClassNameManager.getClassName,"," MaskShow = \"maskShow\","," MaskHide = \"maskHide\","," ClickOutside = \"clickoutside\","," FocusOutside = \"focusoutside\",",""," supportsPosFixed = (function(){",""," /*! IS_POSITION_FIXED_SUPPORTED - Juriy Zaytsev (kangax) - http://yura.thinkweb2.com/cft/ */",""," var doc = Y.config.doc,"," isSupported = null,"," el, root;",""," if (doc.createElement) {"," el = doc.createElement('div');"," if (el && el.style) {"," el.style.position = 'fixed';"," el.style.top = '10px';"," root = doc.body;"," if (root && root.appendChild && root.removeChild) {"," root.appendChild(el);"," isSupported = (el.offsetTop === 10);"," root.removeChild(el);"," }"," }"," }",""," return isSupported;"," }());",""," /**"," * Widget extension, which can be used to add modality support to the base Widget class,"," * through the Base.create method."," *"," * @class WidgetModality"," * @param {Object} config User configuration object"," */"," function WidgetModal(config) {}",""," var MODAL = 'modal',"," MASK = 'mask',"," MODAL_CLASSES = {"," modal : getCN(WIDGET, MODAL),"," mask : getCN(WIDGET, MASK)"," };",""," /**"," * Static property used to define the default attribute"," * configuration introduced by WidgetModality."," *"," * @property ATTRS"," * @static"," * @type Object"," */"," WidgetModal.ATTRS = {"," /**"," * @attribute maskNode"," * @type Y.Node"," *"," * @description Returns a Y.Node instance of the node being used as the mask."," */"," maskNode : {"," getter : '_getMaskNode',"," readOnly : true"," },","",""," /**"," * @attribute modal"," * @type boolean"," *"," * @description Whether the widget should be modal or not."," */"," modal: {"," value:false,"," validator: isBoolean"," },",""," /**"," * @attribute focusOn"," * @type array"," *"," * @description An array of objects corresponding to the nodes and events that will trigger a re-focus back on the widget."," * The implementer can supply an array of objects, with each object having the following properties:"," * <p>eventName: (string, required): The eventName to listen to.</p>"," * <p>node: (Y.Node, optional): The Y.Node that will fire the event (defaults to the boundingBox of the widget)</p>"," * <p>By default, this attribute consists of two objects which will cause the widget to re-focus if anything"," * outside the widget is clicked on or focussed upon.</p>"," */"," focusOn: {"," valueFn: function() {"," return ["," {"," // node: this.get(BOUNDING_BOX),"," eventName: ClickOutside"," },"," {"," //node: this.get(BOUNDING_BOX),"," eventName: FocusOutside"," }"," ];"," },",""," validator: Y.Lang.isArray"," }",""," };","",""," WidgetModal.CLASSES = MODAL_CLASSES;","",""," /**"," * Returns the mask if it exists on the page - otherwise creates a mask. There's only"," * one mask on a page at a given time."," * <p>"," * This method in invoked internally by the getter of the maskNode ATTR."," * </p>"," * @method _GET_MASK"," * @static"," */"," WidgetModal._GET_MASK = function() {",""," var mask = Y.one('.' + MODAL_CLASSES.mask),"," win = Y.one('win');",""," if (mask) {"," return mask;"," }",""," mask = Y.Node.create('<div></div>').addClass(MODAL_CLASSES.mask);",""," if (supportsPosFixed) {"," mask.setStyles({"," position: 'fixed',"," width : '100%',"," height : '100%',"," top : '0',"," left : '0',"," display : 'block'"," });"," } else {"," mask.setStyles({"," position: 'absolute',"," width : win.get('winWidth') +'px',"," height : win.get('winHeight') + 'px',"," top : '0',"," left : '0',"," display : 'block'"," });"," }",""," return mask;"," };",""," /**"," * A stack of Y.Widget objects representing the current hierarchy of modal widgets presently displayed on the screen"," * @property STACK"," */"," WidgetModal.STACK = [];","",""," WidgetModal.prototype = {",""," initializer: function () {"," Y.after(this._renderUIModal, this, RENDER_UI);"," Y.after(this._syncUIModal, this, SYNC_UI);"," Y.after(this._bindUIModal, this, BIND_UI);"," },",""," destructor: function () {"," // Hack to remove this thing from the STACK."," this._uiSetHostVisibleModal(false);"," },",""," // *** Instance Members *** //",""," _uiHandlesModal: null,","",""," /**"," * Adds modal class to the bounding box of the widget"," * <p>"," * This method in invoked after renderUI is invoked for the Widget class"," * using YUI's aop infrastructure."," * </p>"," * @method _renderUIModal"," * @protected"," */"," _renderUIModal : function () {",""," var bb = this.get(BOUNDING_BOX);"," //cb = this.get(CONTENT_BOX);",""," //this makes the content box content appear over the mask"," // cb.setStyles({"," // position: \"\""," // });",""," this._repositionMask(this);"," bb.addClass(MODAL_CLASSES.modal);",""," },","",""," /**"," * Hooks up methods to be executed when the widget's visibility or z-index changes"," * <p>"," * This method in invoked after bindUI is invoked for the Widget class"," * using YUI's aop infrastructure."," * </p>"," * @method _bindUIModal"," * @protected"," */"," _bindUIModal : function () {",""," this.after(VISIBLE+CHANGE, this._afterHostVisibleChangeModal);"," this.after(Z_INDEX+CHANGE, this._afterHostZIndexChangeModal);"," this.after(\"focusOnChange\", this._afterFocusOnChange);",""," // Re-align the mask in the viewport if `position: fixed;` is not"," // supported. iOS < 5 and Android < 3 don't actually support it even"," // though they both pass the feature test; the UA sniff is here to"," // account for that. Ideally this should be replaced with a better"," // feature test."," if (!supportsPosFixed ||"," (Y.UA.ios && Y.UA.ios < 5) ||"," (Y.UA.android && Y.UA.android < 3)) {",""," Y.one('win').on('scroll', this._resyncMask, this);"," }"," },",""," /**"," * Syncs the mask with the widget's current state, namely the visibility and z-index of the widget"," * <p>"," * This method in invoked after syncUI is invoked for the Widget class"," * using YUI's aop infrastructure."," * </p>"," * @method _syncUIModal"," * @protected"," */"," _syncUIModal : function () {",""," //var host = this.get(HOST);",""," this._uiSetHostVisibleModal(this.get(VISIBLE));"," this._uiSetHostZIndexModal(this.get(Z_INDEX));",""," },",""," /**"," * Provides mouse and tab focus to the widget's bounding box."," *"," * @method _focus"," */"," _focus : function (e) {",""," var bb = this.get(BOUNDING_BOX),"," oldTI = bb.get('tabIndex');",""," bb.set('tabIndex', oldTI >= 0 ? oldTI : 0);"," this.focus();"," },"," /**"," * Blurs the widget."," *"," * @method _blur"," */"," _blur : function () {",""," this.blur();"," },",""," /**"," * Returns the Y.Node instance of the maskNode"," *"," * @method _getMaskNode"," * @return {Node} The Y.Node instance of the mask, as returned from WidgetModal._GET_MASK"," */"," _getMaskNode : function () {",""," return WidgetModal._GET_MASK();"," },",""," /**"," * Performs events attaching/detaching, stack shifting and mask repositioning based on the visibility of the widget"," *"," * @method _uiSetHostVisibleModal"," * @param {boolean} Whether the widget is visible or not"," */"," _uiSetHostVisibleModal : function (visible) {"," var stack = WidgetModal.STACK,"," maskNode = this.get('maskNode'),"," isModal = this.get('modal'),"," topModal, index;",""," if (visible) {",""," Y.Array.each(stack, function(modal){"," modal._detachUIHandlesModal();"," modal._blur();"," });",""," // push on top of stack"," stack.unshift(this);",""," this._repositionMask(this);"," this._uiSetHostZIndexModal(this.get(Z_INDEX));",""," if (isModal) {"," maskNode.show();"," Y.later(1, this, '_attachUIHandlesModal');"," this._focus();"," }","",""," } else {",""," index = Y.Array.indexOf(stack, this);"," if (index >= 0) {"," // Remove modal widget from global stack."," stack.splice(index, 1);"," }",""," this._detachUIHandlesModal();"," this._blur();",""," if (stack.length) {"," topModal = stack[0];"," this._repositionMask(topModal);"," //topModal._attachUIHandlesModal();"," topModal._uiSetHostZIndexModal(topModal.get(Z_INDEX));",""," if (topModal.get('modal')) {"," //topModal._attachUIHandlesModal();"," Y.later(1, topModal, '_attachUIHandlesModal');"," topModal._focus();"," }",""," } else {",""," if (maskNode.getStyle('display') === 'block') {"," maskNode.hide();"," }",""," }",""," }"," },",""," /**"," * Sets the z-index of the mask node."," *"," * @method _uiSetHostZIndexModal"," * @param {Number} Z-Index of the widget"," */"," _uiSetHostZIndexModal : function (zIndex) {",""," if (this.get('modal')) {"," this.get('maskNode').setStyle(Z_INDEX, zIndex || 0);"," }",""," },",""," /**"," * Attaches UI Listeners for \"clickoutside\" and \"focusoutside\" on the"," * widget. When these events occur, and the widget is modal, focus is"," * shifted back onto the widget."," *"," * @method _attachUIHandlesModal"," */"," _attachUIHandlesModal : function () {",""," if (this._uiHandlesModal || WidgetModal.STACK[0] !== this) {"," // Quit early if we have ui handles, or if we not at the top"," // of the global stack."," return;"," }",""," var bb = this.get(BOUNDING_BOX),"," maskNode = this.get('maskNode'),"," focusOn = this.get('focusOn'),"," focus = Y.bind(this._focus, this),"," uiHandles = [],"," i, len, o;",""," for (i = 0, len = focusOn.length; i < len; i++) {",""," o = {};"," o.node = focusOn[i].node;"," o.ev = focusOn[i].eventName;"," o.keyCode = focusOn[i].keyCode;",""," //no keycode or node defined"," if (!o.node && !o.keyCode && o.ev) {"," uiHandles.push(bb.on(o.ev, focus));"," }",""," //node defined, no keycode (not a keypress)"," else if (o.node && !o.keyCode && o.ev) {"," uiHandles.push(o.node.on(o.ev, focus));"," }",""," //node defined, keycode defined, event defined (its a key press)"," else if (o.node && o.keyCode && o.ev) {"," uiHandles.push(o.node.on(o.ev, focus, o.keyCode));"," }",""," else {"," Y.Log('focusOn ATTR Error: The event with name \"'+o.ev+'\" could not be attached.');"," }",""," }",""," if ( ! supportsPosFixed) {"," uiHandles.push(Y.one('win').on('scroll', Y.bind(function(e){"," maskNode.setStyle('top', maskNode.get('docScrollY'));"," }, this)));"," }",""," this._uiHandlesModal = uiHandles;"," },",""," /**"," * Detaches all UI Listeners that were set in _attachUIHandlesModal from the widget."," *"," * @method _detachUIHandlesModal"," */"," _detachUIHandlesModal : function () {"," Y.each(this._uiHandlesModal, function(h){"," h.detach();"," });"," this._uiHandlesModal = null;"," },",""," /**"," * Default function that is called when visibility is changed on the widget."," *"," * @method _afterHostVisibleChangeModal"," * @param {EventFacade} e The event facade of the change"," */"," _afterHostVisibleChangeModal : function (e) {",""," this._uiSetHostVisibleModal(e.newVal);"," },",""," /**"," * Default function that is called when z-index is changed on the widget."," *"," * @method _afterHostZIndexChangeModal"," * @param {EventFacade} e The event facade of the change"," */"," _afterHostZIndexChangeModal : function (e) {",""," this._uiSetHostZIndexModal(e.newVal);"," },",""," /**"," * Returns a boolean representing whether the current widget is in a \"nested modality\" state."," * This is done by checking the number of widgets currently on the stack."," *"," * @method isNested"," * @public"," */"," isNested: function() {"," var length = WidgetModal.STACK.length,"," retval = (length > 1) ? true : false;"," return retval;"," },",""," /**"," * Repositions the mask in the DOM for nested modality cases."," *"," * @method _repositionMask"," * @param {Widget} nextElem The Y.Widget instance that will be visible in the stack once the current widget is closed."," */"," _repositionMask: function(nextElem) {",""," var currentModal = this.get('modal'),"," nextModal = nextElem.get('modal'),"," maskNode = this.get('maskNode'),"," bb, bbParent;",""," //if this is modal and host is not modal"," if (currentModal && !nextModal) {"," //leave the mask where it is, since the host is not modal."," maskNode.remove();"," this.fire(MaskHide);"," }",""," //if the main widget is not modal but the host is modal, or both of them are modal"," else if ((!currentModal && nextModal) || (currentModal && nextModal)) {",""," //then remove the mask off DOM, reposition it, and reinsert it into the DOM"," maskNode.remove();"," this.fire(MaskHide);"," bb = nextElem.get(BOUNDING_BOX);"," bbParent = bb.get('parentNode') || Y.one('body');"," bbParent.insert(maskNode, bbParent.get('firstChild'));"," this.fire(MaskShow);"," }",""," },",""," /**"," * Resyncs the mask in the viewport for browsers that don't support fixed positioning"," *"," * @method _resyncMask"," * @param {Y.Widget} nextElem The Y.Widget instance that will be visible in the stack once the current widget is closed."," * @private"," */"," _resyncMask: function (e) {"," var o = e.currentTarget,"," offsetX = o.get('docScrollX'),"," offsetY = o.get('docScrollY'),"," w = o.get('innerWidth') || o.get('winWidth'),"," h = o.get('innerHeight') || o.get('winHeight'),"," mask = this.get('maskNode');",""," mask.setStyles({"," \"top\": offsetY + \"px\","," \"left\": offsetX + \"px\","," \"width\": w + 'px',"," \"height\": h + 'px'"," });"," },",""," /**"," * Default function called when focusOn Attribute is changed. Remove existing listeners and create new listeners."," *"," * @method _afterFocusOnChange"," */"," _afterFocusOnChange : function(e) {"," this._detachUIHandlesModal();",""," if (this.get(VISIBLE)) {"," this._attachUIHandlesModal();"," }"," }"," };",""," Y.WidgetModality = WidgetModal;","","","","}, '3.7.2', {\"requires\": [\"base-build\", \"event-outside\", \"widget\"], \"skinnable\": true});"];
36 _yuitest_coverage["build/widget-modality/widget-modality.js"].lines = {"1":0,"9":0,"29":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"47":0,"57":0,"59":0,"74":0,"111":0,"129":0,"141":0,"143":0,"146":0,"147":0,"150":0,"152":0,"153":0,"162":0,"172":0,"179":0,"182":0,"185":0,"186":0,"187":0,"192":0,"211":0,"219":0,"220":0,"236":0,"237":0,"238":0,"245":0,"249":0,"266":0,"267":0,"278":0,"281":0,"282":0,"291":0,"302":0,"312":0,"317":0,"319":0,"320":0,"321":0,"325":0,"327":0,"328":0,"330":0,"331":0,"332":0,"333":0,"339":0,"340":0,"342":0,"345":0,"346":0,"348":0,"349":0,"350":0,"352":0,"354":0,"356":0,"357":0,"362":0,"363":0,"379":0,"380":0,"394":0,"397":0,"400":0,"407":0,"409":0,"410":0,"411":0,"412":0,"415":0,"416":0,"420":0,"421":0,"425":0,"426":0,"430":0,"435":0,"436":0,"437":0,"441":0,"450":0,"451":0,"453":0,"464":0,"475":0,"486":0,"488":0,"499":0,"505":0,"507":0,"508":0,"512":0,"515":0,"516":0,"517":0,"518":0,"519":0,"520":0,"533":0,"540":0,"554":0,"556":0,"557":0,"562":0};
37 _yuitest_coverage["build/widget-modality/widget-modality.js"].functions = {"(anonymous 2):25":0,"WidgetModal:57":0,"valueFn:110":0,"_GET_MASK:141":0,"initializer:184":0,"destructor:190":0,"_renderUIModal:209":0,"_bindUIModal:234":0,"_syncUIModal:262":0,"_focus:276":0,"_blur:289":0,"_getMaskNode:300":0,"(anonymous 3):319":0,"_uiSetHostVisibleModal:311":0,"_uiSetHostZIndexModal:377":0,"(anonymous 4):436":0,"_attachUIHandlesModal:392":0,"(anonymous 5):450":0,"_detachUIHandlesModal:449":0,"_afterHostVisibleChangeModal:462":0,"_afterHostZIndexChangeModal:473":0,"isNested:485":0,"_repositionMask:497":0,"_resyncMask:532":0,"_afterFocusOnChange:553":0,"(anonymous 1):1":0};
38 _yuitest_coverage["build/widget-modality/widget-modality.js"].coveredLines = 120;
39 _yuitest_coverage["build/widget-modality/widget-modality.js"].coveredFunctions = 26;
40 _yuitest_coverline("build/widget-modality/widget-modality.js", 1);
41 YUI.add('widget-modality', function (Y, NAME) {
44 * Provides modality support for Widgets, though an extension
46 * @module widget-modality
49 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "(anonymous 1)", 1);
50 _yuitest_coverline("build/widget-modality/widget-modality.js", 9);
51 var WIDGET = 'widget',
52 RENDER_UI = 'renderUI',
55 BOUNDING_BOX = 'boundingBox',
56 CONTENT_BOX = 'contentBox',
60 isBoolean = Y.Lang.isBoolean,
61 getCN = Y.ClassNameManager.getClassName,
62 MaskShow = "maskShow",
63 MaskHide = "maskHide",
64 ClickOutside = "clickoutside",
65 FocusOutside = "focusoutside",
67 supportsPosFixed = (function(){
69 /*! IS_POSITION_FIXED_SUPPORTED - Juriy Zaytsev (kangax) - http://yura.thinkweb2.com/cft/ */
71 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "(anonymous 2)", 25);
72 _yuitest_coverline("build/widget-modality/widget-modality.js", 29);
73 var doc = Y.config.doc,
77 _yuitest_coverline("build/widget-modality/widget-modality.js", 33);
78 if (doc.createElement) {
79 _yuitest_coverline("build/widget-modality/widget-modality.js", 34);
80 el = doc.createElement('div');
81 _yuitest_coverline("build/widget-modality/widget-modality.js", 35);
83 _yuitest_coverline("build/widget-modality/widget-modality.js", 36);
84 el.style.position = 'fixed';
85 _yuitest_coverline("build/widget-modality/widget-modality.js", 37);
86 el.style.top = '10px';
87 _yuitest_coverline("build/widget-modality/widget-modality.js", 38);
89 _yuitest_coverline("build/widget-modality/widget-modality.js", 39);
90 if (root && root.appendChild && root.removeChild) {
91 _yuitest_coverline("build/widget-modality/widget-modality.js", 40);
93 _yuitest_coverline("build/widget-modality/widget-modality.js", 41);
94 isSupported = (el.offsetTop === 10);
95 _yuitest_coverline("build/widget-modality/widget-modality.js", 42);
101 _yuitest_coverline("build/widget-modality/widget-modality.js", 47);
106 * Widget extension, which can be used to add modality support to the base Widget class,
107 * through the Base.create method.
109 * @class WidgetModality
110 * @param {Object} config User configuration object
112 _yuitest_coverline("build/widget-modality/widget-modality.js", 57);
113 function WidgetModal(config) {}
115 _yuitest_coverline("build/widget-modality/widget-modality.js", 59);
119 modal : getCN(WIDGET, MODAL),
120 mask : getCN(WIDGET, MASK)
124 * Static property used to define the default attribute
125 * configuration introduced by WidgetModality.
131 _yuitest_coverline("build/widget-modality/widget-modality.js", 74);
132 WidgetModal.ATTRS = {
134 * @attribute maskNode
137 * @description Returns a Y.Node instance of the node being used as the mask.
140 getter : '_getMaskNode',
149 * @description Whether the widget should be modal or not.
160 * @description An array of objects corresponding to the nodes and events that will trigger a re-focus back on the widget.
161 * The implementer can supply an array of objects, with each object having the following properties:
162 * <p>eventName: (string, required): The eventName to listen to.</p>
163 * <p>node: (Y.Node, optional): The Y.Node that will fire the event (defaults to the boundingBox of the widget)</p>
164 * <p>By default, this attribute consists of two objects which will cause the widget to re-focus if anything
165 * outside the widget is clicked on or focussed upon.</p>
168 valueFn: function() {
169 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "valueFn", 110);
170 _yuitest_coverline("build/widget-modality/widget-modality.js", 111);
173 // node: this.get(BOUNDING_BOX),
174 eventName: ClickOutside
177 //node: this.get(BOUNDING_BOX),
178 eventName: FocusOutside
183 validator: Y.Lang.isArray
189 _yuitest_coverline("build/widget-modality/widget-modality.js", 129);
190 WidgetModal.CLASSES = MODAL_CLASSES;
194 * Returns the mask if it exists on the page - otherwise creates a mask. There's only
195 * one mask on a page at a given time.
197 * This method in invoked internally by the getter of the maskNode ATTR.
202 _yuitest_coverline("build/widget-modality/widget-modality.js", 141);
203 WidgetModal._GET_MASK = function() {
205 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "_GET_MASK", 141);
206 _yuitest_coverline("build/widget-modality/widget-modality.js", 143);
207 var mask = Y.one('.' + MODAL_CLASSES.mask),
210 _yuitest_coverline("build/widget-modality/widget-modality.js", 146);
212 _yuitest_coverline("build/widget-modality/widget-modality.js", 147);
216 _yuitest_coverline("build/widget-modality/widget-modality.js", 150);
217 mask = Y.Node.create('<div></div>').addClass(MODAL_CLASSES.mask);
219 _yuitest_coverline("build/widget-modality/widget-modality.js", 152);
220 if (supportsPosFixed) {
221 _yuitest_coverline("build/widget-modality/widget-modality.js", 153);
231 _yuitest_coverline("build/widget-modality/widget-modality.js", 162);
233 position: 'absolute',
234 width : win.get('winWidth') +'px',
235 height : win.get('winHeight') + 'px',
242 _yuitest_coverline("build/widget-modality/widget-modality.js", 172);
247 * A stack of Y.Widget objects representing the current hierarchy of modal widgets presently displayed on the screen
250 _yuitest_coverline("build/widget-modality/widget-modality.js", 179);
251 WidgetModal.STACK = [];
254 _yuitest_coverline("build/widget-modality/widget-modality.js", 182);
255 WidgetModal.prototype = {
257 initializer: function () {
258 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "initializer", 184);
259 _yuitest_coverline("build/widget-modality/widget-modality.js", 185);
260 Y.after(this._renderUIModal, this, RENDER_UI);
261 _yuitest_coverline("build/widget-modality/widget-modality.js", 186);
262 Y.after(this._syncUIModal, this, SYNC_UI);
263 _yuitest_coverline("build/widget-modality/widget-modality.js", 187);
264 Y.after(this._bindUIModal, this, BIND_UI);
267 destructor: function () {
268 // Hack to remove this thing from the STACK.
269 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "destructor", 190);
270 _yuitest_coverline("build/widget-modality/widget-modality.js", 192);
271 this._uiSetHostVisibleModal(false);
274 // *** Instance Members *** //
276 _uiHandlesModal: null,
280 * Adds modal class to the bounding box of the widget
282 * This method in invoked after renderUI is invoked for the Widget class
283 * using YUI's aop infrastructure.
285 * @method _renderUIModal
288 _renderUIModal : function () {
290 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "_renderUIModal", 209);
291 _yuitest_coverline("build/widget-modality/widget-modality.js", 211);
292 var bb = this.get(BOUNDING_BOX);
293 //cb = this.get(CONTENT_BOX);
295 //this makes the content box content appear over the mask
300 _yuitest_coverline("build/widget-modality/widget-modality.js", 219);
301 this._repositionMask(this);
302 _yuitest_coverline("build/widget-modality/widget-modality.js", 220);
303 bb.addClass(MODAL_CLASSES.modal);
309 * Hooks up methods to be executed when the widget's visibility or z-index changes
311 * This method in invoked after bindUI is invoked for the Widget class
312 * using YUI's aop infrastructure.
314 * @method _bindUIModal
317 _bindUIModal : function () {
319 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "_bindUIModal", 234);
320 _yuitest_coverline("build/widget-modality/widget-modality.js", 236);
321 this.after(VISIBLE+CHANGE, this._afterHostVisibleChangeModal);
322 _yuitest_coverline("build/widget-modality/widget-modality.js", 237);
323 this.after(Z_INDEX+CHANGE, this._afterHostZIndexChangeModal);
324 _yuitest_coverline("build/widget-modality/widget-modality.js", 238);
325 this.after("focusOnChange", this._afterFocusOnChange);
327 // Re-align the mask in the viewport if `position: fixed;` is not
328 // supported. iOS < 5 and Android < 3 don't actually support it even
329 // though they both pass the feature test; the UA sniff is here to
330 // account for that. Ideally this should be replaced with a better
332 _yuitest_coverline("build/widget-modality/widget-modality.js", 245);
333 if (!supportsPosFixed ||
334 (Y.UA.ios && Y.UA.ios < 5) ||
335 (Y.UA.android && Y.UA.android < 3)) {
337 _yuitest_coverline("build/widget-modality/widget-modality.js", 249);
338 Y.one('win').on('scroll', this._resyncMask, this);
343 * Syncs the mask with the widget's current state, namely the visibility and z-index of the widget
345 * This method in invoked after syncUI is invoked for the Widget class
346 * using YUI's aop infrastructure.
348 * @method _syncUIModal
351 _syncUIModal : function () {
353 //var host = this.get(HOST);
355 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "_syncUIModal", 262);
356 _yuitest_coverline("build/widget-modality/widget-modality.js", 266);
357 this._uiSetHostVisibleModal(this.get(VISIBLE));
358 _yuitest_coverline("build/widget-modality/widget-modality.js", 267);
359 this._uiSetHostZIndexModal(this.get(Z_INDEX));
364 * Provides mouse and tab focus to the widget's bounding box.
368 _focus : function (e) {
370 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "_focus", 276);
371 _yuitest_coverline("build/widget-modality/widget-modality.js", 278);
372 var bb = this.get(BOUNDING_BOX),
373 oldTI = bb.get('tabIndex');
375 _yuitest_coverline("build/widget-modality/widget-modality.js", 281);
376 bb.set('tabIndex', oldTI >= 0 ? oldTI : 0);
377 _yuitest_coverline("build/widget-modality/widget-modality.js", 282);
385 _blur : function () {
387 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "_blur", 289);
388 _yuitest_coverline("build/widget-modality/widget-modality.js", 291);
393 * Returns the Y.Node instance of the maskNode
395 * @method _getMaskNode
396 * @return {Node} The Y.Node instance of the mask, as returned from WidgetModal._GET_MASK
398 _getMaskNode : function () {
400 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "_getMaskNode", 300);
401 _yuitest_coverline("build/widget-modality/widget-modality.js", 302);
402 return WidgetModal._GET_MASK();
406 * Performs events attaching/detaching, stack shifting and mask repositioning based on the visibility of the widget
408 * @method _uiSetHostVisibleModal
409 * @param {boolean} Whether the widget is visible or not
411 _uiSetHostVisibleModal : function (visible) {
412 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "_uiSetHostVisibleModal", 311);
413 _yuitest_coverline("build/widget-modality/widget-modality.js", 312);
414 var stack = WidgetModal.STACK,
415 maskNode = this.get('maskNode'),
416 isModal = this.get('modal'),
419 _yuitest_coverline("build/widget-modality/widget-modality.js", 317);
422 _yuitest_coverline("build/widget-modality/widget-modality.js", 319);
423 Y.Array.each(stack, function(modal){
424 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "(anonymous 3)", 319);
425 _yuitest_coverline("build/widget-modality/widget-modality.js", 320);
426 modal._detachUIHandlesModal();
427 _yuitest_coverline("build/widget-modality/widget-modality.js", 321);
431 // push on top of stack
432 _yuitest_coverline("build/widget-modality/widget-modality.js", 325);
435 _yuitest_coverline("build/widget-modality/widget-modality.js", 327);
436 this._repositionMask(this);
437 _yuitest_coverline("build/widget-modality/widget-modality.js", 328);
438 this._uiSetHostZIndexModal(this.get(Z_INDEX));
440 _yuitest_coverline("build/widget-modality/widget-modality.js", 330);
442 _yuitest_coverline("build/widget-modality/widget-modality.js", 331);
444 _yuitest_coverline("build/widget-modality/widget-modality.js", 332);
445 Y.later(1, this, '_attachUIHandlesModal');
446 _yuitest_coverline("build/widget-modality/widget-modality.js", 333);
453 _yuitest_coverline("build/widget-modality/widget-modality.js", 339);
454 index = Y.Array.indexOf(stack, this);
455 _yuitest_coverline("build/widget-modality/widget-modality.js", 340);
457 // Remove modal widget from global stack.
458 _yuitest_coverline("build/widget-modality/widget-modality.js", 342);
459 stack.splice(index, 1);
462 _yuitest_coverline("build/widget-modality/widget-modality.js", 345);
463 this._detachUIHandlesModal();
464 _yuitest_coverline("build/widget-modality/widget-modality.js", 346);
467 _yuitest_coverline("build/widget-modality/widget-modality.js", 348);
469 _yuitest_coverline("build/widget-modality/widget-modality.js", 349);
471 _yuitest_coverline("build/widget-modality/widget-modality.js", 350);
472 this._repositionMask(topModal);
473 //topModal._attachUIHandlesModal();
474 _yuitest_coverline("build/widget-modality/widget-modality.js", 352);
475 topModal._uiSetHostZIndexModal(topModal.get(Z_INDEX));
477 _yuitest_coverline("build/widget-modality/widget-modality.js", 354);
478 if (topModal.get('modal')) {
479 //topModal._attachUIHandlesModal();
480 _yuitest_coverline("build/widget-modality/widget-modality.js", 356);
481 Y.later(1, topModal, '_attachUIHandlesModal');
482 _yuitest_coverline("build/widget-modality/widget-modality.js", 357);
488 _yuitest_coverline("build/widget-modality/widget-modality.js", 362);
489 if (maskNode.getStyle('display') === 'block') {
490 _yuitest_coverline("build/widget-modality/widget-modality.js", 363);
500 * Sets the z-index of the mask node.
502 * @method _uiSetHostZIndexModal
503 * @param {Number} Z-Index of the widget
505 _uiSetHostZIndexModal : function (zIndex) {
507 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "_uiSetHostZIndexModal", 377);
508 _yuitest_coverline("build/widget-modality/widget-modality.js", 379);
509 if (this.get('modal')) {
510 _yuitest_coverline("build/widget-modality/widget-modality.js", 380);
511 this.get('maskNode').setStyle(Z_INDEX, zIndex || 0);
517 * Attaches UI Listeners for "clickoutside" and "focusoutside" on the
518 * widget. When these events occur, and the widget is modal, focus is
519 * shifted back onto the widget.
521 * @method _attachUIHandlesModal
523 _attachUIHandlesModal : function () {
525 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "_attachUIHandlesModal", 392);
526 _yuitest_coverline("build/widget-modality/widget-modality.js", 394);
527 if (this._uiHandlesModal || WidgetModal.STACK[0] !== this) {
528 // Quit early if we have ui handles, or if we not at the top
529 // of the global stack.
530 _yuitest_coverline("build/widget-modality/widget-modality.js", 397);
534 _yuitest_coverline("build/widget-modality/widget-modality.js", 400);
535 var bb = this.get(BOUNDING_BOX),
536 maskNode = this.get('maskNode'),
537 focusOn = this.get('focusOn'),
538 focus = Y.bind(this._focus, this),
542 _yuitest_coverline("build/widget-modality/widget-modality.js", 407);
543 for (i = 0, len = focusOn.length; i < len; i++) {
545 _yuitest_coverline("build/widget-modality/widget-modality.js", 409);
547 _yuitest_coverline("build/widget-modality/widget-modality.js", 410);
548 o.node = focusOn[i].node;
549 _yuitest_coverline("build/widget-modality/widget-modality.js", 411);
550 o.ev = focusOn[i].eventName;
551 _yuitest_coverline("build/widget-modality/widget-modality.js", 412);
552 o.keyCode = focusOn[i].keyCode;
554 //no keycode or node defined
555 _yuitest_coverline("build/widget-modality/widget-modality.js", 415);
556 if (!o.node && !o.keyCode && o.ev) {
557 _yuitest_coverline("build/widget-modality/widget-modality.js", 416);
558 uiHandles.push(bb.on(o.ev, focus));
561 //node defined, no keycode (not a keypress)
562 else {_yuitest_coverline("build/widget-modality/widget-modality.js", 420);
563 if (o.node && !o.keyCode && o.ev) {
564 _yuitest_coverline("build/widget-modality/widget-modality.js", 421);
565 uiHandles.push(o.node.on(o.ev, focus));
568 //node defined, keycode defined, event defined (its a key press)
569 else {_yuitest_coverline("build/widget-modality/widget-modality.js", 425);
570 if (o.node && o.keyCode && o.ev) {
571 _yuitest_coverline("build/widget-modality/widget-modality.js", 426);
572 uiHandles.push(o.node.on(o.ev, focus, o.keyCode));
576 _yuitest_coverline("build/widget-modality/widget-modality.js", 430);
577 Y.Log('focusOn ATTR Error: The event with name "'+o.ev+'" could not be attached.');
582 _yuitest_coverline("build/widget-modality/widget-modality.js", 435);
583 if ( ! supportsPosFixed) {
584 _yuitest_coverline("build/widget-modality/widget-modality.js", 436);
585 uiHandles.push(Y.one('win').on('scroll', Y.bind(function(e){
586 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "(anonymous 4)", 436);
587 _yuitest_coverline("build/widget-modality/widget-modality.js", 437);
588 maskNode.setStyle('top', maskNode.get('docScrollY'));
592 _yuitest_coverline("build/widget-modality/widget-modality.js", 441);
593 this._uiHandlesModal = uiHandles;
597 * Detaches all UI Listeners that were set in _attachUIHandlesModal from the widget.
599 * @method _detachUIHandlesModal
601 _detachUIHandlesModal : function () {
602 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "_detachUIHandlesModal", 449);
603 _yuitest_coverline("build/widget-modality/widget-modality.js", 450);
604 Y.each(this._uiHandlesModal, function(h){
605 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "(anonymous 5)", 450);
606 _yuitest_coverline("build/widget-modality/widget-modality.js", 451);
609 _yuitest_coverline("build/widget-modality/widget-modality.js", 453);
610 this._uiHandlesModal = null;
614 * Default function that is called when visibility is changed on the widget.
616 * @method _afterHostVisibleChangeModal
617 * @param {EventFacade} e The event facade of the change
619 _afterHostVisibleChangeModal : function (e) {
621 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "_afterHostVisibleChangeModal", 462);
622 _yuitest_coverline("build/widget-modality/widget-modality.js", 464);
623 this._uiSetHostVisibleModal(e.newVal);
627 * Default function that is called when z-index is changed on the widget.
629 * @method _afterHostZIndexChangeModal
630 * @param {EventFacade} e The event facade of the change
632 _afterHostZIndexChangeModal : function (e) {
634 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "_afterHostZIndexChangeModal", 473);
635 _yuitest_coverline("build/widget-modality/widget-modality.js", 475);
636 this._uiSetHostZIndexModal(e.newVal);
640 * Returns a boolean representing whether the current widget is in a "nested modality" state.
641 * This is done by checking the number of widgets currently on the stack.
646 isNested: function() {
647 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "isNested", 485);
648 _yuitest_coverline("build/widget-modality/widget-modality.js", 486);
649 var length = WidgetModal.STACK.length,
650 retval = (length > 1) ? true : false;
651 _yuitest_coverline("build/widget-modality/widget-modality.js", 488);
656 * Repositions the mask in the DOM for nested modality cases.
658 * @method _repositionMask
659 * @param {Widget} nextElem The Y.Widget instance that will be visible in the stack once the current widget is closed.
661 _repositionMask: function(nextElem) {
663 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "_repositionMask", 497);
664 _yuitest_coverline("build/widget-modality/widget-modality.js", 499);
665 var currentModal = this.get('modal'),
666 nextModal = nextElem.get('modal'),
667 maskNode = this.get('maskNode'),
670 //if this is modal and host is not modal
671 _yuitest_coverline("build/widget-modality/widget-modality.js", 505);
672 if (currentModal && !nextModal) {
673 //leave the mask where it is, since the host is not modal.
674 _yuitest_coverline("build/widget-modality/widget-modality.js", 507);
676 _yuitest_coverline("build/widget-modality/widget-modality.js", 508);
680 //if the main widget is not modal but the host is modal, or both of them are modal
681 else {_yuitest_coverline("build/widget-modality/widget-modality.js", 512);
682 if ((!currentModal && nextModal) || (currentModal && nextModal)) {
684 //then remove the mask off DOM, reposition it, and reinsert it into the DOM
685 _yuitest_coverline("build/widget-modality/widget-modality.js", 515);
687 _yuitest_coverline("build/widget-modality/widget-modality.js", 516);
689 _yuitest_coverline("build/widget-modality/widget-modality.js", 517);
690 bb = nextElem.get(BOUNDING_BOX);
691 _yuitest_coverline("build/widget-modality/widget-modality.js", 518);
692 bbParent = bb.get('parentNode') || Y.one('body');
693 _yuitest_coverline("build/widget-modality/widget-modality.js", 519);
694 bbParent.insert(maskNode, bbParent.get('firstChild'));
695 _yuitest_coverline("build/widget-modality/widget-modality.js", 520);
702 * Resyncs the mask in the viewport for browsers that don't support fixed positioning
704 * @method _resyncMask
705 * @param {Y.Widget} nextElem The Y.Widget instance that will be visible in the stack once the current widget is closed.
708 _resyncMask: function (e) {
709 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "_resyncMask", 532);
710 _yuitest_coverline("build/widget-modality/widget-modality.js", 533);
711 var o = e.currentTarget,
712 offsetX = o.get('docScrollX'),
713 offsetY = o.get('docScrollY'),
714 w = o.get('innerWidth') || o.get('winWidth'),
715 h = o.get('innerHeight') || o.get('winHeight'),
716 mask = this.get('maskNode');
718 _yuitest_coverline("build/widget-modality/widget-modality.js", 540);
720 "top": offsetY + "px",
721 "left": offsetX + "px",
728 * Default function called when focusOn Attribute is changed. Remove existing listeners and create new listeners.
730 * @method _afterFocusOnChange
732 _afterFocusOnChange : function(e) {
733 _yuitest_coverfunc("build/widget-modality/widget-modality.js", "_afterFocusOnChange", 553);
734 _yuitest_coverline("build/widget-modality/widget-modality.js", 554);
735 this._detachUIHandlesModal();
737 _yuitest_coverline("build/widget-modality/widget-modality.js", 556);
738 if (this.get(VISIBLE)) {
739 _yuitest_coverline("build/widget-modality/widget-modality.js", 557);
740 this._attachUIHandlesModal();
745 _yuitest_coverline("build/widget-modality/widget-modality.js", 562);
746 Y.WidgetModality = WidgetModal;
750 }, '3.7.2', {"requires": ["base-build", "event-outside", "widget"], "skinnable": true});