<!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">// This override adds diagnostics to the Ext.layout.Context class.
|
|
<span id='Ext-diag-layout-Context'>/**
|
</span> */
|
Ext.define('Ext.diag.layout.Context', {
|
override: 'Ext.layout.Context',
|
|
requires: [
|
'Ext.perf.Monitor'
|
],
|
|
<span id='Ext-layout-Context-property-logOn'> logOn: {
|
</span> //boxParent: true,
|
//calculate: true,
|
//cancelComponent: true,
|
//cancelLayout: true,
|
//doInvalidate: true,
|
//flush: true,
|
//flushInvalidate: true,
|
//invalidate: true,
|
//initItem: true,
|
//layoutDone: true,
|
//queueLayout: true,
|
//resetLayout: true,
|
//runCycle: true,
|
//setProp: true,
|
0:0
|
},
|
|
//profileLayoutsByType: true,
|
|
<span id='Ext-diag-layout-Context-method-cancelComponent'> //reportOnSuccess: true,
|
</span>
|
cancelComponent: function (comp) {
|
if (this.logOn.cancelComponent) {
|
Ext.log('cancelCmp: ', comp.id);
|
}
|
this.callParent(arguments);
|
},
|
|
<span id='Ext-diag-layout-Context-method-cancelLayout'> cancelLayout: function (layout) {
|
</span> if (this.logOn.cancelLayout) {
|
Ext.log('cancelLayout: ', this.getLayoutName(layout));
|
}
|
this.callParent(arguments);
|
},
|
|
<span id='Ext-diag-layout-Context-method-callLayout'> callLayout: function (layout, methodName) {
|
</span> var accum = this.accumByType[layout.type],
|
frame = accum && accum.enter();
|
|
this.callParent(arguments);
|
|
if (accum) {
|
frame.leave();
|
}
|
},
|
|
<span id='Ext-layout-Context-method-checkRemainingLayouts'> checkRemainingLayouts: function () {
|
</span> var me = this,
|
expected = 0,
|
key, layout;
|
|
for (key in me.layouts) {
|
layout = me.layouts[key];
|
|
if (me.layouts.hasOwnProperty(key) && layout.running) {
|
++expected;
|
}
|
}
|
|
if (me.remainingLayouts != expected) {
|
Ext.Error.raise({
|
msg: 'Bookkeeping error me.remainingLayouts'
|
});
|
}
|
},
|
|
<span id='Ext-diag-layout-Context-method-flush'> flush: function () {
|
</span> if (this.logOn.flush) {
|
var items = this.flushQueue;
|
Ext.log('--- Flush ', items && items.getCount());
|
}
|
|
return this.callParent(arguments);
|
},
|
|
<span id='Ext-diag-layout-Context-method-flushInvalidates'> flushInvalidates: function () {
|
</span> if (this.logOn.flushInvalidate) {
|
Ext.log('>> flushInvalidates');
|
}
|
|
var ret = this.callParent(arguments);
|
|
if (this.logOn.flushInvalidate) {
|
Ext.log('<< flushInvalidates');
|
}
|
|
return ret;
|
},
|
|
<span id='Ext-diag-layout-Context-method-getCmp'> getCmp: function (target) {
|
</span> var ret = this.callParent(arguments);
|
if (!ret.wrapsComponent) {
|
Ext.Error.raise({
|
msg: target.id + ' is not a component'
|
});
|
}
|
return ret;
|
},
|
|
<span id='Ext-diag-layout-Context-method-getEl'> getEl: function (parent, target) {
|
</span> var ret = this.callParent(arguments);
|
if (ret && ret.wrapsComponent) {
|
Ext.Error.raise({
|
msg: parent.id + '/' + target.id + ' is a component (expected element)'
|
});
|
}
|
return ret;
|
},
|
|
<span id='Ext-layout-Context-method-getLayoutName'> getLayoutName: function (layout) {
|
</span> return layout.owner.id + '<' + layout.type + '>';
|
},
|
|
<span id='Ext-diag-layout-Context-method-layoutDone'> layoutDone: function (layout) {
|
</span> var me = this,
|
name = me.getLayoutName(layout);
|
|
if (me.logOn.layoutDone) {
|
Ext.log('layoutDone: ', name, ' ( ', me.remainingLayouts, ' running)');
|
}
|
|
if (!layout.running) {
|
Ext.Error.raise({
|
msg: name + ' is already done'
|
});
|
}
|
if (!me.remainingLayouts) {
|
Ext.Error.raise({
|
msg: name + ' finished but no layouts are running'
|
});
|
}
|
|
me.callParent(arguments);
|
},
|
|
<span id='Ext-layout-Context-method-layoutTreeHasFailures'> layoutTreeHasFailures: function (layout, reported) {
|
</span> var me = this;
|
|
function hasFailure (lo) {
|
var failure = !lo.done,
|
key, childLayout;
|
|
if (lo.done) {
|
for (key in me.layouts) {
|
if (me.layouts.hasOwnProperty(key)) {
|
childLayout = me.layouts[key];
|
|
if (childLayout.owner.ownerLayout === lo) {
|
if (hasFailure(childLayout)) {
|
failure = true;
|
}
|
}
|
}
|
}
|
}
|
|
return failure;
|
}
|
|
if (hasFailure(layout)) {
|
return true;
|
}
|
|
function markReported (lo) {
|
var key, childLayout;
|
|
reported[lo.id] = 1;
|
|
for (key in me.layouts) {
|
if (me.layouts.hasOwnProperty(key)) {
|
childLayout = me.layouts[key];
|
|
if (childLayout.owner.ownerLayout === lo) {
|
markReported(childLayout);
|
}
|
}
|
}
|
}
|
|
markReported(layout);
|
return false;
|
},
|
|
<span id='Ext-diag-layout-Context-method-queueLayout'> queueLayout: function (layout) {
|
</span> if (layout.done || layout.blockCount || layout.pending) {
|
Ext.Error.raise({
|
msg: this.getLayoutName(layout) + ' should not be queued for layout'
|
});
|
}
|
if (this.logOn.queueLayout) {
|
Ext.log('Queue ', this.getLayoutName(layout));
|
}
|
return this.callParent(arguments);
|
},
|
|
<span id='Ext-layout-Context-method-reportLayoutResult'> reportLayoutResult: function (layout, reported) {
|
</span> var me = this,
|
owner = layout.owner,
|
ownerContext = me.getCmp(owner),
|
blockedBy = [],
|
triggeredBy = [],
|
key, value, i, length, childLayout,
|
item, setBy, info;
|
|
reported[layout.id] = 1;
|
|
for (key in layout.blockedBy) {
|
if (layout.blockedBy.hasOwnProperty(key)) {
|
blockedBy.push(layout.blockedBy[key]);
|
}
|
}
|
blockedBy.sort();
|
|
for (key in me.triggersByLayoutId[layout.id]) {
|
if (me.triggersByLayoutId[layout.id].hasOwnProperty(key)) {
|
value = me.triggersByLayoutId[layout.id][key];
|
triggeredBy.push({ name: key, info: value });
|
}
|
}
|
triggeredBy.sort(function (a, b) {
|
return a.name < b.name ? -1 : (b.name < a.name ? 1 : 0);
|
});
|
|
Ext.log({indent: 1}, (layout.done ? '++' : '--'), me.getLayoutName(layout),
|
(ownerContext.isBoxParent ? ' [isBoxParent]' : ''),
|
(ownerContext.boxChildren ? ' - boxChildren: ' + ownerContext.state.boxesMeasured + '/' + ownerContext.boxChildren.length : ''),
|
ownerContext.boxParent ? (' - boxParent: ' + ownerContext.boxParent.id) : '',
|
' - size: ', ownerContext.widthModel.name, '/', ownerContext.heightModel.name);
|
|
if (!layout.done || me.reportOnSuccess) {
|
if (blockedBy.length) {
|
++Ext.log.indent;
|
Ext.log({indent: 1}, 'blockedBy: count=',layout.blockCount);
|
|
length = blockedBy.length;
|
for (i = 0; i < length; i++) {
|
Ext.log(blockedBy[i]);
|
}
|
|
Ext.log.indent -= 2;
|
}
|
if (triggeredBy.length) {
|
++Ext.log.indent;
|
Ext.log({indent: 1}, 'triggeredBy: count='+layout.triggerCount);
|
|
length = triggeredBy.length;
|
for (i = 0; i < length; i++) {
|
info = value.info || value;
|
item = info.item;
|
setBy = (item.setBy && item.setBy[info.name]) || '?';
|
|
value = triggeredBy[i];
|
|
Ext.log(
|
value.name,
|
' (',
|
item.props[info.name],
|
') dirty: ',
|
(item.dirty ? !!item.dirty[info.name] : false),
|
', setBy: ',
|
setBy
|
);
|
}
|
|
Ext.log.indent -= 2;
|
}
|
}
|
|
for (key in me.layouts) {
|
if (me.layouts.hasOwnProperty(key)) {
|
childLayout = me.layouts[key];
|
|
if (!childLayout.done && childLayout.owner.ownerLayout === layout) {
|
me.reportLayoutResult(childLayout, reported);
|
}
|
}
|
}
|
|
for (key in me.layouts) {
|
if (me.layouts.hasOwnProperty(key)) {
|
childLayout = me.layouts[key];
|
|
if (childLayout.done && childLayout.owner.ownerLayout === layout) {
|
me.reportLayoutResult(childLayout, reported);
|
}
|
}
|
}
|
|
--Ext.log.indent;
|
},
|
|
<span id='Ext-diag-layout-Context-method-resetLayout'> resetLayout: function (layout) {
|
</span> var me = this,
|
type = layout.type,
|
name = me.getLayoutName(layout),
|
accum = me.accumByType[type],
|
frame;
|
|
if (me.logOn.resetLayout) {
|
Ext.log('resetLayout: ', name, ' ( ', me.remainingLayouts, ' running)');
|
}
|
|
if (!me.state) { // if (first time ... before run)
|
if (!accum && me.profileLayoutsByType) {
|
me.accumByType[type] = accum = Ext.Perf.get('layout_' + layout.type);
|
}
|
me.numByType[type] = (me.numByType[type] || 0) + 1;
|
}
|
|
frame = accum && accum.enter();
|
me.callParent(arguments);
|
if (accum) {
|
frame.leave();
|
}
|
|
me.checkRemainingLayouts();
|
},
|
|
<span id='Ext-layout-Context-method-round'> round: function (t) {
|
</span> return Math.round(t * 1000) / 1000;
|
},
|
|
<span id='Ext-diag-layout-Context-method-run'> run: function () {
|
</span> var me = this,
|
ret, time, key, value, i, layout,
|
boxParent, children, n,
|
reported, unreported,
|
calcs, total,
|
calcsLength, calc;
|
|
me.accumByType = {};
|
me.calcsByType = {};
|
me.numByType = {};
|
me.timesByType = {};
|
me.triggersByLayoutId = {};
|
|
Ext.log.indentSize = 3;
|
Ext.log('==================== LAYOUT ====================');
|
|
time = Ext.perf.getTimestamp();
|
ret = me.callParent(arguments);
|
time = Ext.perf.getTimestamp() - time;
|
|
if (me.logOn.boxParent && me.boxParents) {
|
for (key in me.boxParents) {
|
if (me.boxParents.hasOwnProperty(key)) {
|
boxParent = me.boxParents[key];
|
children = boxParent.boxChildren;
|
n = children.length;
|
|
Ext.log('boxParent: ', boxParent.id);
|
for (i = 0; i < n; ++i) {
|
Ext.log(' --> ', children[i].id);
|
}
|
}
|
}
|
}
|
|
if (ret) {
|
Ext.log('----------------- SUCCESS -----------------');
|
} else {
|
Ext.log(
|
{level: 'error' },
|
'----------------- FAILURE -----------------'
|
);
|
}
|
|
for (key in me.layouts) {
|
if (me.layouts.hasOwnProperty(key)) {
|
layout = me.layouts[key];
|
|
if (layout.running) {
|
Ext.log.error('Layout left running: ', me.getLayoutName(layout));
|
}
|
if (layout.ownerContext) {
|
Ext.log.error('Layout left connected: ', me.getLayoutName(layout));
|
}
|
}
|
}
|
|
if (!ret || me.reportOnSuccess) {
|
reported = {};
|
unreported = 0;
|
|
for (key in me.layouts) {
|
if (me.layouts.hasOwnProperty(key)) {
|
layout = me.layouts[key];
|
|
if (me.items[layout.owner.el.id].isTopLevel) {
|
if (me.reportOnSuccess || me.layoutTreeHasFailures(layout, reported)) {
|
me.reportLayoutResult(layout, reported);
|
}
|
}
|
}
|
}
|
|
// Just in case we missed any layouts...
|
for (key in me.layouts) {
|
if (me.layouts.hasOwnProperty(key)) {
|
layout = me.layouts[key];
|
|
if (!reported[layout.id]) {
|
if (!unreported) {
|
Ext.log('----- Unreported!! -----');
|
}
|
++unreported;
|
me.reportLayoutResult(layout, reported);
|
}
|
}
|
}
|
}
|
|
Ext.log('Cycles: ', me.cycleCount, ', Flushes: ', me.flushCount,
|
', Calculates: ', me.calcCount, ' in ', me.round(time), ' msec');
|
|
Ext.log('Calculates by type:');
|
/*Ext.Object.each(me.numByType, function (type, total) {
|
Ext.log(type, ': ', total, ' in ', me.calcsByType[type], ' tries (',
|
Math.round(me.calcsByType[type] / total * 10) / 10, 'x) at ',
|
me.round(me.timesByType[type]), ' msec (avg ',
|
me.round(me.timesByType[type] / me.calcsByType[type]), ' msec)');
|
});*/
|
calcs = [];
|
for (key in me.numByType) {
|
if (me.numByType.hasOwnProperty(key)) {
|
total = me.numByType[key];
|
|
calcs.push({
|
type : key,
|
total : total,
|
calcs : me.calcsByType[key],
|
multiple : Math.round(me.calcsByType[key] / total * 10) / 10,
|
calcTime : me.round(me.timesByType[key]),
|
avgCalcTime: me.round(me.timesByType[key] / me.calcsByType[key])
|
});
|
}
|
}
|
|
|
calcs.sort(function (a,b) {
|
return b.calcTime - a.calcTime;
|
});
|
|
calcsLength = calcs.length;
|
for (i=0; i<calcsLength; i++) {
|
calc = calcs[i];
|
|
Ext.log(
|
calc.type,
|
': ',
|
calc.total,
|
' in ',
|
calc.calcs,
|
' tries (',
|
calc.multiple,
|
'x) at ',
|
calc.calcTime,
|
' msec (avg ',
|
calc.avgCalcTime,
|
' msec)'
|
);
|
}
|
|
return ret;
|
},
|
|
<span id='Ext-diag-layout-Context-method-runCycle'> runCycle: function () {
|
</span> if (this.logOn.runCycle) {
|
Ext.log('>>> Cycle ', this.cycleCount, ' (queue length: ', this.layoutQueue.length, ')');
|
}
|
|
return this.callParent(arguments);
|
},
|
|
<span id='Ext-diag-layout-Context-method-runLayout'> runLayout: function (layout) {
|
</span> var me = this,
|
type = layout.type,
|
accum = me.accumByType[type],
|
frame, ret, time;
|
|
if (me.logOn.calculate) {
|
Ext.log('-- calculate ', this.getLayoutName(layout));
|
}
|
|
frame = accum && accum.enter();
|
|
time = Ext.perf.getTimestamp();
|
ret = me.callParent(arguments);
|
time = Ext.perf.getTimestamp() - time;
|
if (accum) {
|
frame.leave();
|
}
|
|
me.calcsByType[type] = (me.calcsByType[type] || 0) + 1;
|
me.timesByType[type] = (me.timesByType[type] || 0) + time;
|
|
/* add a / to the front of this line to enable layout completion logging
|
if (layout.done) {
|
var ownerContext = me.getCmp(layout.owner),
|
props = ownerContext.props;
|
|
if (layout.isComponentLayout) {
|
Ext.log('complete ', layout.owner.id, ':', type, ' w=',props.width, ' h=', props.height);
|
} else {
|
Ext.log('complete ', layout.owner.id, ':', type, ' cw=',props.contentWidth, ' ch=', props.contentHeight);
|
}
|
}**/
|
|
return ret;
|
}
|
});
|
</pre>
|
</body>
|
</html>
|