1 // ========================================================================== 2 // Project: SproutCore - JavaScript Application Framework 3 // Copyright: ©2006-2011 Strobe Inc. and contributors. 4 // Portions ©2008-2011 Apple Inc. All rights reserved. 5 // License: Licensed under MIT license (see license.js) 6 // ========================================================================== 7 8 9 /** @class 10 11 A modal pane is used to capture mouse events inside a pane that is modal. 12 You normally will not work with modal panes directly, though you may set 13 the modalPane property to a subclass of this pane when designing custom 14 panes. 15 16 A modal pane is automatically appended when a pane with isModal set to 17 `YES` is made visible and removed when the same pane is hidden. The only 18 purpose of the `ModalPane` is to absorb mouse events so that they cannot 19 filter through to the underlying content. 20 21 @extends SC.Pane 22 @since SproutCore 1.0 23 */ 24 SC.ModalPane = SC.Pane.extend( 25 /** @scope SC.ModalPane.prototype */{ 26 27 /** 28 @type Array 29 @default ['sc-modal'] 30 @see SC.View#classNames 31 */ 32 classNames: 'sc-modal', 33 34 /** @private */ 35 _openPaneCount: 0, 36 37 /** @private 38 Called by a pane just before it appends itself. The modal pane can 39 make itself visible first if needed. 40 41 @param {SC.Pane} pane the pane 42 @returns {SC.ModalPane} receiver 43 */ 44 paneWillAppend: function(pane) { 45 var _tmpPane; 46 this._openPaneCount++; 47 if (!this.get('isVisibleInWindow')) this.append(); 48 var panes = SC.RootResponder.responder.panes; 49 for(var i=0, iLen=panes.length; i<iLen; i++ ){ 50 _tmpPane = panes[i]; 51 if(_tmpPane!==pane) { 52 //_tmpPane.set('ariaHidden', YES); 53 this._hideShowTextfields(_tmpPane, NO); 54 } 55 } 56 return this ; 57 }, 58 59 /** @private 60 Called by a pane just after it removes itself. The modal pane can remove 61 itself if needed. Modal panes only remove themselves when an equal 62 number of `paneWillAppend()` and `paneDidRemove()` calls are received. 63 64 @param {SC.Pane} pane the pane 65 @returns {SC.ModalPane} receiver 66 */ 67 paneDidRemove: function(pane) { 68 var _tmpPane; 69 this._openPaneCount--; 70 var panes = SC.RootResponder.responder.panes; 71 for(var i=0, iLen=panes.length; i<iLen; i++ ){ 72 _tmpPane = panes[i]; 73 if(_tmpPane!==pane) { 74 //_tmpPane.set('ariaHidden', NO); 75 this._hideShowTextfields(_tmpPane, YES); 76 } 77 } 78 if (this._openPaneCount <= 0) { 79 this._openPaneCount = 0 ; 80 if (this.get('isVisibleInWindow')) this.remove(); 81 } 82 }, 83 84 /** @private 85 If `focusable` is NO all SC.TextFieldViews not belonging to the given 86 pane will have isBrowserFocusable set to NO. If `focusable` is YES, then 87 all SC.TextFieldViews not belonging to the given pane will have 88 isBrowserFocusable set to YES, unless they previously had it set explictly 89 to NO. 90 */ 91 _hideShowTextfields: function(pane, focusable){ 92 var view; 93 94 for (view in SC.View.views) { 95 view = SC.View.views[view]; 96 if (view.get('isTextField') && view !== pane && view.get('pane') === pane) { 97 if (focusable) { 98 // Setting isBrowserFocusable back to YES. If we cached the previous 99 // value, use that instead. 100 if (view._scmp_isBrowserFocusable !== undefined) { 101 focusable = view._scmp_isBrowserFocusable; 102 103 // Clean up entirely. 104 delete view._scmp_isBrowserFocusable; 105 } 106 } else { 107 // Cache the value of isBrowserFocusable. If the text field 108 // already had isBrowserFocusable: NO, we don't want to 109 // set it back to YES. 110 view._scmp_isBrowserFocusable = view.get('isBrowserFocusable'); 111 } 112 view.set('isBrowserFocusable', focusable); 113 } 114 } 115 }, 116 117 /** @private */ 118 mouseDown: function(evt) { 119 var owner = this.get('owner'); 120 if (owner && owner.modalPaneDidClick) owner.modalPaneDidClick(evt); 121 }, 122 123 /** @private */ 124 touchStart: function(evt) { 125 this.mouseDown(evt); 126 } 127 }); 128