| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708 | <!DOCTYPE html><html><head>  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  <title>The source code</title>  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>  <style type="text/css">    .highlight { display: block; background-color: #ddd; }  </style>  <script type="text/javascript">    function highlight() {      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";    }  </script></head><body onload="prettyPrint(); highlight();">  <pre class="prettyprint lang-js"><span id='Ext-layout-ContextItem'>/**</span> * This class manages state information for a component or element during a layout. *  * # Blocks * * A "block" is a required value that is preventing further calculation. When a layout has * encountered a situation where it cannot possibly calculate results, it can associate * itself with the context item and missing property so that it will not be rescheduled * until that property is set. *  * Blocks are a one-shot registration. Once the property changes, the block is removed. *  * Be careful with blocks. If *any* further calculations can be made, a block is not the * right choice. *  * # Triggers * * Whenever any call to {@link #getProp}, {@link #getDomProp}, {@link #hasProp} or * {@link #hasDomProp} is made, the current layout is automatically registered as being * dependent on that property in the appropriate state. Any changes to the property will * trigger the layout and it will be queued in the {@link Ext.layout.Context}. * * Triggers, once added, remain for the entire layout. Any changes to the property will * reschedule all unfinished layouts in their trigger set. * * @private */Ext.define('Ext.layout.ContextItem', {        requires: ['Ext.layout.ClassList'],    heightModel: null,    widthModel: null,    sizeModel: null,    boxChildren: null,    boxParent: null,    children: [],    dirty: null,    // The number of dirty properties    dirtyCount: 0,    hasRawContent: true,    isContextItem: true,    isTopLevel: false,    consumersContentHeight: 0,    consumersContentWidth: 0,    consumersContainerHeight: 0,    consumersContainerWidth: 0,    consumersHeight: 0,    consumersWidth: 0,    ownerCtContext: null,    remainingChildLayouts: 0,    remainingComponentChildLayouts: 0,    remainingContainerChildLayouts: 0,    // the current set of property values:    props: null,<span id='Ext-layout-ContextItem-property-state'>    /**</span>     * @property {Object} state     * State variables that are cleared when invalidated. Only applies to component items.     */    state: null,<span id='Ext-layout-ContextItem-property-wrapsComponent'>    /**</span>     * @property {Boolean} wrapsComponent     * True if this item wraps a Component (rather than an Element).     * @readonly     */    wrapsComponent: false,    constructor: function (config) {        var me = this,            el, ownerCt, ownerCtContext, sizeModel, target;        Ext.apply(me, config);        el = me.el;        me.id = el.id;        me.lastBox = el.lastBox;        // These hold collections of layouts that are either blocked or triggered by sets        // to our properties (either ASAP or after flushing to the DOM). All of them have        // the same structure:        //        //      me.blocks = {        //          width: {        //              'layout-1001': layout1001        //          }        //      }        //        // The property name is the primary key which yields an object keyed by layout id        // with the layout instance as the value. This prevents duplicate entries for one        // layout and gives O(1) access to the layout instance when we need to iterate and        // process them.        //         // me.blocks = {};        // me.domBlocks = {};        // me.domTriggers = {};        // me.triggers = {};        me.flushedProps = {};        me.props = {};        // the set of cached styles for the element:        me.styles = {};        target = me.target;        if (target.isComponent) {            me.wrapsComponent = true;            // These items are created top-down, so the ContextItem of our ownerCt should            // be available (if it is part of this layout run).            ownerCt = target.ownerCt;            if (ownerCt && (ownerCtContext = me.context.items[ownerCt.el.id])) {                me.ownerCtContext = ownerCtContext;            }            // If our ownerCtContext is in the run, it will have a SizeModel that we use to            // optimize the determination of our sizeModel.            me.sizeModel = sizeModel = target.getSizeModel(ownerCtContext &&                ownerCtContext.widthModel.pairsByHeightOrdinal[ownerCtContext.heightModel.ordinal]);            me.widthModel = sizeModel.width;            me.heightModel = sizeModel.height;            // NOTE: The initial determination of sizeModel is valid (thankfully) and is            // needed to cope with adding components to a layout run on-the-fly (e.g., in            // the menu overflow handler of a box layout). Since this is the case, we do            // not need to recompute the sizeModel in init unless it is a "full" init (as            // our ownerCt's sizeModel could have changed in that case).        }    },<span id='Ext-layout-ContextItem-method-init'>    /**</span>     * Clears all properties on this object except (perhaps) those not calculated by this     * component. This is more complex than it would seem because a layout can decide to     * invalidate its results and run the component's layouts again, but since some of the     * values may be calculated by the container, care must be taken to preserve those     * values.     *     * @param {Boolean} full True if all properties are to be invalidated, false to keep     * those calculated by the ownerCt.     * @return {Mixed} A value to pass as the first argument to {@link #initContinue}.     * @private     */    init: function (full, options) {        var me = this,            oldProps = me.props,            oldDirty = me.dirty,            ownerCtContext = me.ownerCtContext,            ownerLayout = me.target.ownerLayout,            firstTime = !me.state,            ret = full || firstTime,            children, i, n, ownerCt, sizeModel, target,            oldHeightModel = me.heightModel,            oldWidthModel = me.widthModel,            newHeightModel, newWidthModel;        me.dirty = me.invalid = false;        me.props = {};        if (me.boxChildren) {            me.boxChildren.length = 0; // keep array (more GC friendly)        }        if (!firstTime) {            me.clearAllBlocks('blocks');            me.clearAllBlocks('domBlocks');        }        // For Element wrappers, we are done...        if (!me.wrapsComponent) {            return ret;        }        // From here on, we are only concerned with Component wrappers...        target = me.target;        me.state = {}; // only Component wrappers need a "state"        if (firstTime) {            // This must occur before we proceed since it can do many things (like add            // child items perhaps):            if (target.beforeLayout) {                target.beforeLayout();            }            // Determine the ownerCtContext if we aren't given one. Normally the firstTime            // we meet a component is before the context is run, but it is possible for            // components to be added to a run that is already in progress. If so, we have            // to lookup the ownerCtContext since the odds are very high that the new            // component is a child of something already in the run. It is currently            // unsupported to drag in the owner of a running component (needs testing).            if (!ownerCtContext && (ownerCt = target.ownerCt)) {                ownerCtContext = me.context.items[ownerCt.el.id];            }            if (ownerCtContext) {                me.ownerCtContext = ownerCtContext;                me.isBoxParent = target.ownerLayout.isItemBoxParent(me);            } else {                me.isTopLevel = true; // this is used by initAnimation...            }            me.frameBodyContext = me.getEl('frameBody');        } else {            ownerCtContext = me.ownerCtContext;            // In theory (though untested), this flag can change on-the-fly...            me.isTopLevel = !ownerCtContext;            // Init the children element items since they may have dirty state (no need to            // do this the firstTime).            children = me.children;            for (i = 0, n = children.length; i < n; ++i) {                children[i].init(true);            }        }        // We need to know how we will determine content size: containers can look at the        // results of their items but non-containers or item-less containers with just raw        // markup need to be measured in the DOM:        me.hasRawContent = !(target.isContainer && target.items.items.length > 0);        if (full) {            // We must null these out or getSizeModel will assume they are the correct,            // dynamic size model and return them (the previous dynamic sizeModel).            me.widthModel = me.heightModel = null;            sizeModel = target.getSizeModel(ownerCtContext &&                 ownerCtContext.widthModel.pairsByHeightOrdinal[ownerCtContext.heightModel.ordinal]);            if (firstTime) {                me.sizeModel = sizeModel;            }            me.widthModel = sizeModel.width;            me.heightModel = sizeModel.height;        } else if (oldProps) {            // these are almost always calculated by the ownerCt (we might need to track            // this at some point more carefully):            me.recoverProp('x', oldProps, oldDirty);            me.recoverProp('y', oldProps, oldDirty);            // if these are calculated by the ownerCt, don't trash them:            if (me.widthModel.calculated) {                me.recoverProp('width', oldProps, oldDirty);            }            if (me.heightModel.calculated) {                me.recoverProp('height', oldProps, oldDirty);            }        }        if (oldProps && ownerLayout && ownerLayout.manageMargins) {            me.recoverProp('margin-top', oldProps, oldDirty);            me.recoverProp('margin-right', oldProps, oldDirty);            me.recoverProp('margin-bottom', oldProps, oldDirty);            me.recoverProp('margin-left', oldProps, oldDirty);        }        // Process any invalidate options present. These can only come from explicit calls        // to the invalidate() method.        if (options) {            // Consider a container box with wrapping text. If the box is made wider, the            // text will take up less height (until there is no more wrapping). Conversely,            // if the box is made narrower, the height starts to increase due to wrapping.            //            // Imposing a minWidth constraint would increase the width. This may decrease            // the height. If the box is shrinkWrap, however, the width will already be            // such that there is no wrapping, so the height will not further decrease.            // Since the height will also not increase if we widen the box, there is no            // problem simultaneously imposing a minHeight or maxHeight constraint.            //            // When we impose as maxWidth constraint, however, we are shrinking the box            // which may increase the height. If we are imposing a maxHeight constraint,            // that is fine because a further increased height will still need to be            // constrained. But if we are imposing a minHeight constraint, we cannot know            // whether the increase in height due to wrapping will be greater than the            // minHeight. If we impose a minHeight constraint at the same time, then, we            // could easily be locking in the wrong height.            //            // It is important to note that this logic applies to simultaneously *adding*            // both a maxWidth and a minHeight constraint. It is perfectly fine to have            // a state with both constraints, but we cannot add them both at once.            newHeightModel = options.heightModel;            newWidthModel = options.widthModel;            if (newWidthModel && newHeightModel && oldWidthModel && oldHeightModel) {                if (oldWidthModel.shrinkWrap && oldHeightModel.shrinkWrap) {                    if (newWidthModel.constrainedMax && newHeightModel.constrainedMin) {                        newHeightModel = null;                    }                }            }            // Apply size model updates (if any) and state updates (if any).            if (newWidthModel) {                me.widthModel = newWidthModel;            }            if (newHeightModel) {                me.heightModel = newHeightModel;            }            if (options.state) {                Ext.apply(me.state, options.state);            }        }        return ret;    },<span id='Ext-layout-ContextItem-method-initContinue'>    /**</span>     * @private     */    initContinue: function (full) {        var me = this,            ownerCtContext = me.ownerCtContext,            widthModel = me.widthModel,            boxParent;        if (full) {            if (ownerCtContext && widthModel.shrinkWrap) {                boxParent = ownerCtContext.isBoxParent ? ownerCtContext : ownerCtContext.boxParent;                if (boxParent) {                    boxParent.addBoxChild(me);                }            } else if (widthModel.natural) {                me.boxParent = ownerCtContext;            }        }        return full;    },<span id='Ext-layout-ContextItem-method-initDone'>    /**</span>     * @private     */    initDone: function (full, componentChildrenDone, containerChildrenDone, containerLayoutDone) {        var me = this,            props = me.props,            state = me.state;        // These properties are only set when they are true:        if (componentChildrenDone) {            props.componentChildrenDone = true;        }        if (containerChildrenDone) {            props.containerChildrenDone = true;        }        if (containerLayoutDone) {            props.containerLayoutDone = true;        }        if (me.boxChildren && me.boxChildren.length && me.widthModel.shrinkWrap) {            // set a very large width to allow the children to measure their natural            // widths (this is cleared once all children have been measured):            me.el.setWidth(10000);            // don't run layouts for this component until we clear this width...            state.blocks = (state.blocks || 0) + 1;        }    },<span id='Ext-layout-ContextItem-method-initAnimation'>    /**</span>     * @private     */    initAnimation: function() {        var me = this,            target = me.target,            ownerCtContext = me.ownerCtContext;        if (ownerCtContext && ownerCtContext.isTopLevel) {            // See which properties we are supposed to animate to their new state.            // If there are any, queue ourself to be animated by the owning Context            me.animatePolicy = target.ownerLayout.getAnimatePolicy(me);        } else if (!ownerCtContext && target.isCollapsingOrExpanding && target.animCollapse) {            // Collapsing/expnding a top level Panel with animation. We need to fabricate            // an animatePolicy depending on which dimension the collapse is using,            // isCollapsingOrExpanding is set during the collapse/expand process.            me.animatePolicy = target.componentLayout.getAnimatePolicy(me);        }        if (me.animatePolicy) {            me.context.queueAnimation(me);        }    },    noFraming: { left: 0, top: 0, right: 0, bottom: 0, width: 0, height: 0 },<span id='Ext-layout-ContextItem-method-addCls'>    /**</span>     * Queue the addition of a class name (or array of class names) to this ContextItem's target when next flushed.     */    addCls: function(newCls) {        this.getClassList().addMany(newCls);    },<span id='Ext-layout-ContextItem-method-removeCls'>    /**</span>     * Queue the removal of a class name (or array of class names) from this ContextItem's target when next flushed.     */    removeCls: function(removeCls) {        this.getClassList().removeMany(removeCls);    },<span id='Ext-layout-ContextItem-method-addBlock'>    /**</span>     * Adds a block.     *      * @param {String} name The name of the block list ('blocks' or 'domBlocks').     * @param {Ext.layout.Layout} layout The layout that is blocked.     * @param {String} propName The property name that blocked the layout (e.g., 'width').     * @private     */    addBlock: function (name, layout, propName) {        var me = this,            collection = me[name] || (me[name] = {}),            blockedLayouts = collection[propName] || (collection[propName] = {});        if (!blockedLayouts[layout.id]) {            blockedLayouts[layout.id] = layout;            ++layout.blockCount;            ++me.context.blockCount;        }    },    addBoxChild: function (boxChildItem) {        var me = this,            children,            widthModel = boxChildItem.widthModel;        boxChildItem.boxParent = this;        // Children that are widthModel.auto (regardless of heightModel) that measure the        // DOM (by virtue of hasRawContent), need to wait for their "box parent" to be sized.        // If they measure too early, they will be wrong results. In the widthModel.shrinkWrap        // case, the boxParent "crushes" the child. In the case of widthModel.natural, the        // boxParent's width is likely a key part of the child's width (e.g., "50%" or just        // normal block-level behavior of 100% width)        boxChildItem.measuresBox = widthModel.shrinkWrap ? boxChildItem.hasRawContent : widthModel.natural;        if (boxChildItem.measuresBox) {            children = me.boxChildren;            if (children) {                children.push(boxChildItem);            } else {                me.boxChildren = [ boxChildItem ];            }        }    },<span id='Ext-layout-ContextItem-method-addTrigger'>    /**</span>     * Adds a trigger.     *      * @param {String} propName The property name that triggers the layout (e.g., 'width').     * @param {Boolean} inDom True if the trigger list is `domTriggers`, false if `triggers`.     * @private     */    addTrigger: function (propName, inDom) {        var me = this,            name = inDom ? 'domTriggers' : 'triggers',            collection = me[name] || (me[name] = {}),            context = me.context,            layout = context.currentLayout,            triggers = collection[propName] || (collection[propName] = {});        if (!triggers[layout.id]) {            triggers[layout.id] = layout;            ++layout.triggerCount;            triggers = context.triggers[inDom ? 'dom' : 'data'];            (triggers[layout.id] || (triggers[layout.id] = [])).push({                item: this,                prop: propName            });            if (me.props[propName] !== undefined) {                if (!inDom || !(me.dirty && (propName in me.dirty))) {                    ++layout.firedTriggers;                }            }        }    },    boxChildMeasured: function () {        var me = this,            state = me.state,            count = (state.boxesMeasured = (state.boxesMeasured || 0) + 1);        if (count == me.boxChildren.length) {            // all of our children have measured themselves, so we can clear the width            // and resume layouts for this component...            state.clearBoxWidth = 1;            ++me.context.progressCount;            me.markDirty();        }    },    borderNames: [ 'border-top-width', 'border-right-width', 'border-bottom-width', 'border-left-width'],    marginNames: [ 'margin-top', 'margin-right', 'margin-bottom', 'margin-left' ],    paddingNames: [ 'padding-top', 'padding-right', 'padding-bottom', 'padding-left' ],    trblNames: [ 'top', 'right', 'bottom', 'left' ],    cacheMissHandlers: {        borderInfo: function (me) {            var info = me.getStyles(me.borderNames, me.trblNames);            info.width = info.left + info.right;            info.height = info.top + info.bottom;            return info;        },        marginInfo: function (me) {            var info = me.getStyles(me.marginNames, me.trblNames);            info.width = info.left + info.right;            info.height = info.top + info.bottom;            return info;        },        paddingInfo: function (me) {            // if this context item's target is a framed component the padding is on the frameBody, not on the main el            var item = me.frameBodyContext || me,                info = item.getStyles(me.paddingNames, me.trblNames);            info.width = info.left + info.right;            info.height = info.top + info.bottom;            return info;        }    },    checkCache: function (entry) {        return this.cacheMissHandlers[entry](this);    },    clearAllBlocks: function (name) {        var collection = this[name],            propName;        if (collection) {            for (propName in collection) {                this.clearBlocks(name, propName);            }        }    },<span id='Ext-layout-ContextItem-method-clearBlocks'>    /**</span>     * Removes any blocks on a property in the specified set. Any layouts that were blocked     * by this property and are not still blocked (by other properties) will be rescheduled.     *      * @param {String} name The name of the block list ('blocks' or 'domBlocks').     * @param {String} propName The property name that blocked the layout (e.g., 'width').     * @private     */    clearBlocks: function (name, propName) {        var collection = this[name],            blockedLayouts = collection && collection[propName],            context, layout, layoutId;        if (blockedLayouts) {            delete collection[propName];            context = this.context;            for (layoutId in blockedLayouts) {                layout = blockedLayouts[layoutId];                --context.blockCount;                if (! --layout.blockCount && !layout.pending && !layout.done) {                    context.queueLayout(layout);                }            }        }    },<span id='Ext-layout-ContextItem-method-block'>    /**</span>     * Registers a layout in the block list for the given property. Once the property is     * set in the {@link Ext.layout.Context}, the layout is unblocked.     *      * @param {Ext.layout.Layout} layout     * @param {String} propName The property name that blocked the layout (e.g., 'width').     */    block: function (layout, propName) {        this.addBlock('blocks', layout, propName);    },<span id='Ext-layout-ContextItem-method-domBlock'>    /**</span>     * Registers a layout in the DOM block list for the given property. Once the property     * flushed to the DOM by the {@link Ext.layout.Context}, the layout is unblocked.     *      * @param {Ext.layout.Layout} layout     * @param {String} propName The property name that blocked the layout (e.g., 'width').     */    domBlock: function (layout, propName) {        this.addBlock('domBlocks', layout, propName);    },<span id='Ext-layout-ContextItem-method-fireTriggers'>    /**</span>     * Reschedules any layouts associated with a given trigger.     *      * @param {String} name The name of the trigger list ('triggers' or 'domTriggers').     * @param {String} propName The property name that triggers the layout (e.g., 'width').     * @private     */    fireTriggers: function (name, propName) {        var collection = this[name],            triggers = collection && collection[propName],            context = this.context,            layout, layoutId;        if (triggers) {            for (layoutId in triggers) {                layout = triggers[layoutId];                ++layout.firedTriggers;                if (!layout.done && !layout.blockCount && !layout.pending) {                    context.queueLayout(layout);                }            }        }    },<span id='Ext-layout-ContextItem-method-flush'>    /**</span>     * Flushes any updates in the dirty collection to the DOM. This is only called if there     * are dirty entries because this object is only added to the flushQueue of the     * {@link Ext.layout.Context} when entries become dirty.     */    flush: function () {        var me = this,            dirty = me.dirty,            state = me.state,            targetEl = me.el;        me.dirtyCount = 0;        // Flush added/removed classes        if (me.classList && me.classList.dirty) {            me.classList.flush();        }        // Set any queued DOM attributes        if ('attributes' in me) {            targetEl.set(me.attributes);            delete me.attributes;        }        // Set any queued DOM HTML content        if ('innerHTML' in me) {            targetEl.innerHTML = me.innerHTML;            delete me.innerHTML;        }        if (state && state.clearBoxWidth) {            state.clearBoxWidth = 0;            me.el.setStyle('width', null);            if (! --state.blocks) {                me.context.queueItemLayouts(me);            }        }        if (dirty) {            delete me.dirty;            me.writeProps(dirty, true);        }    },<span id='Ext-layout-ContextItem-method-flushAnimations'>    /**</span>     * @private     */    flushAnimations: function() {        var me = this,            animateFrom = me.lastBox,            target, targetAnim, duration, animateProps, anim,            changeCount, j, propsLen, propName, oldValue, newValue;        // Only animate if the Component has been previously layed out: first layout should not animate        if (animateFrom) {            target = me.target;            targetAnim = target.layout && target.layout.animate;            if (targetAnim) {                duration = Ext.isNumber(targetAnim) ? targetAnim : targetAnim.duration;            }            animateProps = Ext.Object.getKeys(me.animatePolicy);            // Create an animation block using the targetAnim configuration to provide defaults.            // They may want custom duration, or easing, or listeners.            anim = Ext.apply({}, {                from: {},                to: {},                duration: duration || Ext.fx.Anim.prototype.duration            }, targetAnim);            for (changeCount = 0, j = 0, propsLen = animateProps.length; j < propsLen; j++) {                propName = animateProps[j];                oldValue = animateFrom[propName];                newValue = me.peek(propName);                if (oldValue != newValue) {                    propName = me.translateProps[propName]||propName;                    anim.from[propName] = oldValue;                    anim.to[propName] = newValue;                    ++changeCount;                }            }            // If any values have changed, kick off animation from the cached old values to the new values            if (changeCount) {                // It'a Panel being collapsed. rollback, and then fix the class name string                if (me.isCollapsingOrExpanding === 1) {                    target.componentLayout.undoLayout(me);                }                // Otherwise, undo just the animated properties so the animation can proceed from the old layout.                else {                    me.writeProps(anim.from);                }                me.el.animate(anim);                                Ext.fx.Manager.getFxQueue(me.el.id)[0].on({                    afteranimate: function() {                        if (me.isCollapsingOrExpanding === 1) {                            target.componentLayout.redoLayout(me);                            target.afterCollapse(true);                        } else if (me.isCollapsingOrExpanding === 2) {                            target.afterExpand(true);                        }                    }                });            }        }    },<span id='Ext-layout-ContextItem-method-getBorderInfo'>    /**</span>     * Gets the border information for the element as an object with left, top, right and     * bottom properties holding border size in pixels. This object is only read from the     * DOM on first request and is cached.     * @return {Object}     */    getBorderInfo: function () {        var me = this,            info = me.borderInfo;        if (!info) {            me.borderInfo = info = me.checkCache('borderInfo');        }        return info;    },<span id='Ext-layout-ContextItem-method-getClassList'>    /**</span>     * Returns a ClassList-like object to buffer access to this item's element's classes.     */    getClassList: function () {        return this.classList || (this.classList = new Ext.layout.ClassList(this));    },<span id='Ext-layout-ContextItem-method-getEl'>    /**</span>     * Returns the context item for an owned element. This should only be called on a     * component's item. The list of child items is used to manage invalidating calculated     * results.     */    getEl: function (nameOrEl, owner) {        var me = this,            src, el, elContext;        if (nameOrEl) {            if (nameOrEl.dom) {                el = nameOrEl;            } else {                src = me.target;                if (owner) {                    src = owner;                }                el = src[nameOrEl];                if (typeof el == 'function') { // ex 'getTarget'                    el = el.call(src);                    if (el === me.el) {                        return this; // comp.getTarget() often returns comp.el                    }                }            }            if (el) {                elContext = me.context.getEl(me, el);            }        }        return elContext || null;    },    getFraming: function () {        var me = this;        if (!me.framingInfo) {            me.framingInfo = me.target.frameSize || me.noFraming;        }        return me.framingInfo;    },<span id='Ext-layout-ContextItem-method-getFrameInfo'>    /**</span>     * Gets the "frame" information for the element as an object with left, top, right and     * bottom properties holding border+framing size in pixels. This object is calculated     * on first request and is cached.     * @return {Object}     */    getFrameInfo: function () {        var me = this,            info = me.frameInfo,            frame, border;        if (!info) {            frame = me.getFraming();            border = me.getBorderInfo();                        me.frameInfo = info = {                top   : frame.top    + border.top,                right : frame.right  + border.right,                bottom: frame.bottom + border.bottom,                left  : frame.left   + border.left,                width : frame.width  + border.width,                height: frame.height + border.height            };        }        return info;    },<span id='Ext-layout-ContextItem-method-getMarginInfo'>    /**</span>     * Gets the margin information for the element as an object with left, top, right and     * bottom properties holding margin size in pixels. This object is only read from the     * DOM on first request and is cached.     * @return {Object}     */    getMarginInfo: function () {        var me = this,            info = me.marginInfo,            comp, manageMargins, margins, ownerLayout, ownerLayoutId;        if (!info) {            if (!me.wrapsComponent) {                info = me.checkCache('marginInfo');            } else {                comp = me.target;                ownerLayout = comp.ownerLayout;                ownerLayoutId = ownerLayout ? ownerLayout.id : null;                manageMargins = ownerLayout && ownerLayout.manageMargins;                // Option #1 for configuring margins on components is the "margin" config                // property. When supplied, this config is written to the DOM during the                // render process (see AbstractComponent#initStyles).                //                // Option #2 is available to some layouts (e.g., Box, Border, Fit) that                // handle margin calculations themselves. These layouts support a "margins"                // config property on their items and they have a "defaultMargins" config                // property. These margin values are added to the "natural" margins read                // from the DOM and 0's are written to the DOM after they are added.                // To avoid having to do all this on every layout, we cache the results on                // the component in the (private) "margin$" property. We identify the cache                // results as belonging to the appropriate ownerLayout in case items are                // moved around.                info = comp.margin$;                if (info && info.ownerId !== ownerLayoutId) {                    // got one but from the wrong owner                    info = null;                    //  if (manageMargins) {                    //      TODO: clear inline margins (the 0's we wrote last time)???                    //  }                }                if (!info) { // if (no cache)                    // CSS margins are only checked if there isn't a margin property on the component                    info = me.parseMargins(comp.margin) || me.checkCache('marginInfo');                    // Some layouts also support margins and defaultMargins, e.g. Fit, Border, Box                    if (manageMargins) {                        margins = me.parseMargins(comp.margins, ownerLayout.defaultMargins);                        if (margins) { // if (using 'margins' and/or 'defaultMargins')                            // margin and margins can both be present at the same time and must be combined                            info = {                                top:    info.top    + margins.top,                                right:  info.right  + margins.right,                                bottom: info.bottom + margins.bottom,                                left:   info.left   + margins.left                            };                        }                        me.setProp('margin-top', 0);                        me.setProp('margin-right', 0);                        me.setProp('margin-bottom', 0);                        me.setProp('margin-left', 0);                    }                    // cache the layout margins and tag them with the layout id:                    info.ownerId = ownerLayoutId;                    comp.margin$ = info;                }                info.width  = info.left + info.right;                info.height = info.top  + info.bottom;            }            me.marginInfo = info;        }        return info;    },<span id='Ext-layout-ContextItem-method-clearMarginCache'>    /**</span>     * clears the margin cache so that marginInfo get re-read from the dom on the next call to getMarginInfo()     * This is needed in some special cases where the margins have changed since the last layout, making the cached     * values invalid.  For example collapsed window headers have different margin than expanded ones.     */    clearMarginCache: function() {        delete this.marginInfo;        delete this.target.margin$;    },<span id='Ext-layout-ContextItem-method-getPaddingInfo'>    /**</span>     * Gets the padding information for the element as an object with left, top, right and     * bottom properties holding padding size in pixels. This object is only read from the     * DOM on first request and is cached.     * @return {Object}     */    getPaddingInfo: function () {        var me = this,            info = me.paddingInfo;        if (!info) {            me.paddingInfo = info = me.checkCache('paddingInfo');        }        return info;    },<span id='Ext-layout-ContextItem-method-getProp'>    /**</span>     * Gets a property of this object. Also tracks the current layout as dependent on this     * property so that changes to it will trigger the layout to be recalculated.     * @param {String} propName The property name that blocked the layout (e.g., 'width').     * @return {Object} The property value or undefined if not yet set.     */    getProp: function (propName) {        var me = this,            result = me.props[propName];        me.addTrigger(propName);        return result;    },<span id='Ext-layout-ContextItem-method-getDomProp'>    /**</span>     * Gets a property of this object if it is correct in the DOM. Also tracks the current     * layout as dependent on this property so that DOM writes of it will trigger the     * layout to be recalculated.     * @param {String} propName The property name (e.g., 'width').     * @return {Object} The property value or undefined if not yet set or is dirty.     */    getDomProp: function (propName) {        var me = this,            result = (me.dirty && (propName in me.dirty)) ? undefined : me.props[propName];        me.addTrigger(propName, true);        return result;    },<span id='Ext-layout-ContextItem-method-getStyle'>    /**</span>     * Returns a style for this item. Each style is read from the DOM only once on first     * request and is then cached. If the value is an integer, it is parsed automatically     * (so '5px' is not returned, but rather 5).     *     * @param {String} styleName The CSS style name.     * @return {Object} The value of the DOM style (parsed as necessary).     */    getStyle: function (styleName) {        var me = this,            styles = me.styles,            info, value;        if (styleName in styles) {            value = styles[styleName];        } else {            info = me.styleInfo[styleName];            value = me.el.getStyle(styleName);            if (info && info.parseInt) {                value = parseInt(value, 10) || 0;            }            styles[styleName] = value;        }        return value;    },<span id='Ext-layout-ContextItem-method-getStyles'>    /**</span>     * Returns styles for this item. Each style is read from the DOM only once on first     * request and is then cached. If the value is an integer, it is parsed automatically     * (so '5px' is not returned, but rather 5).     *     * @param {String[]} styleNames The CSS style names.     * @param {String[]} [altNames] The alternate names for the returned styles. If given,     * these names must correspond one-for-one to the `styleNames`.     * @return {Object} The values of the DOM styles (parsed as necessary).     */    getStyles: function (styleNames, altNames) {        var me = this,            styleCache = me.styles,            values = {},            hits = 0,            n = styleNames.length,            i, missing, missingAltNames, name, info, styleInfo, styles, value;        altNames = altNames || styleNames;        // We are optimizing this for all hits or all misses. If we hit on all styles, we        // don't create a missing[]. If we miss on all styles, we also don't create one.        for (i = 0; i < n; ++i) {            name = styleNames[i];            if (name in styleCache) {                values[altNames[i]] = styleCache[name];                ++hits;                if (i && hits==1) { // if (first hit was after some misses)                    missing = styleNames.slice(0, i);                    missingAltNames = altNames.slice(0, i);                }            } else if (hits) {                (missing || (missing = [])).push(name);                (missingAltNames || (missingAltNames = [])).push(altNames[i]);            }        }        if (hits < n) {            missing = missing || styleNames;            missingAltNames = missingAltNames || altNames;            styleInfo = me.styleInfo;            styles = me.el.getStyle(missing);            for (i = missing.length; i--; ) {                name = missing[i];                info = styleInfo[name];                value = styles[name];                if (info && info.parseInt) {                    value = parseInt(value, 10) || 0;                }                values[missingAltNames[i]] = value;                styleCache[name] = value;            }        }        return values;    },<span id='Ext-layout-ContextItem-method-hasProp'>    /**</span>     * Returns true if the given property has been set. This is equivalent to calling     * {@link #getProp} and not getting an undefined result. In particular, this call     * registers the current layout to be triggered by changes to this property.     *      * @param {String} propName The property name (e.g., 'width').     * @return {Boolean}     */    hasProp: function (propName) {        var value = this.getProp(propName);        return typeof value != 'undefined';    },<span id='Ext-layout-ContextItem-method-hasDomProp'>    /**</span>     * Returns true if the given property is correct in the DOM. This is equivalent to     * calling {@link #getDomProp} and not getting an undefined result. In particular,     * this call registers the current layout to be triggered by flushes of this property.     *      * @param {String} propName The property name (e.g., 'width').     * @return {Boolean}     */    hasDomProp: function (propName) {        var value = this.getDomProp(propName);        return typeof value != 'undefined';    },<span id='Ext-layout-ContextItem-method-invalidate'>    /**</span>     * Invalidates the component associated with this item. The layouts for this component     * and all of its contained items will be re-run after first clearing any computed     * values.     *      * If state needs to be carried forward beyond the invalidation, the `options` parameter     * can be used.     *     * @param {Object} options An object describing how to handle the invalidation.     * @param {Object} options.state An object to {@link Ext#apply} to the {@link #state}     *  of this item after invalidation clears all other properties.     * @param {Function} options.before A function to call after the context data is cleared     * and before the {@link Ext.layout.Layout#beginLayoutCycle} methods are called.     * @param {Ext.layout.ContextItem} options.before.item This ContextItem.     * @param {Object} options.before.options The options object passed to {@link #invalidate}.     * @param {Function} options.after A function to call after the context data is cleared     * and after the {@link Ext.layout.Layout#beginLayoutCycle} methods are called.     * @param {Ext.layout.ContextItem} options.after.item This ContextItem.     * @param {Object} options.after.options The options object passed to {@link #invalidate}.     * @param {Object} options.scope The scope to use when calling the callback functions.     */    invalidate: function (options) {        this.context.queueInvalidate(this, options);    },    markDirty: function () {        if (++this.dirtyCount == 1) {            // our first dirty property... queue us for flush            this.context.queueFlush(this);        }    },    onBoxMeasured: function () {        var boxParent = this.boxParent,            state = this.state;        if (boxParent && boxParent.widthModel.shrinkWrap && !state.boxMeasured && this.measuresBox) {            // since an autoWidth boxParent is holding a width on itself to allow each            // child to measure            state.boxMeasured = 1; // best to only call once per child            boxParent.boxChildMeasured();        }    },    parseMargins: function (margins, defaultMargins) {        if (margins === true) {            margins = 5;        }        var type = typeof margins,            ret;        if (type == 'string' || type == 'number') {            ret = Ext.util.Format.parseBox(margins);        } else if (margins || defaultMargins) {            ret = { top: 0, right: 0, bottom: 0, left: 0 }; // base defaults            if (defaultMargins) {                Ext.apply(ret, this.parseMargins(defaultMargins)); // + layout defaults            }            Ext.apply(ret, margins); // + config        }        return ret;    },    peek: function (propName) {        return this.props[propName];    },<span id='Ext-layout-ContextItem-method-recoverProp'>    /**</span>     * Recovers a property value from the last computation and restores its value and     * dirty state.     *      * @param {String} propName The name of the property to recover.     * @param {Object} oldProps The old "props" object from which to recover values.     * @param {Object} oldDirty The old "dirty" object from which to recover state.     */    recoverProp: function (propName, oldProps, oldDirty) {        var me = this,            props = me.props,            dirty;        if (propName in oldProps) {            props[propName] = oldProps[propName];            if (oldDirty && propName in oldDirty) {                dirty = me.dirty || (me.dirty = {});                dirty[propName] = oldDirty[propName];            }        }    },    redo: function(deep) {        var me = this,            items, len, i;        me.revertProps(me.props);        if (deep && me.wrapsComponent) {            // Rollback the state of child Components            if (me.childItems) {                for (i = 0, items = me.childItems, len = items.length; i < len; i++) {                    items[i].redo(deep);                }            }            // Rollback the state of child Elements            for (i = 0, items = me.children, len = items.length; i < len; i++) {                items[i].redo();            }        }    },    revertProps: function (props) {        var name,            flushed = this.flushedProps,            reverted = {};        for (name in props) {            if (flushed.hasOwnProperty(name)) {                reverted[name] = props[name];            }        }        this.writeProps(reverted);    },<span id='Ext-layout-ContextItem-method-setAttribute'>    /**</span>     * Queue the setting of a DOM attribute on this ContextItem's target when next flushed.     */    setAttribute: function(name, value) {        var me = this;        if (!me.attributes) {            me.attributes = {};        }        me.attributes[name] = value;        me.markDirty();    },    setBox: function (box) {        var me = this;        if ('left' in box) {            me.setProp('x', box.left);        }        if ('top' in box) {            me.setProp('y', box.top);        }        // if sizeModel says we should not be setting these, the appropriate calls will be        // null operations... otherwise, we must set these values, so what we have in box        // is what we go with (undefined, NaN and no change are handled at a lower level):        me.setSize(box.width, box.height);    },<span id='Ext-layout-ContextItem-method-setContentHeight'>    /**</span>     * Sets the contentHeight property. If the component uses raw content, then only the     * measured height is acceptable.     *     * Calculated values can sometimes be NaN or undefined, which generally mean the     * calculation is not done. To indicate that such as value was passed, 0 is returned.     * Otherwise, 1 is returned.     *     * If the caller is not measuring (i.e., they are calculating) and the component has raw     * content, 1 is returned indicating that the caller is done.     */    setContentHeight: function (height, measured) {        if (!measured && this.hasRawContent) {            return 1;        }        return this.setProp('contentHeight', height);    },<span id='Ext-layout-ContextItem-method-setContentWidth'>    /**</span>     * Sets the contentWidth property. If the component uses raw content, then only the     * measured width is acceptable.     *      * Calculated values can sometimes be NaN or undefined, which generally means that the     * calculation is not done. To indicate that such as value was passed, 0 is returned.     * Otherwise, 1 is returned.     *     * If the caller is not measuring (i.e., they are calculating) and the component has raw     * content, 1 is returned indicating that the caller is done.     */    setContentWidth: function (width, measured) {        if (!measured && this.hasRawContent) {            return 1;        }        return this.setProp('contentWidth', width);    },<span id='Ext-layout-ContextItem-method-setContentSize'>    /**</span>     * Sets the contentWidth and contentHeight properties. If the component uses raw content,     * then only the measured values are acceptable.     *      * Calculated values can sometimes be NaN or undefined, which generally means that the     * calculation is not done. To indicate that either passed value was such a value, false     * returned. Otherwise, true is returned.     *     * If the caller is not measuring (i.e., they are calculating) and the component has raw     * content, true is returned indicating that the caller is done.     */    setContentSize: function (width, height, measured) {        return this.setContentWidth(width, measured) +               this.setContentHeight(height, measured) == 2;    },<span id='Ext-layout-ContextItem-method-setProp'>    /**</span>     * Sets a property value. This will unblock and/or trigger dependent layouts if the     * property value is being changed. Values of NaN and undefined are not accepted by     * this method.     *      * @param {String} propName The property name (e.g., 'width').     * @param {Object} value The new value of the property.     * @param {Boolean} dirty Optionally specifies if the value is currently in the DOM     *  (default is `true` which indicates the value is not in the DOM and must be flushed     *  at some point).     * @return {Number} 1 if this call specified the property value, 0 if not.     */    setProp: function (propName, value, dirty) {        var me = this,            valueType = typeof value,            borderBox, info;        if (valueType == 'undefined' || (valueType === 'number' && isNaN(value))) {            return 0;        }        if (me.props[propName] === value) {            return 1;        }        me.props[propName] = value;        ++me.context.progressCount;        if (dirty === false) {            // if the prop is equivalent to what is in the DOM (we won't be writing it),            // we need to clear hard blocks (domBlocks) on that property.            me.fireTriggers('domTriggers', propName);            me.clearBlocks('domBlocks', propName);        } else {            info = me.styleInfo[propName];            if (info) {                if (!me.dirty) {                    me.dirty = {};                }                if (propName == 'width' || propName == 'height') {                    borderBox = me.isBorderBoxValue;                    if (borderBox == null) {                        me.isBorderBoxValue = borderBox = !!me.el.isBorderBox();                    }                    if (!borderBox) {                        me.borderInfo || me.getBorderInfo();                        me.paddingInfo || me.getPaddingInfo();                    }                }                me.dirty[propName] = value;                me.markDirty();            }        }        // we always clear soft blocks on set        me.fireTriggers('triggers', propName);        me.clearBlocks('blocks', propName);        return 1;    },<span id='Ext-layout-ContextItem-method-setHeight'>    /**</span>     * Sets the height and constrains the height to min/maxHeight range.     *      * @param {Number} height The height.     * @param {Boolean} [dirty=true] Specifies if the value is currently in the DOM. A     * value of `false` indicates that the value is already in the DOM.     * @return {Number} The actual height after constraining.     */    setHeight: function (height, dirty /*, private {Boolean} force */) {        var me = this,            comp = me.target,            frameBody, frameInfo, padding;        if (height < 0) {            height = 0;        }        if (!me.wrapsComponent) {            if (!me.setProp('height', height, dirty)) {                return NaN;            }        } else {            height = Ext.Number.constrain(height, comp.minHeight || 0, comp.maxHeight);            if (!me.setProp('height', height, dirty)) {                return NaN;            }            frameBody = me.frameBodyContext;            if (frameBody){                frameInfo = me.getFrameInfo();                frameBody.setHeight(height - frameInfo.height, dirty);            }        }        return height;    },<span id='Ext-layout-ContextItem-method-setWidth'>    /**</span>     * Sets the height and constrains the width to min/maxWidth range.     *      * @param {Number} width The width.     * @param {Boolean} [dirty=true] Specifies if the value is currently in the DOM. A     * value of `false` indicates that the value is already in the DOM.     * @return {Number} The actual width after constraining.     */    setWidth: function (width, dirty /*, private {Boolean} force */) {        var me = this,            comp = me.target,            frameBody, frameInfo, padding;        if (width < 0) {            width = 0;        }        if (!me.wrapsComponent) {            if (!me.setProp('width', width, dirty)) {                return NaN;            }        } else {            width = Ext.Number.constrain(width, comp.minWidth || 0, comp.maxWidth);            if (!me.setProp('width', width, dirty)) {                return NaN;            }            //if ((frameBody = me.target.frameBody) && (frameBody = me.getEl(frameBody))){            frameBody = me.frameBodyContext;            if (frameBody) {                frameInfo = me.getFrameInfo();                frameBody.setWidth(width - frameInfo.width, dirty);            }            /*if (owner.frameMC) {                frameContext = ownerContext.frameContext ||                        (ownerContext.frameContext = ownerContext.getEl('frameMC'));                width += (frameContext.paddingInfo || frameContext.getPaddingInfo()).width;            }*/        }        return width;    },    setSize: function (width, height, dirty) {        this.setWidth(width, dirty);        this.setHeight(height, dirty);    },    translateProps: {        x: 'left',        y: 'top'    },    undo: function(deep) {        var me = this,            items, len, i;        me.revertProps(me.lastBox);        if (deep && me.wrapsComponent) {            // Rollback the state of child Components            if (me.childItems) {                for (i = 0, items = me.childItems, len = items.length; i < len; i++) {                    items[i].undo(deep);                }            }            // Rollback the state of child Elements            for (i = 0, items = me.children, len = items.length; i < len; i++) {                items[i].undo();            }        }    },    unsetProp: function (propName) {        var dirty = this.dirty;        delete this.props[propName];        if (dirty) {            delete dirty[propName];        }    },    writeProps: function(dirtyProps, flushing) {        if (!(dirtyProps && typeof dirtyProps == 'object')) {            //<debug warn>            Ext.Logger.warn('writeProps expected dirtyProps to be an object');            //</debug>            return;        }        var me = this,            el = me.el,            styles = {},            styleCount = 0, // used as a boolean, the exact count doesn't matter            styleInfo = me.styleInfo,                        info,            propName,            numericValue,                        dirtyX = 'x' in dirtyProps,            dirtyY = 'y' in dirtyProps,            x = dirtyProps.x,            y = dirtyProps.y,                        width = dirtyProps.width,            height = dirtyProps.height,            isBorderBox = me.isBorderBoxValue,            target = me.target,            max = Math.max,            paddingWidth = 0,            paddingHeight = 0,            hasWidth, hasHeight, isAbsolute, scrollbarSize, style, targetEl;        // Process non-style properties:        if ('displayed' in dirtyProps) {            el.setDisplayed(dirtyProps.displayed);        }        // Unblock any hard blocks (domBlocks) and copy dom styles into 'styles'        for (propName in dirtyProps) {            if (flushing) {                me.fireTriggers('domTriggers', propName);                me.clearBlocks('domBlocks', propName);                me.flushedProps[propName] = 1;            }            info = styleInfo[propName];            if (info && info.dom) {                // Numeric dirty values should have their associated suffix added                if (info.suffix && (numericValue = parseInt(dirtyProps[propName], 10))) {                    styles[propName] = numericValue + info.suffix;                }                // Non-numeric (eg "auto") go in unchanged.                else {                    styles[propName] = dirtyProps[propName];                }                ++styleCount;            }        }        // convert x/y into setPosition (for a component) or left/top styles (for an el)        if (dirtyX || dirtyY) {            if (target.isComponent) {                // Ensure we always pass the current coordinate in if one coordinate has not been dirtied by a calculation cycle.                target.setPosition(x||me.props.x, y||me.props.y);            } else {                // we wrap an element, so convert x/y to styles:                if (dirtyX) {                    styles.left = x + 'px';                    ++styleCount;                }                if (dirtyY) {                    styles.top = y + 'px';                    ++styleCount;                }            }        }        // Support for the content-box box model...        if (!isBorderBox && (width > 0 || height > 0)) { // no need to subtract from 0            // The width and height values assume the border-box box model,            // so we must remove the padding & border to calculate the content-box.            //<debug>            if (!(me.borderInfo && me.paddingInfo)) {                throw Error("Needed to have gotten the borderInfo and paddingInfo when the width or height was setProp'd");            }            //</debug>            if(!me.frameBodyContext) {                // Padding needs to be removed only if the element is not framed.                paddingWidth = me.paddingInfo.width;                paddingHeight = me.paddingInfo.height;            }            if (width) {                width = max(parseInt(width, 10) - (me.borderInfo.width + paddingWidth), 0);                styles.width = width + 'px';                ++styleCount;            }            if (height) {                height = max(parseInt(height, 10) - (me.borderInfo.height + paddingHeight), 0);                styles.height = height + 'px';                ++styleCount;            }        }        // IE9 strict subtracts the scrollbar size from the element size when the element        // is absolutely positioned and uses box-sizing: border-box. To workaround this        // issue we have to add the the scrollbar size.        //         // See http://social.msdn.microsoft.com/Forums/da-DK/iewebdevelopment/thread/47c5148f-a142-4a99-9542-5f230c78cb3b        //        if (me.wrapsComponent && Ext.isIE9 && Ext.isStrict) {            // when we set a width and we have a vertical scrollbar (overflowY), we need            // to add the scrollbar width... conversely for the height and overflowX            if ((hasWidth = width !== undefined && me.hasOverflowY) ||                (hasHeight = height !== undefined && me.hasOverflowX)) {                // check that the component is absolute positioned and border-box:                isAbsolute = me.isAbsolute;                if (isAbsolute === undefined) {                    isAbsolute = false;                    targetEl = me.target.getTargetEl();                    style = targetEl.getStyle('position');                    if (style == 'absolute') {                        style = targetEl.getStyle('box-sizing');                        isAbsolute = (style == 'border-box');                    }                    me.isAbsolute = isAbsolute; // cache it                }                if (isAbsolute) {                    scrollbarSize = Ext.getScrollbarSize();                    if (hasWidth) {                        width = parseInt(width, 10) + scrollbarSize.width;                        styles.width = width + 'px';                        ++styleCount;                    }                    if (hasHeight) {                        height = parseInt(height, 10) + scrollbarSize.height;                        styles.height = height + 'px';                        ++styleCount;                    }                }            }        }        // we make only one call to setStyle to allow it to optimize itself:        if (styleCount) {            el.setStyle(styles);        }    }}, function () {        var px =    { dom: true, parseInt: true, suffix: 'px' },        isDom = { dom: true },        faux =  { dom: false };    // If a property exists in styleInfo, it participates in some way with the DOM. It may    // be virtualized (like 'x' and y') and be indirect, but still requires a flush cycle    // to reach the DOM. Properties (like 'contentWidth' and 'contentHeight') have no real    // presence in the DOM and hence have no flush intanglements.    //     // For simple styles, the object value on the right contains properties that help in    // decoding values read by getStyle and preparing values to pass to setStyle.    //    this.prototype.styleInfo = {        childrenDone:           faux,        componentChildrenDone:  faux,        containerChildrenDone:  faux,        containerLayoutDone:    faux,        displayed:              faux,        done:                   faux,        x:                      faux,        y:                      faux,        // For Ext.grid.ColumnLayout        columnWidthsDone:       faux,        left:                   px,        top:                    px,        right:                  px,        bottom:                 px,        width:                  px,        height:                 px,        'border-top-width':     px,        'border-right-width':   px,        'border-bottom-width':  px,        'border-left-width':    px,        'margin-top':           px,        'margin-right':         px,        'margin-bottom':        px,        'margin-left':          px,        'padding-top':          px,        'padding-right':        px,        'padding-bottom':       px,        'padding-left':         px,        'line-height':          isDom,        display:                isDom    };});</pre></body></html>
 |