var _hooking = 3, _layoutRuns = [] _syncStatusCheck = function () { _hooking--; }; Ext.require([ 'Ext.perf.Monitor', 'Ext.perf.Accumulator' ], function(){ if (typeof _accumulatorCfg != 'undefined') { Ext.Perf.setup(_accumulatorCfg); } _syncStatusCheck(); } ) Ext.define('PageAnalyzer.hook.Context', function () { function compareTriggers (a, b) { if (a.value === undefined) { if (b.value !== undefined) { return -1; } } else if (b.value === undefined) { return 1; } return a.name < b.name ? -1 : (b.name < a.name ? 1 : 0); } function getLayoutName (layout) { return layout.owner.id + '<' + layout.type + '>'; } function getLayoutResults (me, layout, reported, orphan) { var owner = layout.owner, ownerContext = me.getCmp(owner), sizeModel = ownerContext.sizeModel, stats = me.layoutsById[layout.id], results = { allDone: layout.done, done: layout.done, id: layout.id, type: layout.type, name: getLayoutName(layout), blocks: [], boxParent: ownerContext.boxParent ? ownerContext.boxParent.id : null, isBoxParent: ownerContext.isBoxParent, triggers: [], orphan: !!orphan, heightModel: ownerContext.heightModel.name, widthModel: ownerContext.widthModel.name, children: [], duration: stats ? stats.duration : 0, totalTime: stats ? stats.duration : 0, count: stats ? stats.count : 1 }, order = [false, true], child, i; reported[layout.id] = true; if (results.heightModel != sizeModel.height.name) { results.heightModel += ' (' + sizeModel.height.name + ')'; } if (results.widthModel != sizeModel.width.name) { results.widthModel += ' (' + sizeModel.width.name + ')'; } Ext.Object.each(layout.blockedBy, function (t) { results.blocks.push(t); }); Ext.Object.each(me.triggersByLayoutId[layout.id], function (name, info) { var item = info.item, dirty = item.dirty || false, prop = info.name, value = item.props[prop]; results.triggers.push({ name: name, prop: prop, value: value, dirty: dirty && (prop in dirty), missing: value === undefined, setBy: (item.setBy && item.setBy[prop]) || '??' }); }); results.blocks.sort(); results.triggers.sort(compareTriggers); for (i = 0; i < 2; ++i) { Ext.Object.each(me.layouts, function (id, childLayout) { if (childLayout.done === order[i] && childLayout.owner.ownerLayout === layout) { child = getLayoutResults(me, childLayout, reported); if (!child.allDone) { results.allDone = false; } results.totalTime += child.totalTime; results.children.push(child); } }); } return results; } function beforeRun (me) { me.calcsByType = {}; me.numByType = {}; me.timesByType = {}; me.triggersByLayoutId = {}; me.layoutsById = {}; me.layoutsByType = {}; me.flushLayoutStats = {}; return { startTime: Ext.perf.getTimestamp() }; } function afterRun (me, before, ok) { var t2 = new Date(), reported = {}; var data = { duration: Ext.perf.getTimestamp() - before.startTime, time: t2, success: ok, cycleCount: me.cycleCount, flushCount: me.flushCount, calcCount: me.calcCount, orphans: 0, layouts: [], statsById: me.layoutsById, statsByType: me.layoutsByType, flushTime: me.flushTime, flushInvalidateTime: me.flushInvalidateTime, flushCount: me.flushCount, flushInvalidateCount: me.flushInvalidateCount, flushLayoutStats: me.flushLayoutStats }; data.totalTime = data.duration; Ext.Object.each(me.layouts, function (id, layout) { if (me.items[layout.owner.el.id].isTopLevel) { data.layouts.push(getLayoutResults(me, layout, reported)); } }); Ext.Object.each(me.layouts, function (id, layout) { if (!reported[layout.id]) { ++data.orphans; data.layouts.push(getLayoutResults(me, layout, reported, true)); } }); _layoutRuns.push(Ext.encode(data)); } function beforeRunLayout (me) { return { startTime: Ext.perf.getTimestamp() }; } function afterRunLayout (me, layout, before) { var id = layout.id, type = layout.type, duration = Ext.perf.getTimestamp() - before.startTime, typeMapping = me.layoutsByType[type] || (me.layoutsByType[type] = { duration: 0, layoutCount: 0, count: 0 }), idMapping = me.layoutsById[id]; if(!idMapping) { typeMapping.layoutCount++; idMapping = me.layoutsById[id] = { duration: 0, count: 0 }; } idMapping.duration += duration; typeMapping.duration += duration; idMapping.count++; typeMapping.count++; } return { override: 'Ext.layout.Context', flushInvalidateTime: 0, flushInvalidateCount: 0, flushTime: 0, flushCount: 0, flush: function() { var start = Ext.perf.getTimestamp(); this.callParent(arguments); this.flushTime += Ext.perf.getTimestamp() - start; this.flushCount++; }, flushInvalidates: function() { var start = Ext.perf.getTimestamp(); this.callParent(arguments); this.flushInvalidateTime += Ext.perf.getTimestamp() - start; this.flushInvalidateCount++; }, flushLayouts: function (queueName, methodName, dontClear) { var start = Ext.perf.getTimestamp(), stats = this.flushLayoutStats[methodName] || (this.flushLayoutStats[methodName] = { count: 0, time: 0 }); this.callParent(arguments); stats.time += Ext.perf.getTimestamp() - start; stats.count++; }, run: function () { var me = this, before = beforeRun(me), ok = me.callParent(arguments); afterRun(me, before, ok); return ok; }, runLayout: function (layout) { var me = this, before = beforeRunLayout(me); me.callParent(arguments); afterRunLayout(me, layout, before); } }; }(), _syncStatusCheck); //----------------------------------------------------------------------------- Ext.define('PageAnalyzer.hook.ContextItem', function () { function getLayoutName (layout) { return layout.owner.id + '<' + layout.type + '>'; } return { override: 'Ext.layout.ContextItem', addBlock: function (name, layout, propName) { //Ext.log(this.id,'.',propName,' ',name,': ',getLayoutName(layout)); (layout.blockedBy || (layout.blockedBy = {}))[ this.id+'.'+propName+(name.substring(0,3)=='dom' ? ':dom' : '')] = 1; return this.callParent(arguments); }, addBoxChild: function (boxChildItem) { var ret = this.callParent(arguments), boxChildren = this.boxChildren, boxParents; if (boxChildren && boxChildren.length == 1) { // the boxParent collection is created by the run override found in // Ext.diag.layout.Context, but IE sometimes does not load that override, so // we work around it for now boxParents = this.context.boxParents || (this.context.boxParents = new Ext.util.MixedCollection()); boxParents.add(this); } return ret; }, addTrigger: function (propName, inDom) { var layout = this.context.currentLayout, triggers; this.callParent(arguments); //Ext.log(this.id,'.',propName,' ',name = inDom ? ':dom' : '',' ',getLayoutName(layout)); triggers = this.context.triggersByLayoutId; (triggers[layout.id] || (triggers[layout.id] = {}))[ this.id+'.'+propName+(inDom ? ':dom' : '')] = { item: this, name: propName }; }, clearBlocks: function (name, propName) { var collection = this[name], blockedLayouts = collection && collection[propName], key = this.id+'.'+propName+(name.substring(0,3)=='dom' ? ':dom' : ''), layout, layoutId; if (blockedLayouts) { for (layoutId in blockedLayouts) { layout = blockedLayouts[layoutId]; delete layout.blockedBy[key]; } } return this.callParent(arguments); }, setProp: function (propName, value, dirty) { var me = this, layout = me.context.currentLayout, setBy = getLayoutName(layout), //fullName = me.id + '.' + propName, setByProps; if (value !== null) { setByProps = me.setBy || (me.setBy = {}); if (!setByProps[propName]) { setByProps[propName] = setBy; } else if (setByProps[propName] != setBy) { //Ext.log({level: 'warn'}, 'BAD! ', fullName, ' set by ', setByProps[propName], ' and ', setBy); } } if (typeof value != 'undefined' && !isNaN(value) && me.props[propName] !== value) { //Ext.log('set ', fullName, ' = ', value, ' (', dirty, ')'); } return this.callParent(arguments); } }; }(), _syncStatusCheck);