Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / src / layout / component / AbstractDock.js
1 /*
2
3 This file is part of Ext JS 4
4
5 Copyright (c) 2011 Sencha Inc
6
7 Contact:  http://www.sencha.com/contact
8
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.  Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
11
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
13
14 */
15 /**
16  * @class Ext.layout.component.AbstractDock
17  * @extends Ext.layout.component.Component
18  * @private
19  * This ComponentLayout handles docking for Panels. It takes care of panels that are
20  * part of a ContainerLayout that sets this Panel's size and Panels that are part of
21  * an AutoContainerLayout in which this panel get his height based of the CSS or
22  * or its content.
23  */
24
25 Ext.define('Ext.layout.component.AbstractDock', {
26
27     /* Begin Definitions */
28
29     extend: 'Ext.layout.component.Component',
30
31     /* End Definitions */
32
33     type: 'dock',
34
35     /**
36      * @private
37      * @property autoSizing
38      * @type Boolean
39      * This flag is set to indicate this layout may have an autoHeight/autoWidth.
40      */
41     autoSizing: true,
42
43     beforeLayout: function() {
44         var returnValue = this.callParent(arguments);
45         if (returnValue !== false && (!this.initializedBorders || this.childrenChanged) && (!this.owner.border || this.owner.manageBodyBorders)) {
46             this.handleItemBorders();
47             this.initializedBorders = true;
48         }
49         return returnValue;
50     },
51     
52     handleItemBorders: function() {
53         var owner = this.owner,
54             body = owner.body,
55             docked = this.getLayoutItems(),
56             borders = {
57                 top: [],
58                 right: [],
59                 bottom: [],
60                 left: []
61             },
62             oldBorders = this.borders,
63             opposites = {
64                 top: 'bottom',
65                 right: 'left',
66                 bottom: 'top',
67                 left: 'right'
68             },
69             i, ln, item, dock, side;
70
71         for (i = 0, ln = docked.length; i < ln; i++) {
72             item = docked[i];
73             dock = item.dock;
74             
75             if (item.ignoreBorderManagement) {
76                 continue;
77             }
78             
79             if (!borders[dock].satisfied) {
80                 borders[dock].push(item);
81                 borders[dock].satisfied = true;
82             }
83             
84             if (!borders.top.satisfied && opposites[dock] !== 'top') {
85                 borders.top.push(item);
86             }
87             if (!borders.right.satisfied && opposites[dock] !== 'right') {
88                 borders.right.push(item);
89             }            
90             if (!borders.bottom.satisfied && opposites[dock] !== 'bottom') {
91                 borders.bottom.push(item);
92             }            
93             if (!borders.left.satisfied && opposites[dock] !== 'left') {
94                 borders.left.push(item);
95             }
96         }
97
98         if (oldBorders) {
99             for (side in oldBorders) {
100                 if (oldBorders.hasOwnProperty(side)) {
101                     ln = oldBorders[side].length;
102                     if (!owner.manageBodyBorders) {
103                         for (i = 0; i < ln; i++) {
104                             oldBorders[side][i].removeCls(Ext.baseCSSPrefix + 'docked-noborder-' + side);
105                         }
106                         if (!oldBorders[side].satisfied && !owner.bodyBorder) {
107                             body.removeCls(Ext.baseCSSPrefix + 'docked-noborder-' + side);                   
108                         }                    
109                     }
110                     else if (oldBorders[side].satisfied) {
111                         body.setStyle('border-' + side + '-width', '');
112                     }
113                 }
114             }
115         }
116                 
117         for (side in borders) {
118             if (borders.hasOwnProperty(side)) {
119                 ln = borders[side].length;
120                 if (!owner.manageBodyBorders) {
121                     for (i = 0; i < ln; i++) {
122                         borders[side][i].addCls(Ext.baseCSSPrefix + 'docked-noborder-' + side);
123                     }
124                     if ((!borders[side].satisfied && !owner.bodyBorder) || owner.bodyBorder === false) {
125                         body.addCls(Ext.baseCSSPrefix + 'docked-noborder-' + side);                   
126                     }                    
127                 }
128                 else if (borders[side].satisfied) {
129                     body.setStyle('border-' + side + '-width', '1px');
130                 }
131             }
132         }
133         
134         this.borders = borders;
135     },
136     
137     /**
138      * @protected
139      * @param {Ext.Component} owner The Panel that owns this DockLayout
140      * @param {Ext.Element} target The target in which we are going to render the docked items
141      * @param {Array} args The arguments passed to the ComponentLayout.layout method
142      */
143     onLayout: function(width, height) {
144         if (this.onLayout_running) {
145             return;
146         }
147         this.onLayout_running = true;
148         var me = this,
149             owner = me.owner,
150             body = owner.body,
151             layout = owner.layout,
152             target = me.getTarget(),
153             autoWidth = false,
154             autoHeight = false,
155             padding, border, frameSize;
156
157         // We start of by resetting all the layouts info
158         var info = me.info = {
159             boxes: [],
160             size: {
161                 width: width,
162                 height: height
163             },
164             bodyBox: {}
165         };
166         // Clear isAutoDock flag
167         delete layout.isAutoDock;
168
169         Ext.applyIf(info, me.getTargetInfo());
170
171         // We need to bind to the ownerCt whenever we do not have a user set height or width.
172         if (owner && owner.ownerCt && owner.ownerCt.layout && owner.ownerCt.layout.isLayout) {
173             if (!Ext.isNumber(owner.height) || !Ext.isNumber(owner.width)) {
174                 owner.ownerCt.layout.bindToOwnerCtComponent = true;
175             }
176             else {
177                 owner.ownerCt.layout.bindToOwnerCtComponent = false;
178             }
179         }
180
181         // Determine if we have an autoHeight or autoWidth.
182         if (height == null || width == null) {
183             padding = info.padding;
184             border = info.border;
185             frameSize = me.frameSize;
186
187             // Auto-everything, clear out any style height/width and read from css
188             if ((height == null) && (width == null)) {
189                 autoHeight = true;
190                 autoWidth = true;
191                 me.setTargetSize(null);
192                 me.setBodyBox({width: null, height: null});
193             }
194             // Auto-height
195             else if (height == null) {
196                 autoHeight = true;
197                 // Clear any sizing that we already set in a previous layout
198                 me.setTargetSize(width);
199                 me.setBodyBox({width: width - padding.left - border.left - padding.right - border.right - frameSize.left - frameSize.right, height: null});
200             // Auto-width
201             }
202             else {
203                 autoWidth = true;
204                 // Clear any sizing that we already set in a previous layout
205                 me.setTargetSize(null, height);
206                 me.setBodyBox({width: null, height: height - padding.top - padding.bottom - border.top - border.bottom - frameSize.top - frameSize.bottom});
207             }
208
209             // Run the container
210             if (layout && layout.isLayout) {
211                 // Auto-Sized so have the container layout notify the component layout.
212                 layout.bindToOwnerCtComponent = true;
213                 // Set flag so we don't do a redundant container layout
214                 layout.isAutoDock = layout.autoSize !== true;
215                 layout.layout();
216
217                 // If this is an autosized container layout, then we must compensate for a
218                 // body that is being autosized.  We do not want to adjust the body's size
219                 // to accommodate the dock items, but rather we will want to adjust the
220                 // target's size.
221                 //
222                 // This is necessary because, particularly in a Box layout, all child items
223                 // are set with absolute dimensions that are not flexible to the size of its
224                 // innerCt/target.  So once they are laid out, they are sized for good. By
225                 // shrinking the body box to accommodate dock items, we're merely cutting off
226                 // parts of the body.  Not good.  Instead, the target's size should expand
227                 // to fit the dock items in.  This is valid because the target container is
228                 // suppose to be autosized to fit everything accordingly.
229                 info.autoSizedCtLayout = layout.autoSize === true;
230                 info.autoHeight = autoHeight;
231                 info.autoWidth = autoWidth;
232             }
233
234             // The dockItems method will add all the top and bottom docked items height
235             // to the info.panelSize height. That's why we have to call setSize after
236             // we dock all the items to actually set the panel's width and height.
237             // We have to do this because the panel body and docked items will be position
238             // absolute which doesn't stretch the panel.
239             me.dockItems();
240             me.setTargetSize(info.size.width, info.size.height);
241         }
242         else {
243             me.setTargetSize(width, height);
244             me.dockItems();
245         }
246         me.callParent(arguments);
247         this.onLayout_running = false;
248     },
249
250     /**
251      * @protected
252      * This method will first update all the information about the docked items,
253      * body dimensions and position, the panel's total size. It will then
254      * set all these values on the docked items and panel body.
255      * @param {Array} items Array containing all the docked items
256      * @param {Boolean} autoBoxes Set this to true if the Panel is part of an
257      * AutoContainerLayout
258      */
259     dockItems : function() {
260         this.calculateDockBoxes();
261
262         // Both calculateAutoBoxes and calculateSizedBoxes are changing the
263         // information about the body, panel size, and boxes for docked items
264         // inside a property called info.
265         var info = this.info,
266             autoWidth = info.autoWidth,
267             autoHeight = info.autoHeight,
268             boxes = info.boxes,
269             ln = boxes.length,
270             dock, i, item;
271
272         // We are going to loop over all the boxes that were calculated
273         // and set the position of each item the box belongs to.
274         for (i = 0; i < ln; i++) {
275             dock = boxes[i];
276             item = dock.item;
277             item.setPosition(dock.x, dock.y);
278             if ((autoWidth || autoHeight) && item.layout && item.layout.isLayout) {
279                 // Auto-Sized so have the container layout notify the component layout.
280                 item.layout.bindToOwnerCtComponent = true;
281             }
282         }
283
284         // Don't adjust body width/height if the target is using an auto container layout.
285         // But, we do want to adjust the body size if the container layout is auto sized.
286         if (!info.autoSizedCtLayout) {
287             if (autoWidth) {
288                 info.bodyBox.width = null;
289             }
290             if (autoHeight) {
291                 info.bodyBox.height = null;
292             }
293         }
294
295         // If the bodyBox has been adjusted because of the docked items
296         // we will update the dimensions and position of the panel's body.
297         this.setBodyBox(info.bodyBox);
298     },
299
300     /**
301      * @protected
302      * This method will set up some initial information about the panel size and bodybox
303      * and then loop over all the items you pass it to take care of stretching, aligning,
304      * dock position and all calculations involved with adjusting the body box.
305      * @param {Array} items Array containing all the docked items we have to layout
306      */
307     calculateDockBoxes : function() {
308         if (this.calculateDockBoxes_running) {
309             // [AbstractDock#calculateDockBoxes] attempted to run again while it was already running
310             return;
311         }
312         this.calculateDockBoxes_running = true;
313         // We want to use the Panel's el width, and the Panel's body height as the initial
314         // size we are going to use in calculateDockBoxes. We also want to account for
315         // the border of the panel.
316         var me = this,
317             target = me.getTarget(),
318             items = me.getLayoutItems(),
319             owner = me.owner,
320             bodyEl = owner.body,
321             info = me.info,
322             autoWidth = info.autoWidth,
323             autoHeight = info.autoHeight,
324             size = info.size,
325             ln = items.length,
326             padding = info.padding,
327             border = info.border,
328             frameSize = me.frameSize,
329             item, i, box, rect;
330
331         // If this Panel is inside an AutoContainerLayout, we will base all the calculations
332         // around the height of the body and the width of the panel.
333         if (autoHeight) {
334             size.height = bodyEl.getHeight() + padding.top + border.top + padding.bottom + border.bottom + frameSize.top + frameSize.bottom;
335         }
336         else {
337             size.height = target.getHeight();
338         }
339         if (autoWidth) {
340             size.width = bodyEl.getWidth() + padding.left + border.left + padding.right + border.right + frameSize.left + frameSize.right;
341         }
342         else {
343             size.width = target.getWidth();
344         }
345
346         info.bodyBox = {
347             x: padding.left + frameSize.left,
348             y: padding.top + frameSize.top,
349             width: size.width - padding.left - border.left - padding.right - border.right - frameSize.left - frameSize.right,
350             height: size.height - border.top - padding.top - border.bottom - padding.bottom - frameSize.top - frameSize.bottom
351         };
352
353         // Loop over all the docked items
354         for (i = 0; i < ln; i++) {
355             item = items[i];
356             // The initBox method will take care of stretching and alignment
357             // In some cases it will also layout the dock items to be able to
358             // get a width or height measurement
359             box = me.initBox(item);
360
361             if (autoHeight === true) {
362                 box = me.adjustAutoBox(box, i);
363             }
364             else {
365                 box = me.adjustSizedBox(box, i);
366             }
367
368             // Save our box. This allows us to loop over all docked items and do all
369             // calculations first. Then in one loop we will actually size and position
370             // all the docked items that have changed.
371             info.boxes.push(box);
372         }
373         this.calculateDockBoxes_running = false;
374     },
375
376     /**
377      * @protected
378      * This method will adjust the position of the docked item and adjust the body box
379      * accordingly.
380      * @param {Object} box The box containing information about the width and height
381      * of this docked item
382      * @param {Number} index The index position of this docked item
383      * @return {Object} The adjusted box
384      */
385     adjustSizedBox : function(box, index) {
386         var bodyBox = this.info.bodyBox,
387             frameSize = this.frameSize,
388             info = this.info,
389             padding = info.padding,
390             pos = box.type,
391             border = info.border;
392
393         switch (pos) {
394             case 'top':
395                 box.y = bodyBox.y;
396                 break;
397
398             case 'left':
399                 box.x = bodyBox.x;
400                 break;
401
402             case 'bottom':
403                 box.y = (bodyBox.y + bodyBox.height) - box.height;
404                 break;
405
406             case 'right':
407                 box.x = (bodyBox.x + bodyBox.width) - box.width;
408                 break;
409         }
410
411         if (box.ignoreFrame) {
412             if (pos == 'bottom') {
413                 box.y += (frameSize.bottom + padding.bottom + border.bottom);
414             }
415             else {
416                 box.y -= (frameSize.top + padding.top + border.top);
417             }
418             if (pos == 'right') {
419                 box.x += (frameSize.right + padding.right + border.right);
420             }
421             else {
422                 box.x -= (frameSize.left + padding.left + border.left);
423             }
424         }
425
426         // If this is not an overlaying docked item, we have to adjust the body box
427         if (!box.overlay) {
428             switch (pos) {
429                 case 'top':
430                     bodyBox.y += box.height;
431                     bodyBox.height -= box.height;
432                     break;
433
434                 case 'left':
435                     bodyBox.x += box.width;
436                     bodyBox.width -= box.width;
437                     break;
438
439                 case 'bottom':
440                     bodyBox.height -= box.height;
441                     break;
442
443                 case 'right':
444                     bodyBox.width -= box.width;
445                     break;
446             }
447         }
448         return box;
449     },
450
451     /**
452      * @protected
453      * This method will adjust the position of the docked item inside an AutoContainerLayout
454      * and adjust the body box accordingly.
455      * @param {Object} box The box containing information about the width and height
456      * of this docked item
457      * @param {Number} index The index position of this docked item
458      * @return {Object} The adjusted box
459      */
460     adjustAutoBox : function (box, index) {
461         var info = this.info,
462             owner = this.owner,
463             bodyBox = info.bodyBox,
464             size = info.size,
465             boxes = info.boxes,
466             boxesLn = boxes.length,
467             pos = box.type,
468             frameSize = this.frameSize,
469             padding = info.padding,
470             border = info.border,
471             autoSizedCtLayout = info.autoSizedCtLayout,
472             ln = (boxesLn < index) ? boxesLn : index,
473             i, adjustBox;
474
475         if (pos == 'top' || pos == 'bottom') {
476             // This can affect the previously set left and right and bottom docked items
477             for (i = 0; i < ln; i++) {
478                 adjustBox = boxes[i];
479                 if (adjustBox.stretched && adjustBox.type == 'left' || adjustBox.type == 'right') {
480                     adjustBox.height += box.height;
481                 }
482                 else if (adjustBox.type == 'bottom') {
483                     adjustBox.y += box.height;
484                 }
485             }
486         }
487
488         switch (pos) {
489             case 'top':
490                 box.y = bodyBox.y;
491                 if (!box.overlay) {
492                     bodyBox.y += box.height;
493                     if (info.autoHeight) {
494                         size.height += box.height;
495                     } else {
496                         bodyBox.height -= box.height;
497                     }
498                 }
499                 break;
500
501             case 'bottom':
502                 if (!box.overlay) {
503                     if (info.autoHeight) {
504                         size.height += box.height;
505                     } else {
506                         bodyBox.height -= box.height;
507                     }
508                 }
509                 box.y = (bodyBox.y + bodyBox.height);
510                 break;
511
512             case 'left':
513                 box.x = bodyBox.x;
514                 if (!box.overlay) {
515                     bodyBox.x += box.width;
516                     if (info.autoWidth) {
517                         size.width += box.width;
518                     } else {
519                         bodyBox.width -= box.width;
520                     }
521                 }
522                 break;
523
524             case 'right':
525                 if (!box.overlay) {
526                     if (info.autoWidth) {
527                         size.width += box.width;
528                     } else {
529                         bodyBox.width -= box.width;
530                     }
531                 }
532                 box.x = (bodyBox.x + bodyBox.width);
533                 break;
534         }
535
536         if (box.ignoreFrame) {
537             if (pos == 'bottom') {
538                 box.y += (frameSize.bottom + padding.bottom + border.bottom);
539             }
540             else {
541                 box.y -= (frameSize.top + padding.top + border.top);
542             }
543             if (pos == 'right') {
544                 box.x += (frameSize.right + padding.right + border.right);
545             }
546             else {
547                 box.x -= (frameSize.left + padding.left + border.left);
548             }
549         }
550         return box;
551     },
552
553     /**
554      * @protected
555      * This method will create a box object, with a reference to the item, the type of dock
556      * (top, left, bottom, right). It will also take care of stretching and aligning of the
557      * docked items.
558      * @param {Ext.Component} item The docked item we want to initialize the box for
559      * @return {Object} The initial box containing width and height and other useful information
560      */
561     initBox : function(item) {
562         var me = this,
563             bodyBox = me.info.bodyBox,
564             horizontal = (item.dock == 'top' || item.dock == 'bottom'),
565             owner = me.owner,
566             frameSize = me.frameSize,
567             info = me.info,
568             padding = info.padding,
569             border = info.border,
570             box = {
571                 item: item,
572                 overlay: item.overlay,
573                 type: item.dock,
574                 offsets: Ext.Element.parseBox(item.offsets || {}),
575                 ignoreFrame: item.ignoreParentFrame
576             };
577         // First we are going to take care of stretch and align properties for all four dock scenarios.
578         if (item.stretch !== false) {
579             box.stretched = true;
580             if (horizontal) {
581                 box.x = bodyBox.x + box.offsets.left;
582                 box.width = bodyBox.width - (box.offsets.left + box.offsets.right);
583                 if (box.ignoreFrame) {
584                     box.width += (frameSize.left + frameSize.right + border.left + border.right + padding.left + padding.right);
585                 }
586                 item.setCalculatedSize(box.width - item.el.getMargin('lr'), undefined, owner);
587             }
588             else {
589                 box.y = bodyBox.y + box.offsets.top;
590                 box.height = bodyBox.height - (box.offsets.bottom + box.offsets.top);
591                 if (box.ignoreFrame) {
592                     box.height += (frameSize.top + frameSize.bottom + border.top + border.bottom + padding.top + padding.bottom);
593                 }
594                 item.setCalculatedSize(undefined, box.height - item.el.getMargin('tb'), owner);
595
596                 // At this point IE will report the left/right-docked toolbar as having a width equal to the
597                 // container's full width. Forcing a repaint kicks it into shape so it reports the correct width.
598                 if (!Ext.supports.ComputedStyle) {
599                     item.el.repaint();
600                 }
601             }
602         }
603         else {
604             item.doComponentLayout();
605             box.width = item.getWidth() - (box.offsets.left + box.offsets.right);
606             box.height = item.getHeight() - (box.offsets.bottom + box.offsets.top);
607             box.y += box.offsets.top;
608             if (horizontal) {
609                 box.x = (item.align == 'right') ? bodyBox.width - box.width : bodyBox.x;
610                 box.x += box.offsets.left;
611             }
612         }
613
614         // If we haven't calculated the width or height of the docked item yet
615         // do so, since we need this for our upcoming calculations
616         if (box.width === undefined) {
617             box.width = item.getWidth() + item.el.getMargin('lr');
618         }
619         if (box.height === undefined) {
620             box.height = item.getHeight() + item.el.getMargin('tb');
621         }
622
623         return box;
624     },
625
626     /**
627      * @protected
628      * Returns an array containing all the <b>visible</b> docked items inside this layout's owner Panel
629      * @return {Array} An array containing all the <b>visible</b> docked items of the Panel
630      */
631     getLayoutItems : function() {
632         var it = this.owner.getDockedItems(),
633             ln = it.length,
634             i = 0,
635             result = [];
636         for (; i < ln; i++) {
637             if (it[i].isVisible(true)) {
638                 result.push(it[i]);
639             }
640         }
641         return result;
642     },
643
644     /**
645      * @protected
646      * Render the top and left docked items before any existing DOM nodes in our render target,
647      * and then render the right and bottom docked items after. This is important, for such things
648      * as tab stops and ARIA readers, that the DOM nodes are in a meaningful order.
649      * Our collection of docked items will already be ordered via Panel.getDockedItems().
650      */
651     renderItems: function(items, target) {
652         var cns = target.dom.childNodes,
653             cnsLn = cns.length,
654             ln = items.length,
655             domLn = 0,
656             i, j, cn, item;
657
658         // Calculate the number of DOM nodes in our target that are not our docked items
659         for (i = 0; i < cnsLn; i++) {
660             cn = Ext.get(cns[i]);
661             for (j = 0; j < ln; j++) {
662                 item = items[j];
663                 if (item.rendered && (cn.id == item.el.id || cn.contains(item.el.id))) {
664                     break;
665                 }
666             }
667
668             if (j === ln) {
669                 domLn++;
670             }
671         }
672
673         // Now we go through our docked items and render/move them
674         for (i = 0, j = 0; i < ln; i++, j++) {
675             item = items[i];
676
677             // If we're now at the right/bottom docked item, we jump ahead in our
678             // DOM position, just past the existing DOM nodes.
679             //
680             // TODO: This is affected if users provide custom weight values to their
681             // docked items, which puts it out of (t,l,r,b) order. Avoiding a second
682             // sort operation here, for now, in the name of performance. getDockedItems()
683             // needs the sort operation not just for this layout-time rendering, but
684             // also for getRefItems() to return a logical ordering (FocusManager, CQ, et al).
685             if (i === j && (item.dock === 'right' || item.dock === 'bottom')) {
686                 j += domLn;
687             }
688
689             // Same logic as Layout.renderItems()
690             if (item && !item.rendered) {
691                 this.renderItem(item, target, j);
692             }
693             else if (!this.isValidParent(item, target, j)) {
694                 this.moveItem(item, target, j);
695             }
696         }
697     },
698
699     /**
700      * @protected
701      * This function will be called by the dockItems method. Since the body is positioned absolute,
702      * we need to give it dimensions and a position so that it is in the middle surrounded by
703      * docked items
704      * @param {Object} box An object containing new x, y, width and height values for the
705      * Panel's body
706      */
707     setBodyBox : function(box) {
708         var me = this,
709             owner = me.owner,
710             body = owner.body,
711             info = me.info,
712             bodyMargin = info.bodyMargin,
713             padding = info.padding,
714             border = info.border,
715             frameSize = me.frameSize;
716         
717         // Panel collapse effectively hides the Panel's body, so this is a no-op.
718         if (owner.collapsed) {
719             return;
720         }
721         
722         if (Ext.isNumber(box.width)) {
723             box.width -= bodyMargin.left + bodyMargin.right;
724         }
725         
726         if (Ext.isNumber(box.height)) {
727             box.height -= bodyMargin.top + bodyMargin.bottom;
728         }
729         
730         me.setElementSize(body, box.width, box.height);
731         if (Ext.isNumber(box.x)) {
732             body.setLeft(box.x - padding.left - frameSize.left);
733         }
734         if (Ext.isNumber(box.y)) {
735             body.setTop(box.y - padding.top - frameSize.top);
736         }
737     },
738
739     /**
740      * @protected
741      * We are overriding the Ext.layout.Layout configureItem method to also add a class that
742      * indicates the position of the docked item. We use the itemCls (x-docked) as a prefix.
743      * An example of a class added to a dock: right item is x-docked-right
744      * @param {Ext.Component} item The item we are configuring
745      */
746     configureItem : function(item, pos) {
747         this.callParent(arguments);
748         if (item.dock == 'top' || item.dock == 'bottom') {
749             item.layoutManagedWidth = 1;
750             item.layoutManagedHeight = 2;
751         } else {
752             item.layoutManagedWidth = 2;
753             item.layoutManagedHeight = 1;
754         }
755         
756         item.addCls(Ext.baseCSSPrefix + 'docked');
757         item.addClsWithUI('docked-' + item.dock);
758     },
759
760     afterRemove : function(item) {
761         this.callParent(arguments);
762         if (this.itemCls) {
763             item.el.removeCls(this.itemCls + '-' + item.dock);
764         }
765         var dom = item.el.dom;
766
767         if (!item.destroying && dom) {
768             dom.parentNode.removeChild(dom);
769         }
770         this.childrenChanged = true;
771     }
772 });