83f87c5c5469734b64d207a490b45a4f0e84b394
[moodle.git] / lib / yui / src / dock / js / panel.js
1 /* global DOCKPANEL, LOGNS */
3 /**
4  * Dock JS.
5  *
6  * This file contains the panel class used by the dock to display the content of docked blocks.
7  *
8  * @module moodle-core-dock
9  */
11 /**
12  * Panel.
13  *
14  * @namespace M.core.dock
15  * @class Panel
16  * @constructor
17  * @extends Base
18  * @uses EventTarget
19  */
20 DOCKPANEL = function() {
21     DOCKPANEL.superclass.constructor.apply(this, arguments);
22 };
23 DOCKPANEL.prototype = {
24     /**
25      * True once the panel has been created.
26      * @property created
27      * @protected
28      * @type {Boolean}
29      */
30     created: false,
31     /**
32      * Called during the initialisation process of the object.
33      * @method initializer
34      */
35     initializer: function() {
36         Y.log('Panel initialising', 'debug', LOGNS);
37         /**
38          * Fired before the panel is shown.
39          * @event dockpane::beforeshow
40          */
41         this.publish('dockpanel:beforeshow', {prefix: 'dockpanel'});
42         /**
43          * Fired after the panel is shown.
44          * @event dockpanel:shown
45          */
46         this.publish('dockpanel:shown', {prefix: 'dockpanel'});
47         /**
48          * Fired before the panel is hidden.
49          * @event dockpane::beforehide
50          */
51         this.publish('dockpanel:beforehide', {prefix: 'dockpanel'});
52         /**
53          * Fired after the panel is hidden.
54          * @event dockpanel:hidden
55          */
56         this.publish('dockpanel:hidden', {prefix: 'dockpanel'});
57         /**
58          * Fired when ever the dock panel is either hidden or shown.
59          * Always fired after the shown or hidden events.
60          * @event dockpanel:visiblechange
61          */
62         this.publish('dockpanel:visiblechange', {prefix: 'dockpanel'});
63     },
64     /**
65      * Creates the Panel if it has not already been created.
66      * @method create
67      * @return {Boolean}
68      */
69     create: function() {
70         if (this.created) {
71             return true;
72         }
73         this.created = true;
74         var dock = this.get('dock'),
75             node = dock.get('dockNode');
76         this.set('node', Y.Node.create('<div id="dockeditempanel" class="dockitempanel_hidden"></div>'));
77         this.set('contentNode', Y.Node.create('<div class="dockeditempanel_content"></div>'));
78         this.set('headerNode', Y.Node.create('<div class="dockeditempanel_hd"></div>'));
79         this.set('bodyNode', Y.Node.create('<div class="dockeditempanel_bd"></div>'));
80         node.append(
81             this.get('node').append(this.get('contentNode').append(this.get('headerNode')).append(this.get('bodyNode')))
82         );
83     },
84     /**
85      * Displays the panel.
86      * @method show
87      */
88     show: function() {
89         this.create();
90         this.fire('dockpanel:beforeshow');
91         this.set('visible', true);
92         this.get('node').removeClass('dockitempanel_hidden');
93         this.fire('dockpanel:shown');
94         this.fire('dockpanel:visiblechange');
95     },
96     /**
97      * Hides the panel
98      * @method hide
99      */
100     hide: function() {
101         this.fire('dockpanel:beforehide');
102         this.set('visible', false);
103         this.get('node').addClass('dockitempanel_hidden');
104         this.fire('dockpanel:hidden');
105         this.fire('dockpanel:visiblechange');
106     },
107     /**
108      * Sets the panel header.
109      * @method setHeader
110      * @param {Node|String} content
111      */
112     setHeader: function(content) {
113         this.create();
114         var header = this.get('headerNode'),
115             i;
116         header.setContent(content);
117         if (arguments.length > 1) {
118             for (i = 1; i < arguments.length; i++) {
119                 if (Y.Lang.isNumber(i) || Y.Lang.isString(i)) {
120                     header.append(arguments[i]);
121                 }
122             }
123         }
124     },
125     /**
126      * Sets the panel body.
127      * @method setBody
128      * @param {Node|String} content
129      */
130     setBody: function(content) {
131         this.create();
132         this.get('bodyNode').setContent(content);
133     },
134     /**
135      * Sets the new top mark of the panel.
136      *
137      * @method setTop
138      * @param {Number} newtop
139      */
140     setTop: function(newtop) {
141         if (Y.UA.ie > 0 && Y.UA.ie < 7) {
142             this.get('node').setY(newtop);
143         } else {
144             this.get('node').setStyle('top', newtop.toString() + 'px');
145         }
146     },
147     /**
148      * Corrects the width of the panel.
149      * @method correctWidth
150      */
151     correctWidth: function() {
152         var bodyNode = this.get('bodyNode'),
153             // Width of content.
154             width = bodyNode.get('clientWidth'),
155             // Scrollable width of content.
156             scroll = bodyNode.get('scrollWidth'),
157             // Width of content container with overflow.
158             offsetWidth = bodyNode.get('offsetWidth'),
159             // The new width - defaults to the current width.
160             newWidth = width,
161             // The max width (80% of screen).
162             maxWidth = Math.round(bodyNode.get('winWidth') * 0.8);
164         // If the scrollable width is more than the visible width
165         if (scroll > width) {
166             //   Content width
167             // + the difference
168             // + any rendering difference (borders, padding)
169             // + 10px to make it look nice.
170             newWidth = width + (scroll - width) + ((offsetWidth - width) * 2) + 10;
171         }
173         // Make sure its not more then the maxwidth
174         if (newWidth > maxWidth) {
175             newWidth = maxWidth;
176         }
178         // Set the new width if its more than the old width.
179         if (newWidth > offsetWidth) {
180             this.get('node').setStyle('width', newWidth + 'px');
181         }
182     }
183 };
184 Y.extend(DOCKPANEL, Y.Base, DOCKPANEL.prototype, {
185     NAME: 'moodle-core-dock-panel',
186     ATTRS: {
187         /**
188          * The dock itself.
189          * @attribute dock
190          * @type DOCK
191          * @writeonce
192          */
193         dock: {
194             writeOnce: 'initOnly'
195         },
196         /**
197          * The node that contains the whole panel.
198          * @attribute node
199          * @type Node
200          */
201         node: {
202             value: null
203         },
204         /**
205          * The node that contains the header, body and footer.
206          * @attribute contentNode
207          * @type Node
208          */
209         contentNode: {
210             value: null
211         },
212         /**
213          * The node that contains the header
214          * @attribute headerNode
215          * @type Node
216          */
217         headerNode: {
218             value: null
219         },
220         /**
221          * The node that contains the body
222          * @attribute bodyNode
223          * @type Node
224          */
225         bodyNode: {
226             value: null
227         },
228         /**
229          * True if the panel is currently visible.
230          * @attribute visible
231          * @type Boolean
232          */
233         visible: {
234             value: false
235         }
236     }
237 });
238 Y.augment(DOCKPANEL, Y.EventTarget);