8dc7e0a89f1c857cf3ed668b7a50d8f61ba3f116
[ccsdk/features.git] /
1 /**
2  * Copyright 2010-2013 Ben Birch
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this software except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 (function( $, app ) {
17
18         var ui = app.ns("ui");
19
20         ui.AbstractPanel = ui.AbstractWidget.extend({
21                 defaults: {
22                         body: null,            // initial content of the body
23                         modal: true,           // create a modal panel - creates a div that blocks interaction with page
24                         height: 'auto',        // panel height
25                         width: 400,            // panel width (in pixels)
26                         open: false,           // show the panel when it is created
27                         parent: 'BODY',        // node that panel is attached to
28                         autoRemove: false      // remove the panel from the dom and destroy it when the widget is closed
29                 },
30                 shared: {  // shared data for all instances of ui.Panel and decendants
31                         stack: [], // array of all open panels
32                         modal: $( { tag: "DIV", id: "uiModal", css: { opacity: 0.2, position: "absolute", top: "0px", left: "0px" } } )
33                 },
34                 init: function() {
35                         this._super();
36                 },
37                 open: function( ev ) {
38                         this.el
39                                 .css( { visibility: "hidden" } )
40                                 .appendTo( this.config.parent )
41                                 .css( this._getPosition( ev ) )
42                                 .css( { zIndex: (this.shared.stack.length ? (+this.shared.stack[this.shared.stack.length - 1].el.css("zIndex") + 10) : 100) } )
43                                 .css( { visibility: "visible", display: "block" } );
44                         this.shared.stack.remove(this);
45                         this.shared.stack.push(this);
46                         this._setModal();
47                         $(document).bind("keyup", this._close_handler );
48                         this.fire("open", { source: this, event: ev } );
49                         return this;
50                 },
51                 close: function() {
52                         var index = this.shared.stack.indexOf(this);
53                         if(index !== -1) {
54                                 this.shared.stack.splice(index, 1);
55                                 this.el.css( { left: "-2999px" } ); // move the dialog to the left rather than hiding to prevent ie6 rendering artifacts
56                                 this._setModal();
57                                 this.fire("close", this );
58                                 if(this.config.autoRemove) {
59                                         this.remove();
60                                 }
61                         }
62                         return this;
63                 },
64                 // close the panel and remove it from the dom, destroying it (you can not reuse the panel after calling remove)
65                 remove: function() {
66                         this.close();
67                         $(document).unbind("keyup", this._close_handler );
68                         this._super();
69                 },
70                 // starting at the top of the stack, find the first panel that wants a modal and put it just underneath, otherwise remove the modal
71                 _setModal: function() {
72                         for(var stackPtr = this.shared.stack.length - 1; stackPtr >= 0; stackPtr--) {
73                                 if(this.shared.stack[stackPtr].config.modal) {
74                                         this.shared.modal
75                                                 .appendTo( document.body )
76                                                 .css( { zIndex: this.shared.stack[stackPtr].el.css("zIndex") - 5 } )
77                                                 .css( $(document).vSize().asSize() );
78                                         return;
79                                 }
80                         }
81                         this.shared.modal.remove(); // no panels that want a modal were found
82                 },
83                 _getPosition: function() {
84                         return $(window).vSize()                        // get the current viewport size
85                                 .sub(this.el.vSize())                         // subtract the size of the panel
86                                 .mod(function(s) { return s / 2; })           // divide by 2 (to center it)
87                                 .add($(document).vScroll())                   // add the current scroll offset
88                                 .mod(function(s) { return Math.max(5, s); })  // make sure the panel is not off the edge of the window
89                                 .asOffset();                                  // and return it as a {top, left} object
90                 },
91                 _close_handler: function( ev ) {
92                         if( ev.type === "keyup" && ev.keyCode !== 27) { return; } // press esc key to close
93                         $(document).unbind("keyup", this._close_handler);
94                         this.close( ev );
95                 }
96         });
97
98 })( this.jQuery, this.app );