PageRenderTime 36ms CodeModel.GetById 21ms app.highlight 9ms RepoModel.GetById 0ms app.codeStats 0ms

/ext-4.1.0_b3/docs/source/Renderable.html

https://bitbucket.org/srogerf/javascript
HTML | 1086 lines | 933 code | 153 blank | 0 comment | 0 complexity | c3706afd7f1ffa686a9250f604400cb3 MD5 | raw file
   1<!DOCTYPE html>
   2<html>
   3<head>
   4  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
   5  <title>The source code</title>
   6  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
   7  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
   8  <style type="text/css">
   9    .highlight { display: block; background-color: #ddd; }
  10  </style>
  11  <script type="text/javascript">
  12    function highlight() {
  13      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
  14    }
  15  </script>
  16</head>
  17<body onload="prettyPrint(); highlight();">
  18  <pre class="prettyprint lang-js"><span id='Ext-util-Renderable'>/**
  19</span> * Given a component hierarchy of this:
  20 *
  21 *      {
  22 *          xtype: 'panel',
  23 *          id: 'ContainerA',
  24 *          layout: 'hbox',
  25 *          renderTo: Ext.getBody(),
  26 *          items: [
  27 *              {
  28 *                  id: 'ContainerB',
  29 *                  xtype: 'container',
  30 *                  items: [
  31 *                      { id: 'ComponentA' }
  32 *                  ]
  33 *              }
  34 *          ]
  35 *      }
  36 *
  37 * The rendering of the above proceeds roughly like this:
  38 *
  39 *  - ContainerA's initComponent calls #render passing the `renderTo` property as the
  40 *    container argument.
  41 *  - `render` calls the `getRenderTree` method to get a complete {@link Ext.DomHelper} spec.
  42 *  - `getRenderTree` fires the &quot;beforerender&quot; event and calls the #beforeRender
  43 *    method. Its result is obtained by calling #getElConfig.
  44 *  - The #getElConfig method uses the `renderTpl` and its render data as the content
  45 *    of the `autoEl` described element.
  46 *  - The result of `getRenderTree` is passed to {@link Ext.DomHelper#append}.
  47 *  - The `renderTpl` contains calls to render things like docked items, container items
  48 *    and raw markup (such as the `html` or `tpl` config properties). These calls are to
  49 *    methods added to the {@link Ext.XTemplate} instance by #setupRenderTpl.
  50 *  - The #setupRenderTpl method adds methods such as `renderItems`, `renderContent`, etc.
  51 *    to the template. These are directed to &quot;doRenderItems&quot;, &quot;doRenderContent&quot; etc..
  52 *  - The #setupRenderTpl calls traverse from components to their {@link Ext.layout.Layout}
  53 *    object.
  54 *  - When a container is rendered, it also has a `renderTpl`. This is processed when the
  55 *    `renderContainer` method is called in the component's `renderTpl`. This call goes to
  56 *    Ext.layout.container.Container#doRenderContainer. This method repeats this
  57 *    process for all components in the container.
  58 *  - After the top-most component's markup is generated and placed in to the DOM, the next
  59 *    step is to link elements to their components and finish calling the component methods
  60 *    `onRender` and `afterRender` as well as fire the corresponding events.
  61 *  - The first step in this is to call #finishRender. This method descends the
  62 *    component hierarchy and calls `onRender` and fires the `render` event. These calls
  63 *    are delivered top-down to approximate the timing of these calls/events from previous
  64 *    versions.
  65 *  - During the pass, the component's `el` is set. Likewise, the `renderSelectors` and
  66 *    `childEls` are applied to capture references to the component's elements.
  67 *  - These calls are also made on the {@link Ext.layout.container.Container} layout to
  68 *    capture its elements. Both of these classes use {@link Ext.util.ElementContainer} to
  69 *    handle `childEls` processing.
  70 *  - Once this is complete, a similar pass is made by calling #finishAfterRender.
  71 *    This call also descends the component hierarchy, but this time the calls are made in
  72 *    a bottom-up order to `afterRender`.
  73 *
  74 * @private
  75 */
  76Ext.define('Ext.util.Renderable', {
  77    requires: [
  78        'Ext.dom.Element'
  79    ],
  80
  81    frameCls: Ext.baseCSSPrefix + 'frame',
  82
  83    frameIdRegex: /[\-]frame\d+[TMB][LCR]$/,
  84
  85    frameElementCls: {
  86        tl: [],
  87        tc: [],
  88        tr: [],
  89        ml: [],
  90        mc: [],
  91        mr: [],
  92        bl: [],
  93        bc: [],
  94        br: []
  95    },
  96
  97    frameElNames: ['TL','TC','TR','ML','MC','MR','BL','BC','BR'],
  98
  99    frameTpl: [
 100        '{%this.renderDockedItems(out,values,0);%}',
 101        '&lt;tpl if=&quot;top&quot;&gt;',
 102            '&lt;tpl if=&quot;left&quot;&gt;&lt;div id=&quot;{fgid}TL&quot; class=&quot;{frameCls}-tl {baseCls}-tl {baseCls}-{ui}-tl&lt;tpl if=&quot;uiCls&quot;&gt;&lt;tpl for=&quot;uiCls&quot;&gt; {parent.baseCls}-{parent.ui}-{.}-tl&lt;/tpl&gt;&lt;/tpl&gt;&quot; style=&quot;background-position: {tl}; padding-left: {frameWidth}px&quot; role=&quot;presentation&quot;&gt;&lt;/tpl&gt;',
 103                '&lt;tpl if=&quot;right&quot;&gt;&lt;div id=&quot;{fgid}TR&quot; class=&quot;{frameCls}-tr {baseCls}-tr {baseCls}-{ui}-tr&lt;tpl if=&quot;uiCls&quot;&gt;&lt;tpl for=&quot;uiCls&quot;&gt; {parent.baseCls}-{parent.ui}-{.}-tr&lt;/tpl&gt;&lt;/tpl&gt;&quot; style=&quot;background-position: {tr}; padding-right: {frameWidth}px&quot; role=&quot;presentation&quot;&gt;&lt;/tpl&gt;',
 104                    '&lt;div id=&quot;{fgid}TC&quot; class=&quot;{frameCls}-tc {baseCls}-tc {baseCls}-{ui}-tc&lt;tpl if=&quot;uiCls&quot;&gt;&lt;tpl for=&quot;uiCls&quot;&gt; {parent.baseCls}-{parent.ui}-{.}-tc&lt;/tpl&gt;&lt;/tpl&gt;&quot; style=&quot;background-position: {tc}; height: {frameWidth}px&quot; role=&quot;presentation&quot;&gt;&lt;/div&gt;',
 105                '&lt;tpl if=&quot;right&quot;&gt;&lt;/div&gt;&lt;/tpl&gt;',
 106            '&lt;tpl if=&quot;left&quot;&gt;&lt;/div&gt;&lt;/tpl&gt;',
 107        '&lt;/tpl&gt;',
 108        '&lt;tpl if=&quot;left&quot;&gt;&lt;div id=&quot;{fgid}ML&quot; class=&quot;{frameCls}-ml {baseCls}-ml {baseCls}-{ui}-ml&lt;tpl if=&quot;uiCls&quot;&gt;&lt;tpl for=&quot;uiCls&quot;&gt; {parent.baseCls}-{parent.ui}-{.}-ml&lt;/tpl&gt;&lt;/tpl&gt;&quot; style=&quot;background-position: {ml}; padding-left: {frameWidth}px&quot; role=&quot;presentation&quot;&gt;&lt;/tpl&gt;',
 109            '&lt;tpl if=&quot;right&quot;&gt;&lt;div id=&quot;{fgid}MR&quot; class=&quot;{frameCls}-mr {baseCls}-mr {baseCls}-{ui}-mr&lt;tpl if=&quot;uiCls&quot;&gt;&lt;tpl for=&quot;uiCls&quot;&gt; {parent.baseCls}-{parent.ui}-{.}-mr&lt;/tpl&gt;&lt;/tpl&gt;&quot; style=&quot;background-position: {mr}; padding-right: {frameWidth}px&quot; role=&quot;presentation&quot;&gt;&lt;/tpl&gt;',
 110                '&lt;div id=&quot;{fgid}MC&quot; class=&quot;{frameCls}-mc {baseCls}-mc {baseCls}-{ui}-mc&lt;tpl if=&quot;uiCls&quot;&gt;&lt;tpl for=&quot;uiCls&quot;&gt; {parent.baseCls}-{parent.ui}-{.}-mc&lt;/tpl&gt;&lt;/tpl&gt;&quot; role=&quot;presentation&quot;&gt;',
 111                    '{%this.applyRenderTpl(out, values)%}',
 112                '&lt;/div&gt;',
 113            '&lt;tpl if=&quot;right&quot;&gt;&lt;/div&gt;&lt;/tpl&gt;',
 114        '&lt;tpl if=&quot;left&quot;&gt;&lt;/div&gt;&lt;/tpl&gt;',
 115        '&lt;tpl if=&quot;bottom&quot;&gt;',
 116            '&lt;tpl if=&quot;left&quot;&gt;&lt;div id=&quot;{fgid}BL&quot; class=&quot;{frameCls}-bl {baseCls}-bl {baseCls}-{ui}-bl&lt;tpl if=&quot;uiCls&quot;&gt;&lt;tpl for=&quot;uiCls&quot;&gt; {parent.baseCls}-{parent.ui}-{.}-bl&lt;/tpl&gt;&lt;/tpl&gt;&quot; style=&quot;background-position: {bl}; padding-left: {frameWidth}px&quot; role=&quot;presentation&quot;&gt;&lt;/tpl&gt;',
 117                '&lt;tpl if=&quot;right&quot;&gt;&lt;div id=&quot;{fgid}BR&quot; class=&quot;{frameCls}-br {baseCls}-br {baseCls}-{ui}-br&lt;tpl if=&quot;uiCls&quot;&gt;&lt;tpl for=&quot;uiCls&quot;&gt; {parent.baseCls}-{parent.ui}-{.}-br&lt;/tpl&gt;&lt;/tpl&gt;&quot; style=&quot;background-position: {br}; padding-right: {frameWidth}px&quot; role=&quot;presentation&quot;&gt;&lt;/tpl&gt;',
 118                    '&lt;div id=&quot;{fgid}BC&quot; class=&quot;{frameCls}-bc {baseCls}-bc {baseCls}-{ui}-bc&lt;tpl if=&quot;uiCls&quot;&gt;&lt;tpl for=&quot;uiCls&quot;&gt; {parent.baseCls}-{parent.ui}-{.}-bc&lt;/tpl&gt;&lt;/tpl&gt;&quot; style=&quot;background-position: {bc}; height: {frameWidth}px&quot; role=&quot;presentation&quot;&gt;&lt;/div&gt;',
 119                '&lt;tpl if=&quot;right&quot;&gt;&lt;/div&gt;&lt;/tpl&gt;',
 120            '&lt;tpl if=&quot;left&quot;&gt;&lt;/div&gt;&lt;/tpl&gt;',
 121        '&lt;/tpl&gt;',
 122        '{%this.renderDockedItems(out,values,1);%}'
 123    ],
 124
 125    frameTableTpl: [
 126        '{%this.renderDockedItems(out,values,0);%}',
 127        '&lt;table&gt;&lt;tbody&gt;',
 128            '&lt;tpl if=&quot;top&quot;&gt;',
 129                '&lt;tr&gt;',
 130                    '&lt;tpl if=&quot;left&quot;&gt;&lt;td id=&quot;{fgid}TL&quot; class=&quot;{frameCls}-tl {baseCls}-tl {baseCls}-{ui}-tl&lt;tpl if=&quot;uiCls&quot;&gt;&lt;tpl for=&quot;uiCls&quot;&gt; {parent.baseCls}-{parent.ui}-{.}-tl&lt;/tpl&gt;&lt;/tpl&gt;&quot; style=&quot;background-position: {tl}; padding-left:{frameWidth}px&quot; role=&quot;presentation&quot;&gt;&lt;/td&gt;&lt;/tpl&gt;',
 131                    '&lt;td id=&quot;{fgid}TC&quot; class=&quot;{frameCls}-tc {baseCls}-tc {baseCls}-{ui}-tc&lt;tpl if=&quot;uiCls&quot;&gt;&lt;tpl for=&quot;uiCls&quot;&gt; {parent.baseCls}-{parent.ui}-{.}-tc&lt;/tpl&gt;&lt;/tpl&gt;&quot; style=&quot;background-position: {tc}; height: {frameWidth}px&quot; role=&quot;presentation&quot;&gt;&lt;/td&gt;',
 132                    '&lt;tpl if=&quot;right&quot;&gt;&lt;td id=&quot;{fgid}TR&quot; class=&quot;{frameCls}-tr {baseCls}-tr {baseCls}-{ui}-tr&lt;tpl if=&quot;uiCls&quot;&gt;&lt;tpl for=&quot;uiCls&quot;&gt; {parent.baseCls}-{parent.ui}-{.}-tr&lt;/tpl&gt;&lt;/tpl&gt;&quot; style=&quot;background-position: {tr}; padding-left: {frameWidth}px&quot; role=&quot;presentation&quot;&gt;&lt;/td&gt;&lt;/tpl&gt;',
 133                '&lt;/tr&gt;',
 134            '&lt;/tpl&gt;',
 135            '&lt;tr&gt;',
 136                '&lt;tpl if=&quot;left&quot;&gt;&lt;td id=&quot;{fgid}ML&quot; class=&quot;{frameCls}-ml {baseCls}-ml {baseCls}-{ui}-ml&lt;tpl if=&quot;uiCls&quot;&gt;&lt;tpl for=&quot;uiCls&quot;&gt; {parent.baseCls}-{parent.ui}-{.}-ml&lt;/tpl&gt;&lt;/tpl&gt;&quot; style=&quot;background-position: {ml}; padding-left: {frameWidth}px&quot; role=&quot;presentation&quot;&gt;&lt;/td&gt;&lt;/tpl&gt;',
 137                '&lt;td id=&quot;{fgid}MC&quot; class=&quot;{frameCls}-mc {baseCls}-mc {baseCls}-{ui}-mc&lt;tpl if=&quot;uiCls&quot;&gt;&lt;tpl for=&quot;uiCls&quot;&gt; {parent.baseCls}-{parent.ui}-{.}-mc&lt;/tpl&gt;&lt;/tpl&gt;&quot; style=&quot;background-position: 0 0;&quot; role=&quot;presentation&quot;&gt;',
 138                    '{%this.applyRenderTpl(out, values)%}',
 139                '&lt;/td&gt;',
 140                '&lt;tpl if=&quot;right&quot;&gt;&lt;td id=&quot;{fgid}MR&quot; class=&quot;{frameCls}-mr {baseCls}-mr {baseCls}-{ui}-mr&lt;tpl if=&quot;uiCls&quot;&gt;&lt;tpl for=&quot;uiCls&quot;&gt; {parent.baseCls}-{parent.ui}-{.}-mr&lt;/tpl&gt;&lt;/tpl&gt;&quot; style=&quot;background-position: {mr}; padding-left: {frameWidth}px&quot; role=&quot;presentation&quot;&gt;&lt;/td&gt;&lt;/tpl&gt;',
 141            '&lt;/tr&gt;',
 142            '&lt;tpl if=&quot;bottom&quot;&gt;',
 143                '&lt;tr&gt;',
 144                    '&lt;tpl if=&quot;left&quot;&gt;&lt;td id=&quot;{fgid}BL&quot; class=&quot;{frameCls}-bl {baseCls}-bl {baseCls}-{ui}-bl&lt;tpl if=&quot;uiCls&quot;&gt;&lt;tpl for=&quot;uiCls&quot;&gt; {parent.baseCls}-{parent.ui}-{.}-bl&lt;/tpl&gt;&lt;/tpl&gt;&quot; style=&quot;background-position: {bl}; padding-left: {frameWidth}px&quot; role=&quot;presentation&quot;&gt;&lt;/td&gt;&lt;/tpl&gt;',
 145                    '&lt;td id=&quot;{fgid}BC&quot; class=&quot;{frameCls}-bc {baseCls}-bc {baseCls}-{ui}-bc&lt;tpl if=&quot;uiCls&quot;&gt;&lt;tpl for=&quot;uiCls&quot;&gt; {parent.baseCls}-{parent.ui}-{.}-bc&lt;/tpl&gt;&lt;/tpl&gt;&quot; style=&quot;background-position: {bc}; height: {frameWidth}px&quot; role=&quot;presentation&quot;&gt;&lt;/td&gt;',
 146                    '&lt;tpl if=&quot;right&quot;&gt;&lt;td id=&quot;{fgid}BR&quot; class=&quot;{frameCls}-br {baseCls}-br {baseCls}-{ui}-br&lt;tpl if=&quot;uiCls&quot;&gt;&lt;tpl for=&quot;uiCls&quot;&gt; {parent.baseCls}-{parent.ui}-{.}-br&lt;/tpl&gt;&lt;/tpl&gt;&quot; style=&quot;background-position: {br}; padding-left: {frameWidth}px&quot; role=&quot;presentation&quot;&gt;&lt;/td&gt;&lt;/tpl&gt;',
 147                '&lt;/tr&gt;',
 148            '&lt;/tpl&gt;',
 149        '&lt;/tbody&gt;&lt;/table&gt;',
 150        '{%this.renderDockedItems(out,values,1);%}'
 151    ],
 152
 153<span id='Ext-util-Renderable-method-afterRender'>    /**
 154</span>     * Allows addition of behavior after rendering is complete. At this stage the Component’s Element
 155     * will have been styled according to the configuration, will have had any configured CSS class
 156     * names added, and will be in the configured visibility and the configured enable state.
 157     *
 158     * @template
 159     * @protected
 160     */
 161    afterRender : function() {
 162        var me = this,
 163            data = {},
 164            protoEl = me.protoEl,
 165            target = me.getTargetEl(),
 166            item;
 167
 168        me.finishRenderChildren();
 169
 170        if (me.styleHtmlContent) {
 171            target.addCls(me.styleHtmlCls);
 172        }
 173        
 174        protoEl.writeTo(data);
 175        
 176        // Here we apply any styles that were set on the protoEl during the rendering phase
 177        // A majority of times this will not happen, but we still need to handle it
 178        
 179        item = data.removed;
 180        if (item) {
 181            target.removeCls(item);
 182        }
 183        
 184        item = data.cls;
 185        if (item.length) {
 186            target.addCls(item);
 187        }
 188        
 189        item = data.style;
 190        if (data.style) {
 191            target.setStyle(item);
 192        }
 193        
 194        me.protoEl = null;
 195
 196        // If this is the outermost Container, lay it out as soon as it is rendered.
 197        if (!me.ownerCt) {
 198            me.updateLayout();
 199        }
 200    },
 201
 202    afterFirstLayout : function() {
 203        var me = this,
 204            hasX = Ext.isDefined(me.x),
 205            hasY = Ext.isDefined(me.y),
 206            pos, xy;
 207
 208        // For floaters, calculate x and y if they aren't defined by aligning
 209        // the sized element to the center of either the container or the ownerCt
 210        if (me.floating &amp;&amp; (!hasX || !hasY)) {
 211            if (me.floatParent) {
 212                xy = me.el.getAlignToXY(me.floatParent.getTargetEl(), 'c-c');
 213                pos = me.floatParent.getTargetEl().translatePoints(xy[0], xy[1]);
 214            } else {
 215                xy = me.el.getAlignToXY(me.container, 'c-c');
 216                pos = me.container.translatePoints(xy[0], xy[1]);
 217            }
 218            me.x = hasX ? me.x : pos.left;
 219            me.y = hasY ? me.y : pos.top;
 220            hasX = hasY = true;
 221        }
 222
 223        if (hasX || hasY) {
 224            me.setPosition(me.x, me.y);
 225        }
 226        me.onBoxReady();
 227        if (me.hasListeners.boxready) {
 228            me.fireEvent('boxready', me);
 229        }
 230    },
 231    
 232    onBoxReady: Ext.emptyFn,
 233
 234<span id='Ext-util-Renderable-method-applyRenderSelectors'>    /**
 235</span>     * Sets references to elements inside the component. This applies {@link #renderSelectors}
 236     * as well as {@link #childEls}.
 237     * @private
 238     */
 239    applyRenderSelectors: function() {
 240        var me = this,
 241            selectors = me.renderSelectors,
 242            el = me.el,
 243            dom = el.dom,
 244            selector;
 245
 246        me.applyChildEls(el);
 247
 248        // We still support renderSelectors. There are a few places in the framework that
 249        // need them and they are a documented part of the API. In fact, we support mixing
 250        // childEls and renderSelectors (no reason not to).
 251        if (selectors) {
 252            for (selector in selectors) {
 253                if (selectors.hasOwnProperty(selector) &amp;&amp; selectors[selector]) {
 254                    me[selector] = Ext.get(Ext.DomQuery.selectNode(selectors[selector], dom));
 255                }
 256            }
 257        }
 258    },
 259
 260    beforeRender: function () {
 261        var me = this,
 262            layout = me.getComponentLayout();
 263
 264        if (!layout.initialized) {
 265            layout.initLayout();
 266        }
 267
 268        me.setUI(me.ui);
 269
 270        if (me.disabled) {
 271            // pass silent so the event doesn't fire the first time.
 272            me.disable(true);
 273        }
 274    },
 275
 276<span id='Ext-util-Renderable-method-doApplyRenderTpl'>    /**
 277</span>     * @private
 278     * Called from the selected frame generation template to insert this Component's inner structure inside the framing structure.
 279     *
 280     * When framing is used, a selected frame generation template is used as the primary template of the #getElConfig instead
 281     * of the configured {@link #renderTpl}. The {@link #renderTpl} is invoked by this method which is injected into the framing template.
 282     */
 283    doApplyRenderTpl: function(out, values) {
 284        // Careful! This method is bolted on to the frameTpl so all we get for context is
 285        // the renderData! The &quot;this&quot; pointer is the frameTpl instance!
 286
 287        var me = values.$comp,
 288            tpl;
 289
 290        // Don't do this if the component is already rendered:
 291        if (!me.rendered) {
 292            tpl = me.initRenderTpl();
 293            tpl.applyOut(values.renderData, out);
 294        }
 295    },
 296
 297<span id='Ext-util-Renderable-method-doAutoRender'>    /**
 298</span>     * Handles autoRender.
 299     * Floating Components may have an ownerCt. If they are asking to be constrained, constrain them within that
 300     * ownerCt, and have their z-index managed locally. Floating Components are always rendered to document.body
 301     */
 302    doAutoRender: function() {
 303        var me = this;
 304        if (!me.rendered) {
 305            if (me.floating) {
 306                me.render(document.body);
 307            } else {
 308                me.render(Ext.isBoolean(me.autoRender) ? Ext.getBody() : me.autoRender);
 309            }
 310        }
 311    },
 312
 313    doRenderContent: function (out, renderData) {
 314        // Careful! This method is bolted on to the renderTpl so all we get for context is
 315        // the renderData! The &quot;this&quot; pointer is the renderTpl instance!
 316
 317        var me = renderData.$comp;
 318
 319        if (me.html) {
 320            Ext.DomHelper.generateMarkup(me.html, out);
 321            delete me.html;
 322        }
 323
 324        if (me.tpl) {
 325            // Make sure this.tpl is an instantiated XTemplate
 326            if (!me.tpl.isTemplate) {
 327                me.tpl = new Ext.XTemplate(me.tpl);
 328            }
 329
 330            if (me.data) {
 331                //me.tpl[me.tplWriteMode](target, me.data);
 332                me.tpl.applyOut(me.data, out);
 333                delete me.data;
 334            }
 335        }
 336    },
 337
 338    doRenderFramingDockedItems: function (out, renderData, after) {
 339        // Careful! This method is bolted on to the frameTpl so all we get for context is
 340        // the renderData! The &quot;this&quot; pointer is the frameTpl instance!
 341
 342        var me = renderData.$comp;
 343
 344        // Most components don't have dockedItems, so check for doRenderDockedItems on the
 345        // component (also, don't do this if the component is already rendered):
 346        if (!me.rendered &amp;&amp; me.doRenderDockedItems) {
 347            // The &quot;renderData&quot; property is placed in scope for the renderTpl, but we don't
 348            // want to render docked items at that level in addition to the framing level:
 349            renderData.renderData.$skipDockedItems = true;
 350
 351            // doRenderDockedItems requires the $comp property on renderData, but this is
 352            // set on the frameTpl's renderData as well:
 353            me.doRenderDockedItems.call(this, out, renderData, after);
 354        }
 355    },
 356
 357<span id='Ext-util-Renderable-method-finishRender'>    /**
 358</span>     * This method visits the rendered component tree in a &quot;top-down&quot; order. That is, this
 359     * code runs on a parent component before running on a child. This method calls the
 360     * {@link #onRender} method of each component.
 361     * @param {Number} containerIdx The index into the Container items of this Component.
 362     *
 363     * @private
 364     */
 365    finishRender: function(containerIdx) {
 366        var me = this,
 367            tpl, data, contentEl, el, pre, hide, target;
 368
 369        // We are typically called w/me.el==null as a child of some ownerCt that is being
 370        // rendered. We are also called by render for a normal component (w/o a configured
 371        // me.el). In this case, render sets me.el and me.rendering (indirectly). Lastly
 372        // we are also called on a component (like a Viewport) that has a configured me.el
 373        // (body for a Viewport) when render is called. In this case, it is not flagged as
 374        // &quot;me.rendering&quot; yet becasue it does not produce a renderTree. We use this to know
 375        // not to regen the renderTpl.
 376
 377        if (!me.el || me.$pid) {
 378            if (me.container) {
 379                el = me.container.getById(me.id, true);
 380            } else {
 381                el = Ext.getDom(me.id);
 382            }
 383
 384            if (!me.el) {
 385                // Typical case: we produced the el during render
 386                me.wrapPrimaryEl(el);
 387            } else {
 388                // We were configured with an el and created a proxy, so now we can swap
 389                // the proxy for me.el:
 390                delete me.$pid;
 391
 392                if (!me.el.dom) {
 393                    // make sure me.el is an Element
 394                    me.wrapPrimaryEl(me.el);
 395                }
 396                el.parentNode.insertBefore(me.el.dom, el);
 397                Ext.removeNode(el); // remove placeholder el
 398                // TODO - what about class/style?
 399            }
 400        } else if (!me.rendering) {
 401            // We were configured with an el and then told to render (e.g., Viewport). We
 402            // need to generate the proper DOM. Insert first because the layout system
 403            // insists that child Component elements indices match the Component indices.
 404            tpl = me.initRenderTpl();
 405            if (tpl) {
 406                data = me.initRenderData();
 407                tpl.insertFirst(me.getTargetEl(), data);
 408            }
 409        }
 410        // else we are rendering
 411
 412        if (!me.container) {
 413            // top-level rendered components will already have me.container set up
 414            me.container = Ext.get(me.el.dom.parentNode);
 415        }
 416
 417        if (me.ctCls) {
 418            me.container.addCls(me.ctCls);
 419        }
 420
 421        // Sets the rendered flag and clears the redering flag
 422        me.onRender(me.container, containerIdx);
 423
 424        // Initialize with correct overflow attributes
 425        target = me.getTargetEl();
 426        target.setStyle(me.getOverflowStyle());
 427
 428        // Tell the encapsulating element to hide itself in the way the Component is configured to hide
 429        // This means DISPLAY, VISIBILITY or OFFSETS.
 430        me.el.setVisibilityMode(Ext.Element[me.hideMode.toUpperCase()]);
 431
 432        if (me.overCls) {
 433            me.el.hover(me.addOverCls, me.removeOverCls, me);
 434        }
 435
 436        if (me.hasListeners.render) {
 437            me.fireEvent('render', me);
 438        }
 439
 440        if (me.contentEl) {
 441            pre = Ext.baseCSSPrefix;
 442            hide = pre + 'hide-';
 443            contentEl = Ext.get(me.contentEl);
 444            contentEl.removeCls([pre+'hidden', hide+'display', hide+'offsets', hide+'nosize']);
 445            target.appendChild(contentEl.dom);
 446        }
 447
 448        me.afterRender(); // this can cause a layout
 449        if (me.hasListeners.afterrender) {
 450            me.fireEvent('afterrender', me);
 451        }
 452        me.initEvents();
 453
 454        if (me.hidden) {
 455            // Hiding during the render process should not perform any ancillary
 456            // actions that the full hide process does; It is not hiding, it begins in a hidden state.'
 457            // So just make the element hidden according to the configured hideMode
 458            me.el.hide();
 459        }
 460    },
 461
 462    finishRenderChildren: function () {
 463        var layout = this.getComponentLayout();
 464
 465        layout.finishRender();
 466    },
 467
 468    getElConfig : function() {
 469        var me = this,
 470            autoEl = me.autoEl,
 471            frameInfo = me.getFrameInfo(),
 472            config = {
 473                tag: 'div',
 474                id: me.id,
 475                tpl: frameInfo ? me.initFramingTpl(frameInfo.table) : me.initRenderTpl()
 476            };
 477
 478        me.initStyles(me.protoEl);
 479        me.protoEl.writeTo(config);
 480        me.protoEl.flush();
 481
 482        if (Ext.isString(autoEl)) {
 483            config.tag = autoEl;
 484        } else {
 485            Ext.apply(config, autoEl); // harmless if !autoEl
 486        }
 487
 488        if (config.tpl) {
 489            // Use the framingTpl as the main content creating template. It will call out to this.applyRenderTpl(out, values)
 490            if (frameInfo) {
 491                var i,
 492                    frameElNames = me.frameElNames,
 493                    len = frameElNames.length,
 494                    suffix,
 495                    frameGenId = me.id + '-frame1';
 496
 497                me.frameGenId = 1;
 498                config.tplData = Ext.apply({}, {
 499                    $comp:      me,
 500                    fgid:       frameGenId,
 501                    ui:         me.ui,
 502                    uiCls:      me.uiCls,
 503                    frameCls:   me.frameCls,
 504                    baseCls:    me.baseCls,
 505                    frameWidth: frameInfo.maxWidth,
 506                    top:        !!frameInfo.top,
 507                    left:       !!frameInfo.left,
 508                    right:      !!frameInfo.right,
 509                    bottom:     !!frameInfo.bottom,
 510                    renderData: me.initRenderData()
 511                }, me.getFramePositions(frameInfo));
 512
 513                // Add the childEls for each of the frame elements
 514                for (i = 0; i &lt; len; i++) {
 515                    suffix = frameElNames[i];
 516                    me.addChildEls({ name: 'frame' + suffix, id: frameGenId + suffix });
 517                }
 518
 519                // Panel must have a frameBody
 520                me.addChildEls({
 521                    name: 'frameBody',
 522                    id: frameGenId + 'MC'
 523                });
 524            } else {
 525                config.tplData = me.initRenderData();
 526            }
 527        }
 528
 529        return config;
 530    },
 531
 532    // Create the framingTpl from the string.
 533    // Poke in a reference to applyRenderTpl(frameInfo, out)
 534    initFramingTpl: function(table) {
 535        var tpl = table ? this.getTpl('frameTableTpl') : this.getTpl('frameTpl');
 536
 537        if (tpl &amp;&amp; !tpl.applyRenderTpl) {
 538            this.setupFramingTpl(tpl);
 539        }
 540
 541        return tpl;
 542    },
 543
 544<span id='Ext-util-Renderable-method-setupFramingTpl'>    /**
 545</span>     * @private
 546     * Inject a reference to the function which applies the render template into the framing template. The framing template
 547     * wraps the content.
 548     */
 549    setupFramingTpl: function(frameTpl) {
 550        frameTpl.applyRenderTpl = this.doApplyRenderTpl;
 551        frameTpl.renderDockedItems = this.doRenderFramingDockedItems;
 552    },
 553
 554<span id='Ext-util-Renderable-method-getInsertPosition'>    /**
 555</span>     * This function takes the position argument passed to onRender and returns a
 556     * DOM element that you can use in the insertBefore.
 557     * @param {String/Number/Ext.dom.Element/HTMLElement} position Index, element id or element you want
 558     * to put this component before.
 559     * @return {HTMLElement} DOM element that you can use in the insertBefore
 560     */
 561    getInsertPosition: function(position) {
 562        // Convert the position to an element to insert before
 563        if (position !== undefined) {
 564            if (Ext.isNumber(position)) {
 565                position = this.container.dom.childNodes[position];
 566            }
 567            else {
 568                position = Ext.getDom(position);
 569            }
 570        }
 571
 572        return position;
 573    },
 574
 575    getRenderTree: function() {
 576        var me = this;
 577
 578        me.beforeRender();
 579
 580        if (!me.hasListeners.beforerender || me.fireEvent('beforerender', me) !== false) {
 581            // Flag to let the layout's finishRenderItems and afterFinishRenderItems
 582            // know which items to process
 583            me.rendering = true;
 584
 585            if (me.el) {
 586                // Since we are producing a render tree, we produce a &quot;proxy el&quot; that will
 587                // sit in the rendered DOM precisely where me.el belongs. We replace the
 588                // proxy el in the finishRender phase.
 589                return {
 590                    tag: 'div',
 591                    id: (me.$pid = Ext.id())
 592                };
 593            }
 594
 595            return me.getElConfig();
 596        }
 597
 598        return null;
 599    },
 600
 601    initContainer: function(container) {
 602        var me = this;
 603
 604        // If you render a component specifying the el, we get the container
 605        // of the el, and make sure we dont move the el around in the dom
 606        // during the render
 607        if (!container &amp;&amp; me.el) {
 608            container = me.el.dom.parentNode;
 609            me.allowDomMove = false;
 610        }
 611        me.container = container.dom ? container : Ext.get(container);
 612
 613        return me.container;
 614    },
 615
 616<span id='Ext-util-Renderable-method-initRenderData'>    /**
 617</span>     * Initialized the renderData to be used when rendering the renderTpl.
 618     * @return {Object} Object with keys and values that are going to be applied to the renderTpl
 619     * @private
 620     */
 621    initRenderData: function() {
 622        var me = this;
 623
 624        return Ext.apply({
 625            $comp: me,
 626            id: me.id,
 627            ui: me.ui,
 628            uiCls: me.uiCls,
 629            baseCls: me.baseCls,
 630            componentCls: me.componentCls,
 631            frame: me.frame
 632        }, me.renderData);
 633    },
 634
 635<span id='Ext-util-Renderable-method-initRenderTpl'>    /**
 636</span>     * Initializes the renderTpl.
 637     * @return {Ext.XTemplate} The renderTpl XTemplate instance.
 638     * @private
 639     */
 640    initRenderTpl: function() {
 641        var tpl = this.getTpl('renderTpl');
 642
 643        if (tpl &amp;&amp; !tpl.renderContent) {
 644            this.setupRenderTpl(tpl);
 645        }
 646
 647        return tpl;
 648    },
 649
 650<span id='Ext-util-Renderable-method-onRender'>    /**
 651</span>     * Template method called when this Component's DOM structure is created.
 652     *
 653     * At this point, this Component's (and all descendants') DOM structure *exists* but it has not
 654     * been layed out (positioned and sized).
 655     *
 656     * Subclasses which override this to gain access to the structure at render time should
 657     * call the parent class's method before attempting to access any child elements of the Component.
 658     *
 659     * @param {Ext.core.Element} parentNode The parent Element in which this Component's encapsulating element is contained.
 660     * @param {Number} containerIdx The index within the parent Container's child collection of this Component.
 661     *
 662     * @template
 663     * @protected
 664     */
 665    onRender: function(parentNode, containerIdx) {
 666        var me = this,
 667            x = me.x,
 668            y = me.y,
 669            lastBox, width, height,
 670            el = me.el;
 671
 672        // After the container property has been collected, we can wrap the Component in a reset wraper if necessary
 673        if (Ext.scopeResetCSS &amp;&amp; !me.ownerCt) {
 674            // If this component's el is the body element, we add the reset class to the html tag
 675            if (el.dom == Ext.getBody().dom) {
 676                el.parent().addCls(Ext.resetCls);
 677            }
 678            else {
 679                // Else we wrap this element in an element that adds the reset class.
 680                me.resetEl = el.wrap({
 681                    cls: Ext.resetCls
 682                });
 683            }
 684        }
 685
 686        me.applyRenderSelectors();
 687
 688        // Flag set on getRenderTree to flag to the layout's postprocessing routine that
 689        // the Component is in the process of being rendered and needs postprocessing.
 690        delete me.rendering;
 691
 692        me.rendered = true;
 693
 694        // We need to remember these to avoid writing them during the initial layout:
 695        lastBox = null;
 696
 697        if (x !== undefined) {
 698            lastBox = lastBox || {};
 699            lastBox.x = x;
 700        }
 701        if (y !== undefined) {
 702            lastBox = lastBox || {};
 703            lastBox.y = y;
 704        }
 705        // Framed components need their width/height to apply to the frame, which is
 706        // best handled in layout at present.
 707        // If we're using the content box model, we also cannot assign initial sizes since we do not know the border widths to subtract
 708        if (!me.getFrameInfo() &amp;&amp; Ext.isBorderBox) {
 709            width = me.width;
 710            height = me.height;
 711
 712            if (typeof width == 'number') {
 713                lastBox = lastBox || {};
 714                lastBox.width = width;
 715            }
 716            if (typeof height == 'number') {
 717                lastBox = lastBox || {};
 718                lastBox.height = height;
 719            }
 720        }
 721
 722        me.lastBox = me.el.lastBox = lastBox;
 723    },
 724
 725    render: function(container, position) {
 726        var me = this,
 727            el = me.el &amp;&amp; (me.el = Ext.get(me.el)), // ensure me.el is wrapped
 728            tree,
 729            nextSibling;
 730
 731        Ext.suspendLayouts();
 732
 733        container = me.initContainer(container);
 734
 735        nextSibling = me.getInsertPosition(position);
 736
 737        if (!el) {
 738            tree = me.getRenderTree();
 739            if (nextSibling) {
 740                el = Ext.DomHelper.insertBefore(nextSibling, tree);
 741            } else {
 742                el = Ext.DomHelper.append(container, tree);
 743            }
 744            me.wrapPrimaryEl(el);
 745        } else {
 746            // Set configured styles on pre-rendered Component's element
 747            me.initStyles(el);
 748            if (me.allowDomMove !== false) {
 749                //debugger; // TODO
 750                if (nextSibling) {
 751                    container.dom.insertBefore(el.dom, nextSibling);
 752                } else {
 753                    container.dom.appendChild(el.dom);
 754                }
 755            }
 756        }
 757
 758        me.finishRender(position);
 759
 760        Ext.resumeLayouts(!container.isDetachedBody);
 761    },
 762
 763<span id='Ext-util-Renderable-method-ensureAttachedToBody'>    /**
 764</span>     * Ensures that this component is attached to `document.body`. If the component was
 765     * rendered to {@link Ext#getDetachedBody}, then it will be appended to `document.body`.
 766     * Any configured position is also restored.
 767     * @param {Boolean} [runLayout=false] True to run the component's layout.
 768     */
 769    ensureAttachedToBody: function (runLayout) {
 770        var comp = this,
 771            body;
 772
 773        while (comp.ownerCt) {
 774            comp = comp.ownerCt;
 775        }
 776
 777        if (comp.container.isDetachedBody) {
 778            comp.container = body = Ext.getBody();
 779            body.appendChild(comp.el.dom);
 780            if (runLayout) {
 781                comp.updateLayout();
 782            }
 783            if (typeof comp.x == 'number' || typeof comp.y == 'number') {
 784                comp.setPosition(comp.x, comp.y);
 785            }
 786        }
 787    },
 788
 789    setupRenderTpl: function (renderTpl) {
 790        renderTpl.renderBody = renderTpl.renderContent = this.doRenderContent;
 791    },
 792
 793    wrapPrimaryEl: function (dom) {
 794        this.el = Ext.get(dom, true);
 795    },
 796
 797<span id='Ext-util-Renderable-method-initFrame'>    /**
 798</span>     * @private
 799     */
 800    initFrame : function() {
 801        if (Ext.supports.CSS3BorderRadius) {
 802            return;
 803        }
 804
 805        var me = this,
 806            frameInfo = me.getFrameInfo(),
 807            frameWidth, frameTpl, frameGenId,
 808            i,
 809            frameElNames = me.frameElNames,
 810            len = frameElNames.length,
 811            suffix;
 812
 813        if (frameInfo) {
 814            frameWidth = frameInfo.maxWidth;
 815            frameTpl = me.getFrameTpl(frameInfo.table);
 816
 817            // since we render id's into the markup and id's NEED to be unique, we have a
 818            // simple strategy for numbering their generations.
 819            me.frameGenId = frameGenId = (me.frameGenId || 0) + 1;
 820            frameGenId = me.id + '-frame' + frameGenId;
 821
 822            // Here we render the frameTpl to this component. This inserts the 9point div or the table framing.
 823            frameTpl.insertFirst(me.el, Ext.apply({
 824                $comp:      me,
 825                fgid:       frameGenId,
 826                ui:         me.ui,
 827                uiCls:      me.uiCls,
 828                frameCls:   me.frameCls,
 829                baseCls:    me.baseCls,
 830                frameWidth: frameWidth,
 831                top:        !!frameInfo.top,
 832                left:       !!frameInfo.left,
 833                right:      !!frameInfo.right,
 834                bottom:     !!frameInfo.bottom
 835            }, me.getFramePositions(frameInfo)));
 836
 837            // The frameBody is returned in getTargetEl, so that layouts render items to the correct target.
 838            me.frameBody = me.el.down('.' + me.frameCls + '-mc');
 839
 840            // Clean out the childEls for the old frame elements (the majority of the els)
 841            me.removeChildEls(function (c) {
 842                return c.id &amp;&amp; me.frameIdRegex.test(c.id);
 843            });
 844
 845            // Grab references to the childEls for each of the new frame elements
 846            for (i = 0; i &lt; len; i++) {
 847                suffix = frameElNames[i];
 848                me['frame' + suffix] = me.el.getById(frameGenId + suffix);
 849            }
 850        }
 851    },
 852
 853    updateFrame: function() {
 854        if (Ext.supports.CSS3BorderRadius) {
 855            return;
 856        }
 857
 858        var me = this,
 859            wasTable = this.frameSize &amp;&amp; this.frameSize.table,
 860            oldFrameTL = this.frameTL,
 861            oldFrameBL = this.frameBL,
 862            oldFrameML = this.frameML,
 863            oldFrameMC = this.frameMC,
 864            newMCClassName;
 865
 866        this.initFrame();
 867
 868        if (oldFrameMC) {
 869            if (me.frame) {
 870
 871                // Store the class names set on the new MC
 872                newMCClassName = this.frameMC.dom.className;
 873
 874                // Framing elements have been selected in initFrame, no need to run applyRenderSelectors
 875                // Replace the new mc with the old mc
 876                oldFrameMC.insertAfter(this.frameMC);
 877                this.frameMC.remove();
 878
 879                // Restore the reference to the old frame mc as the framebody
 880                this.frameBody = this.frameMC = oldFrameMC;
 881
 882                // Apply the new mc classes to the old mc element
 883                oldFrameMC.dom.className = newMCClassName;
 884
 885                // Remove the old framing
 886                if (wasTable) {
 887                    me.el.query('&gt; table')[1].remove();
 888                }
 889                else {
 890                    if (oldFrameTL) {
 891                        oldFrameTL.remove();
 892                    }
 893                    if (oldFrameBL) {
 894                        oldFrameBL.remove();
 895                    }
 896                    if (oldFrameML) {
 897                        oldFrameML.remove();
 898                    }
 899                }
 900            }
 901            else {
 902                // We were framed but not anymore. Move all content from the old frame to the body
 903
 904            }
 905        }
 906        else if (me.frame) {
 907            this.applyRenderSelectors();
 908        }
 909    },
 910
 911<span id='Ext-util-Renderable-method-getFrameInfo'>    /**
 912</span>     * @private
 913     * On render, reads an encoded style attribute, &quot;background-position&quot; from the style of this Component's element.
 914     * This information is memoized based upon the CSS class name of this Component's element.
 915     * Because child Components are rendered as textual HTML as part of the topmost Container, a dummy div is inserted
 916     * into the document to receive the document element's CSS class name, and therefore style attributes.
 917     */
 918    getFrameInfo: function() {
 919        // If native framing can be used, or this Component is not configured (or written) to be framed,
 920        // then do not attempt to read CSS framing info.
 921        if (Ext.supports.CSS3BorderRadius) {
 922            return false;
 923        }
 924
 925        var me = this,
 926            frameInfoCache = me.frameInfoCache,
 927            el = me.el || me.protoEl,
 928            cls = el.dom ? el.dom.className : el.classList.join(' '),
 929            frameInfo = frameInfoCache[cls],
 930            styleEl, left, top, info;
 931
 932        if (frameInfo == null) {
 933            // Get the singleton frame style proxy with our el class name stamped into it.
 934            styleEl = Ext.fly(me.getStyleProxy(cls), 'frame-style-el');
 935            left = styleEl.getStyle('background-position-x');
 936            top = styleEl.getStyle('background-position-y');
 937
 938            // Some browsers don't support background-position-x and y, so for those
 939            // browsers let's split background-position into two parts.
 940            if (!left &amp;&amp; !top) {
 941                info = styleEl.getStyle('background-position').split(' ');
 942                left = info[0];
 943                top = info[1];
 944            }
 945
 946            frameInfo = me.calculateFrame(left, top);
 947
 948            if (frameInfo) {
 949                // Just to be sure we set the background image of the el to none.
 950                el.setStyle('background-image', 'none');
 951            }
 952
 953            //&lt;debug error&gt;
 954            // This happens when you set frame: true explicitly without using the x-frame mixin in sass.
 955            // This way IE can't figure out what sizes to use and thus framing can't work.
 956            if (me.frame === true &amp;&amp; !frameInfo) {
 957                Ext.log.error('You have set frame: true explicity on this component (' + me.getXType() + ') and it ' +
 958                        'does not have any framing defined in the CSS template. In this case IE cannot figure out ' +
 959                        'what sizes to use and thus framing on this component will be disabled.');
 960            }
 961            //&lt;/debug&gt;
 962
 963            frameInfoCache[cls] = frameInfo;
 964        }
 965
 966        me.frame = !!frameInfo;
 967        me.frameSize = frameInfo;
 968
 969        return frameInfo;
 970    },
 971    
 972    calculateFrame: function(left, top){
 973        // We actually pass a string in the form of '[type][tl][tr]px [direction][br][bl]px' as
 974        // the background position of this.el from the CSS to indicate to IE that this component needs
 975        // framing. We parse it here.
 976        if (!(parseInt(left, 10) &gt;= 1000000 &amp;&amp; parseInt(top, 10) &gt;= 1000000)) {
 977            return false;
 978        }
 979        var max = Math.max,
 980            tl = parseInt(left.substr(3, 2), 10),
 981            tr = parseInt(left.substr(5, 2), 10),
 982            br = parseInt(top.substr(3, 2), 10),
 983            bl = parseInt(top.substr(5, 2), 10),
 984            frameInfo = {
 985                // Table markup starts with 110, div markup with 100.
 986                table: left.substr(0, 3) == '110',
 987
 988                // Determine if we are dealing with a horizontal or vertical component
 989                vertical: top.substr(0, 3) == '110',
 990
 991                // Get and parse the different border radius sizes
 992                top:    max(tl, tr),
 993                right:  max(tr, br),
 994                bottom: max(bl, br),
 995                left:   max(tl, bl)
 996            };
 997
 998        frameInfo.maxWidth = max(frameInfo.top, frameInfo.right, frameInfo.bottom, frameInfo.left);
 999        frameInfo.width = frameInfo.left + frameInfo.right;
1000        frameInfo.height = frameInfo.top + frameInfo.bottom;
1001        return frameInfo;
1002    },
1003
1004<span id='Ext-util-Renderable-method-getStyleProxy'>    /**
1005</span>     * @private
1006     * Returns an offscreen div with the same class name as the element this is being rendered.
1007     * This is because child item rendering takes place in a detached div which, being ot part of the document, has no styling.
1008     */
1009    getStyleProxy: function(cls) {
1010        var result = this.styleProxyEl || (Ext.AbstractComponent.prototype.styleProxyEl = Ext.getBody().createChild({
1011                style: {
1012                    position: 'absolute',
1013                    top: '-10000px'
1014                }
1015            }, null, true));
1016
1017        result.className = cls;
1018        return result;
1019    },
1020
1021    getFramePositions: function(frameInfo) {
1022        var me = this,
1023            frameWidth = frameInfo.maxWidth,
1024            dock = me.dock,
1025            positions, tc, bc, ml, mr;
1026
1027        if (frameInfo.vertical) {
1028            tc = '0 -' + (frameWidth * 0) + 'px';
1029            bc = '0 -' + (frameWidth * 1) + 'px';
1030
1031            if (dock &amp;&amp; dock == &quot;right&quot;) {
1032                tc = 'right -' + (frameWidth * 0) + 'px';
1033                bc = 'right -' + (frameWidth * 1) + 'px';
1034            }
1035
1036            positions = {
1037                tl: '0 -' + (frameWidth * 0) + 'px',
1038                tr: '0 -' + (frameWidth * 1) + 'px',
1039                bl: '0 -' + (frameWidth * 2) + 'px',
1040                br: '0 -' + (frameWidth * 3) + 'px',
1041
1042                ml: '-' + (frameWidth * 1) + 'px 0',
1043                mr: 'right 0',
1044
1045                tc: tc,
1046                bc: bc
1047            };
1048        } else {
1049            ml = '-' + (frameWidth * 0) + 'px 0';
1050            mr = 'right 0';
1051
1052            if (dock &amp;&amp; dock == &quot;bottom&quot;) {
1053                ml = 'left bottom';
1054                mr = 'right bottom';
1055            }
1056
1057            positions = {
1058                tl: '0 -' + (frameWidth * 2) + 'px',
1059                tr: 'right -' + (frameWidth * 3) + 'px',
1060                bl: '0 -' + (frameWidth * 4) + 'px',
1061                br: 'right -' + (frameWidth * 5) + 'px',
1062
1063                ml: ml,
1064                mr: mr,
1065
1066                tc: '0 -' + (frameWidth * 0) + 'px',
1067                bc: '0 -' + (frameWidth * 1) + 'px'
1068            };
1069        }
1070
1071        return positions;
1072    },
1073
1074<span id='Ext-util-Renderable-method-getFrameTpl'>    /**
1075</span>     * @private
1076     */
1077    getFrameTpl : function(table) {
1078        return this.getTpl(table ? 'frameTableTpl' : 'frameTpl');
1079    },
1080
1081    // Cache the frame information object so as not to cause style recalculations
1082    frameInfoCache: {}
1083});
1084</pre>
1085</body>
1086</html>