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 sc_require('panes/modal'); 9 10 /** @class 11 12 Most SproutCore applications need modal panels. The default way to use the 13 panel pane is to simply add it to your page like this: 14 15 SC.PanelPane.create({ 16 layout: { width: 400, height: 200, centerX: 0, centerY: 0 }, 17 contentView: SC.View.extend({ 18 }) 19 }).append(); 20 21 This will cause your panel to display. The default layout for a Panel 22 is to cover the entire document window with a semi-opaque background, and to 23 resize with the window. 24 25 @extends SC.Pane 26 @author Erich Ocean 27 @since SproutCore 1.0 28 */ 29 SC.PanelPane = SC.Pane.extend( 30 /** @scope SC.PanelPane.prototype */ { 31 32 /** 33 Walk like a duck. 34 @type {Boolean} 35 */ 36 isPanelPane: YES, 37 38 /** 39 @type Array 40 @default ['sc-panel'] 41 @see SC.View#classNames 42 */ 43 classNames: ['sc-panel'], 44 45 /** 46 @type Boolean 47 @default YES 48 @see SC.Pane#acceptsKeyPane 49 */ 50 acceptsKeyPane: YES, 51 52 /** 53 The WAI-ARIA role for panel pane. 54 55 @type String 56 @default 'dialog' 57 @constant 58 */ 59 ariaRole: 'dialog', 60 61 /** 62 The WAI-ARIA label for the panel. Screen readers will use this to tell 63 the user a name for the panel. 64 65 @type String 66 */ 67 ariaLabel: null, 68 69 /** 70 The WAI-ARIA labelledby for the panel. Screen readers will use this to tell 71 the header or name of your panel if there is no label. This should be an id 72 to an element inside the panel. 73 74 @type String 75 */ 76 ariaLabelledBy: null, 77 78 /** 79 The WAI-ARIA describedby text. Screen readers will use this to speak the description 80 of the panel. This should be an id to an element inside the panel. 81 82 @type String 83 */ 84 ariaDescribedBy: null, 85 86 /** 87 Indicates that a pane is modal and should not allow clicks to pass 88 though to panes underneath it. This will usually cause the pane to show 89 the modalPane underneath it. 90 91 @type Boolean 92 @default YES 93 */ 94 isModal: YES, 95 96 /** 97 The modal pane to place behind this pane if this pane is modal. This 98 must be a subclass or an instance of SC.ModalPane. 99 */ 100 modalPane: SC.ModalPane.extend({ 101 classNames: 'for-sc-panel' 102 }), 103 104 // .......................................................... 105 // CONTENT VIEW 106 // 107 108 /** 109 Set this to the view you want to act as the content within the panel. 110 111 @type SC.View 112 @default null 113 */ 114 contentView: null, 115 contentViewBindingDefault: SC.Binding.single(), 116 117 /** 118 @param {SC.View} newContent 119 */ 120 replaceContent: function(newContent) { 121 this.removeAllChildren() ; 122 if (newContent) this.appendChild(newContent); 123 }, 124 125 /** @private */ 126 createChildViews: function() { 127 // if contentView is defined, then create the content 128 var view = this.contentView ; 129 if (view) { 130 view = this.contentView = this.createChildView(view) ; 131 this.childViews = [view] ; 132 } 133 }, 134 135 136 /** 137 Invoked whenever the content property changes. This method will simply 138 call replaceContent. Override replaceContent to change how the view is 139 swapped out. 140 */ 141 contentViewDidChange: function() { 142 this.replaceContent(this.get('contentView')); 143 }.observes('contentView'), 144 145 // .......................................................... 146 // INTERNAL SUPPORT 147 // 148 149 /** 150 The name of the theme's `SC.PanelPane` render delegate. 151 152 @type String 153 @default 'panelRenderDelegate' 154 */ 155 renderDelegateName: 'panelRenderDelegate', 156 157 // get the modal pane. 158 _modalPane: function() { 159 var pane = this.get('modalPane'); 160 161 // instantiate if needed 162 if (pane && pane.isClass) { 163 pane = pane.create({ owner: this }); 164 this.set('modalPane', pane); 165 } 166 167 return pane ; 168 }, 169 170 /** @private - whenever showing on screen, deal with modal pane as well */ 171 appendTo: function(elem) { 172 var pane ; 173 if (!this.get('isVisibleInWindow') && this.get('isModal') && (pane = this._modalPane())) { 174 this._isShowingModal = YES; 175 pane.paneWillAppend(this); 176 } 177 return sc_super(); 178 }, 179 180 /** @private - when removing from screen, deal with modal pane as well. */ 181 remove: function() { 182 var pane, ret = sc_super(); 183 184 if (this._isShowingModal) { 185 this._isShowingModal = NO ; 186 if (pane = this._modalPane()) pane.paneDidRemove(this); 187 } 188 return ret ; 189 }, 190 191 destroy: function() { 192 var modal = this.get('modalPane'); 193 if (modal && !modal.isClass) { 194 modal.destroy(); 195 } 196 197 sc_super(); 198 }, 199 200 /** @private - if isModal state changes, update pane state if needed. */ 201 _isModalDidChange: function() { 202 var modalPane, 203 isModal = this.get('isModal'); 204 205 if (isModal) { 206 if (!this._isShowingModal && (modalPane = this._modalPane())) { 207 this._isShowingModal = YES; 208 modalPane.paneWillAppend(this); 209 } 210 } else { 211 if (this._isShowingModal && (modalPane = this._modalPane())) { 212 this._isShowingModal = NO; 213 modalPane.paneDidRemove(this); 214 } 215 } 216 }.observes('isModal'), 217 218 /** 219 Called when the pane is shown. Takes on key pane status. 220 */ 221 didShowInDocument: function () { 222 this.becomeKeyPane(); 223 }, 224 225 /** 226 Called when the pane is attached. Takes on key pane status. 227 */ 228 didAppendToDocument: function () { 229 this.becomeKeyPane(); 230 }, 231 232 /** 233 Called when the pane is detached. Resigns key pane status. 234 */ 235 willRemoveFromDocument: function () { 236 this.resignKeyPane(); 237 }, 238 239 /** 240 Called when the pane is about to be hidden. Resigns key pane status. 241 */ 242 willHideInDocument: function () { 243 this.resignKeyPane(); 244 }, 245 246 displayProperties: ['ariaLabel', 'ariaLabelledBy', 'ariaDescribedBy'] 247 248 }); 249