//{"duration":8,"time":"2012-02-25T10:55:01","success":false,"cycleCount":6,"flushCount":5,"calcCount":7,"orphans":0,"layouts":[{"allDone":true,"done":true,"id":"autocomponent-1193","type":"autocomponent","name":"headercontainer-1115","blocks":[],"boxParent":null,"isBoxParent":null,"triggers":[],"orphan":false,"heightModel":"configured","widthModel":"calculated","children":[],"duration":0,"totalTime":0,"count":1},{"allDone":false,"done":false,"id":"gridcolumn-1194","type":"gridcolumn","name":"headercontainer-1115","blocks":[],"boxParent":null,"isBoxParent":null,"triggers":[{"name":"gridview-1118.height","prop":"height","value":null,"dirty":false,"missing":true,"setBy":"??"},{"name":"gridcolumn-1116.height","prop":"height","value":22,"dirty":false,"missing":false,"setBy":"gridcolumn-1116"},{"name":"headercontainer-1115.contentWidth","prop":"contentWidth","value":335,"dirty":false,"missing":false,"setBy":"headercontainer-1115"},{"name":"headercontainer-1115.height","prop":"height","value":0,"dirty":false,"missing":false,"setBy":"headercontainer-1115"},{"name":"headercontainer-1115.width","prop":"width","value":335,"dirty":false,"missing":false,"setBy":"headercontainer-1115"},{"name":"numbercolumn-1117.height","prop":"height","value":22,"dirty":false,"missing":false,"setBy":"numbercolumn-1117"}],"orphan":false,"heightModel":"configured","widthModel":"calculated","children":[{"allDone":true,"done":true,"id":"columncomponent-1195","type":"columncomponent","name":"gridcolumn-1116","blocks":[],"boxParent":null,"isBoxParent":true,"triggers":[{"name":"gridcolumn-1116.containerChildrenDone:dom","prop":"containerChildrenDone","value":true,"dirty":false,"missing":false,"setBy":"??"},{"name":"gridcolumn-1116.width:dom","prop":"width","value":168,"dirty":false,"missing":false,"setBy":"headercontainer-1115"}],"orphan":false,"heightModel":"shrinkWrap (calculatedFromShrinkWrap)","widthModel":"calculated","children":[],"duration":0,"totalTime":0,"count":2},{"allDone":true,"done":true,"id":"columncomponent-1197","type":"columncomponent","name":"numbercolumn-1117","blocks":[],"boxParent":null,"isBoxParent":true,"triggers":[{"name":"numbercolumn-1117.containerChildrenDone:dom","prop":"containerChildrenDone","value":true,"dirty":false,"missing":false,"setBy":"??"},{"name":"numbercolumn-1117.width:dom","prop":"width","value":167,"dirty":false,"missing":false,"setBy":"headercontainer-1115"}],"orphan":false,"heightModel":"shrinkWrap (calculatedFromShrinkWrap)","widthModel":"calculated","children":[],"duration":2,"totalTime":2,"count":2}],"duration":4,"totalTime":6,"count":2}],"statsById":{"columncomponent-1195":{"duration":0,"count":2},"columncomponent-1197":{"duration":2,"count":2},"autocomponent-1193":{"duration":0,"count":1},"gridcolumn-1194":{"duration":4,"count":2}},"statsByType":{"columncomponent":{"duration":2,"layoutCount":2,"count":4},"autocomponent":{"duration":0,"layoutCount":1,"count":1},"gridcolumn":{"duration":4,"layoutCount":1,"count":2}},"flushTime":1,"flushInvalidateTime":1,"flushInvalidateCount":1,"flushLayoutStats":{"completeLayout":{"count":2,"time":0}},"totalTime":8,"num":5} Ext.Loader.setConfig({ enabled: true }); Ext.Loader.setPath({ 'Ext.ux': '../ux/', 'PageAnalyzer': './' }); Ext.require([ 'Ext.data.*', 'Ext.tree.*', 'Ext.container.Viewport', 'Ext.layout.container.Border', 'Ext.History', 'Ext.tab.Panel', 'Ext.grid.column.Action', 'Ext.form.field.TextArea', 'Ext.form.field.Number', 'Ext.toolbar.TextItem', 'Ext.layout.container.Table', 'PageAnalyzer.models.LayoutTreeNode', 'PageAnalyzer.models.ComponentTreeNode', 'PageAnalyzer.Console', 'PageAnalyzer.Summary', 'Ext.ux.IFrame', 'Ext.state.Manager', 'Ext.state.CookieProvider' ]); Ext.define('PageAnalyzer.MainForm', { statsGatherCount: 0, layoutTpl: [ '', '', '', '{name:this.encode}', { encode: function (value) { return Ext.htmlEncode(value); } } ], runTpl: [ 'Run #{num} ({time:this.date})', { date: function (value) { return Ext.Date.format(value, "Y-m-d H:i:s"); } } ], triggerTpl: [ '
', '{name} (={[String(values.value) || "?"]}) - dirty: {dirty} - setBy: {setBy:this.encode}', '
', { encode: function (value) { return Ext.htmlEncode(value); } } ], constructor: function (config) { Ext.state.Manager.setProvider(Ext.create('Ext.state.CookieProvider')); var me = this; Ext.apply(me, config); me.noCharts = me.getOption('nocharts'); me.runNumber = 0; me.viewport = Ext.widget(me.createViewport()); me.target = me.targetFrame.getWin(); me.reloadBtn = me.viewport.down('#reloadBtn'); me.stateText = me.viewport.down('#stateText'); if (me.target) { setInterval(function() { me.updateConnectedState(); }, 100); } else { me.reloadBtn.setDisabled(true); } Ext.History.init(function () { Ext.History.on({ change: 'onHistoryChange', scope: me }); me.onHistoryChange(Ext.History.getToken()); }); }, roundTimestamp: function(num) { return Math.round(num * 100) / 100; }, createLayoutTree: function() { var me = this, store = new Ext.data.TreeStore({ proxy: 'memory', model: 'PageAnalyzer.models.LayoutTreeNode' }), tree = { xtype: 'treepanel', store: store, rootVisible: false, useArrows: true, title: 'Layouts', region: 'center', viewConfig: { getRowClass: function (record) { return 'pgan-' + record.data.type; } }, columns: [ { xtype: 'treecolumn', text: 'Layout', flex: 1, hideable: false, draggable: false, dataIndex: 'text' }, { text: 'Triggers', width: 200, dataIndex: 'triggers' }, { text: 'Blocks', width: 125, hidden: true, dataIndex: 'blocks', id: 'blocksCol' }, { text: 'Width', width: 90, dataIndex: 'widthModel' }, { text: 'Height', width: 90, dataIndex: 'heightModel' }, { text: 'Box Parent', width: 100, hidden: true, dataIndex: 'boxParent', id: 'boxParentCol' }, { text: 'Time', width: 70, dataIndex: 'duration', id: 'durationCol', renderer: me.roundTimestamp }, { text: 'Calls', width: 50, dataIndex: 'count', id: 'countCol' }, { text: 'Avg Time', width: 70, id: 'avgCol', renderer: function(value, metadata, rec) { return me.roundTimestamp(rec.data.duration / rec.data.count); } }, { text: 'Tot Time', width: 70, dataIndex: 'totalTime', id: 'totalTimeCol', renderer: me.roundTimestamp }, { menuDisabled: true, sortable: false, xtype: 'actioncolumn', hideable: false, width: 40, items: [{ icon: 'resources/images/delete.gif', iconCls: 'pgan-delete-row', tooltip: 'Delete this run', handler: this.onDeleteLayoutRun, scope: this }, { icon: 'resources/images/info.gif', iconCls: 'pgan-show-row-data', tooltip: 'Show raw data for this run', handler: this.onShowLayoutRunRawData, scope: this }] } ] }; this.layoutTree = Ext.widget(tree); this.layoutTree.getSelectionModel().on({ selectionchange: this.onLayoutSelectionChange, scope: this }); return this.layoutTree; }, createComponentTree: function() { var me = this, store = new Ext.data.TreeStore({ proxy: 'memory', model: 'PageAnalyzer.models.ComponentTreeNode' }), compTree = { xtype: 'treepanel', store: store, rootVisible: false, useArrows: true, title: 'Components', region: 'center', viewConfig: { getRowClass: function (record) { var data = record.data; if (data.isComponent) { return 'pgan-component'; } else { return 'pgan-noncomponent'; } } }, columns: [ { xtype: 'treecolumn', text: 'Component', flex: 1, hideable: false, draggable: false, width: 450, dataIndex: 'text' }, { text: 'Width', width: 90, hidden: true, dataIndex: 'width' }, { text: 'Height', width: 90, hidden: true, dataIndex: 'height' }, { text: 'X', width: 90, hidden: true, dataIndex: 'x' }, { text: 'Y', width: 90, hidden: true, dataIndex: 'y' }, { text: 'CSS Class', width: 100, dataIndex: 'cssClass', id: 'cssClass' }, { text: 'XType', width: 100, dataIndex: 'xtype', id: 'xtypeCol' }, { text: 'Rendered', width: 100, dataIndex: 'rendered', id: 'renderedCol', hidden: true }, { text: 'Hidden', width: 100, dataIndex: 'hidden', id: 'hiddenCol', hidden: true }, { text: 'IsContainer', width: 100, dataIndex: 'isContainer', id: 'isContainerCol', hidden: true }, { menuDisabled: true, sortable: false, xtype: 'actioncolumn', hideable: false, width: 20, items: [{ icon: 'resources/images/info.gif', iconCls: 'pgan-display-comp-spec', tooltip: 'Display Component Test Spec', handler: this.onDisplayLayoutSpec, scope: this }] } ] }; me.componentTree = Ext.widget(compTree); return me.componentTree; }, createPerfPanel: function() { this.perfPanel = this.noCharts ? null : (Ext.widget({ xtype: 'panel', title: 'Performance', layout: 'fit', border: false, tbar: [ { text: 'Clear', handler: this.onClearStats, scope: this } ], items: [ new PageAnalyzer.Console({ itemId: 'perfcon' }) ] })); return this.perfPanel; }, createLayoutPanel: function() { var me = this; me.layoutPanel = Ext.widget({ xtype: 'panel', title: 'Layout', layout: 'border', tbar: [ { text: 'Load Run', iconCls: 'pgan-load-run', handler: me.onLoadRun, scope: me }, { text: 'Show All Triggers', enableToggle: true, handler: me.onShowAllTriggers, scope: me }, { text: 'Clear', handler: me.onClearLayouts, scope: me }, '->', { text: 'Capture Layout Spec', handler: me.onDisplayLayoutSpec, scope: me } ], items: [ me.createLayoutTree(), this.typeSummary = (this.noCharts ? null : new PageAnalyzer.Summary({ title: 'Summaries', region: 'south', height: '50%', collapsible: true, split: true })) ] }); return me.layoutPanel; }, createComponentPanel: function() { var me = this; me.componentPanel = Ext.widget({ xtype: 'panel', title: 'Components', layout: 'border', tbar: [ { text: 'Generate Component Tree', handler: me.loadComponentTree, scope: me } ], items: [ me.createComponentTree() ] }); return me.componentPanel; }, createTestPagePanel: function() { return this.targetFrame = Ext.create("Ext.ux.IFrame", { title: 'Page Under Test', hideMode: 'offsets' }); }, createViewport: function() { this.build = 1; var me = this, ret = { xtype: 'viewport', layout: 'fit', items: [ { xtype: 'panel', layout: 'fit', tbar: { items: [ { xtype: 'tbtext', itemId: 'stateText', tdAttrs: { width: '100px' } }, { xtype: 'tbtext', text: 'Test URL:', itemId: 'titleLbl', tdAttrs: { width: '100px' } }, me.targetUrlField = Ext.widget({ xtype: 'textfield', itemId: 'targetUrl', stateId: 'targetUrlField', selectOnFocus: true, flex: 1, enableKeyEvents: true, listeners: { keypress: function(f, e) { if (e.getKey() === 13) { me.onLoadPage(); } } } }), { text: 'Load', itemId: 'reloadBtn', iconCls: 'pgan-refresh', handler: me.onLoadPage, scope: me, tdAttrs: { width: '100px' } }, me.noCharts ? null : { xtype: 'numberfield', fieldLabel: 'Build', style: 'margin-right: 10px;', labelWidth: 30, width: 100, value: me.build, listeners: { change: function (field) { me.build = field.getValue(); } } }, me.noCharts ? null : { text: 'Update Stats', handler: me.onGatherStats, scope: me }, me.noCharts ? null : { text: 'Reset', handler: this.onResetStats, scope: this } ] }, items: [ Ext.create('Ext.tab.Panel', { items:[ me.createTestPagePanel(), me.createLayoutPanel(), me.createComponentPanel(), me.createPerfPanel() ] }) ] } ] }; return ret; }, addLayoutChildren: function (parent, children) { var n = children.length, triggersTpl = Ext.XTemplate.getTpl(this, 'triggerTpl'), textTpl = Ext.XTemplate.getTpl(this, 'layoutTpl'), child, data, i, j, k, node, triggers; for (i = 0; i < n; ++i) { child = children[i]; triggers = []; for (j = 0, k = child.triggers.length; j < k; ++j) { triggers.push(triggersTpl.apply(child.triggers[j])); } data = { text: textTpl.apply(child), iconCls: 'pgan-layout' + (child.allDone ? '' : (child.done ? '-partial' : '-not')) + '-done', leaf: !child.children.length, triggers: triggers.join(''), blocks: child.blocks.join('
'), boxParent: child.boxParent, isBoxParent: child.isBoxParent, heightModel: child.heightModel, widthModel: child.widthModel, type: 'layout', duration: child.duration, totalTime: child.totalTime, count: child.count }; if (data.boxParent) { this.showBoxParentCol = true; } if (data.blocks) { this.showBlocksCol = true; } node = new PageAnalyzer.models.LayoutTreeNode(data); parent.appendChild(node); this.addLayoutChildren(node, child.children); } }, addLayoutRuns: function (run) { if (typeof run == 'string') { run = Ext.decode(run); } if (Ext.isArray(run)) { Ext.each(run, this.addLayoutRuns, this); return; } if (typeof run.time == 'string') { run.time = Ext.Date.parse(run.time, "Y-m-d\\TH:i:s"); } if (typeof run.duration == 'string') { run.duration = parseInt(run.duration, 10); } //run.success = 0; run.num = ++this.runNumber; var node = new PageAnalyzer.models.LayoutTreeNode({ text: Ext.XTemplate.getTpl(this, 'runTpl').apply(run), iconCls: 'pgan-' + (run.success ? 'good' : 'failed') + '-layout-run', type: 'layoutrun', duration: run.duration, totalTime: run.totalTime, count: 1 }); this.showBoxParentCol = this.showBlocksCol = false; node.rawData = run; node.appendChild(new PageAnalyzer.models.LayoutTreeNode({ text: 'Flush', leaf: true, duration: run.flushTime, totalTime: run.flushTime, count: run.flushCount })); node.appendChild(new PageAnalyzer.models.LayoutTreeNode({ text: 'Invalidate', leaf: true, duration: run.flushInvalidateTime, totalTime: run.flushInvalidateTime, count: run.flushInvalidateCount })); Ext.Object.each(run.flushLayoutStats, function(name, val) { node.appendChild(new PageAnalyzer.models.LayoutTreeNode({ text: (name == 'notifyOwner') ? 'AfterLayout' : Ext.String.capitalize(name), leaf: true, duration: val.time, totalTime: val.time, count: val.count })); }); this.addLayoutChildren(node, run.layouts); this.layoutTree.getRootNode().appendChild(node); Ext.suspendLayouts(); if (this.showBoxParentCol) { this.layoutTree.down('#boxParentCol').show(); } if (this.showBlocksCol) { this.layoutTree.down('#blocksCol').show(); } Ext.resumeLayouts(true); }, getOption: function (opt) { var s = window.location.search; var re = new RegExp('(?:^|[&?])' + opt + '(?:[=]([^&]*))?(?:$|[&])', 'i'); var m = re.exec(s); return m ? (m[1] === undefined ? true : m[1]) : false; }, onDeleteLayoutRun: function (view, recordIndex, cellIndex, item, e, record) { record.parentNode.removeChild(record); }, onHistoryChange: function (token) { this.targetUrlField.setValue(token); }, onLayoutSelectionChange: function(selModel, records) { var run; if (records.length) { run = records[0]; while (run && run.data.type != 'layoutrun') { run = run.parentNode; } this.typeSummary.loadTypeSummary(run.rawData.statsByType); } }, onShowLayoutRunRawData: function(view, recordIndex, cellIndex, item, e, record) { var text = Ext.JSON.encodeValue(record.rawData, '\n'); Ext.widget({ xtype: 'window', modal: true, title: 'Raw data for ' + record.data.text, //closeAction: 'close', autoShow: true, layout: 'fit', width: 500, height: 400, defaultFocus: 'rawData', items: [{ xtype: 'textarea', value: text, itemId: 'rawData', readOnly: true, selectOnFocus: true }] }).show(); //this.rawDataTextArea.setValue(text); }, onLoadRun: function() { var me = this; var window = new Ext.Window({ title: 'Load Run', width: 400, height: 320, layout: 'fit', modal: true, items: [{ xtype: 'textarea' }], buttons: [{ text: 'OK', handler: function() { var text = window.down('textarea').getValue(); window.destroy(); me.addLayoutRuns(text); } }, { text: 'cancel', handler: function() { window.destroy(); } }] }); window.show(); }, getCompNodeForComp: function(comp, refName) { return new PageAnalyzer.models.ComponentTreeNode({ text: comp.id + (comp.itemId ? ' (' + comp.itemId + ')' : ''), compId: comp.id || comp.itemId, xtype: comp.xtype, refName: refName || '', rendered: comp.rendered, hidden: comp.hidden, isContainer: comp.isContainer, isElement: false, isComponent: true, iconCls: 'pgan-' + ((comp.rendered && !comp.hidden) ? 'rendered' : 'unrendered') + (comp.isContainer ? '-container' : '-component') }); }, getCompNodeForElem: function(el, root, refName) { root = root ? root.el : el; return new PageAnalyzer.models.ComponentTreeNode({ text: refName, width: el.getWidth(), height: el.getHeight(), x: root ? (el.getX() - root.getX()) : el.getX(), y: root ? (el.getY() - root.getY()) : el.getY(), cssClass: el.dom ? el.dom.className : undefined, refName: refName, isContainer: false, isComponent: false, isElement: true, hidden: !el.isVisible(true), iconCls: el.isVisible(true) ? 'pgan-visible-element' : 'pgan-hidden-element' }); }, getComponentTreeNodes: function(comps) { var me = this, compNodes = [], refName = ''; if (!Ext.isArray(comps)) { comps = [comps]; } Ext.each(comps, function(comp) { var container = comp.ownerCt, node = me.getCompNodeForComp(comp, refName), items = new PageAnalyzer.models.ComponentTreeNode({ refName: 'items', iconCls: 'pgan-' + (comp.rendered ? 'rendered' : 'unrendered') + '-container', text: 'items', isComponent: false }), dockedItems = new PageAnalyzer.models.ComponentTreeNode({ refName: 'dockedItems', iconCls: 'pgan-' + (comp.rendered ? 'rendered' : 'unrendered') + '-container', text: 'dockedItems', isComponent: false }), children; node.comp = comp; Ext.Object.each(comp, function(name, val){ if (name != 'container' && name != 'renderTo' && name != 'constrainTo' && name != 'focusEl' && val && val.dom && val.dom != me.target.document) { var child = me.getCompNodeForElem(val, container, name); node.appendChild(child); } }); if (comp.items && comp.items.items && comp.items.items.length) { children = me.getComponentTreeNodes(comp.items.items); Ext.each(children, function(child) { items.appendChild(child); }); node.appendChild(items); } if (comp.dockedItems && comp.dockedItems.items && comp.dockedItems.items.length) { children = me.getComponentTreeNodes(comp.dockedItems.items); Ext.each(children, function(child) { dockedItems.appendChild(child); }); node.appendChild(dockedItems); } compNodes.push(node); }); return compNodes; }, loadComponentTree: function() { var me = this, all = me.getTopLevelComponents(), nodes = me.getComponentTreeNodes(all), root = me.componentTree.getRootNode(); root.removeAll(); Ext.each(nodes, function(node){ root.appendChild(node); }); }, getTopLevelComponents: function () { var me = this, all = me.target.Ext.ComponentManager.all.getArray(), top = []; Ext.each(all, function(comp){ if(!comp.ownerCt) { top.push(comp); } }); return top; }, onDisplayLayoutSpec: function (view, recordIndex, cellIndex, item, e, record) { var testSpec = record.getJasmineSpec(), window = new Ext.Window({ title: 'Component Test Spec', width: 400, height: 320, layout: 'fit', modal: true, maximizable: true, items: [{ xtype: 'textarea', value: testSpec, selectOnFocus: true }], buttons: [{ text: 'OK', handler: function() { window.destroy(); } }] }); window.show(); }, onClearLayouts: function() { this.layoutTree.getRootNode().removeAll(); }, onShowAllTriggers: function (button) { var comp = this.layoutTree; if (button.pressed) { comp.addCls('pgan-show-all-triggers'); } else { comp.removeCls('pgan-show-all-triggers'); } comp.updateLayout(); }, updateLayoutRuns: function() { var me = this, target = me.target, runs = target._layoutRuns; if (runs && runs.length) { target._layoutRuns = []; me.addLayoutRuns(runs); } }, onGatherStats: function() { var me = this, target = me.target, perf = target.Ext.Perf, con = me.viewport.down('#perfcon'); // Only gather page startup stats at each reload, not on each gather if (!me.statsGatherCount) { perf.get("Initialize").enter().leave(target.Ext._afterReadytime - target.Ext._beforeReadyTime); if (target.Ext._endTime) { perf.get("Load").enter().leave(target.Ext._endTime - target.Ext._startTime); perf.get("WaitForReady").enter().leave(target.Ext._readyTime - target.Ext._endTime); } else { perf.get("BeforeReady").enter().leave(target.Ext._readyTime - target.Ext._startTime); } } perf.updateGC(); me.statsGatherCount++; var data = perf.getData(), accCfg = perf.currentConfig; con.addSample({ env: 'x', build: me.build, test: target.location.pathname, data: data }); if (accCfg) { con.setAccumulators(accCfg); } }, onClearStats: function() { this.viewport.down('#perfcon').clearSamples(); this.onResetStats(); }, onResetStats: function(){ this.target.Ext.Perf.reset(); }, getHrefMinusHash: function() { var href = location.href.replace(Ext.History.getHash(), ''); return href; }, //------------------------------------------------------------------------- // Target page mgmt states: { // the target page has not loaded Ext disconnected: { text: 'Disconnected', style: { fontWeight: 'bold', color: 'red' } }, // the target page is loaded and has Ext.isReady loaded: { text: 'Loaded', style: { fontWeight: 'bold', color: 'orange' } }, // the target page is loading the layout hooks hooking: { text: 'Loading hooks', style: { fontWeight: 'bold', color: 'yellow' } }, ready: { text: 'Ready', style: { fontWeight: 'bold', color: 'green' } } }, getState: function() { var states = this.states, target = this.target; if (target && target.Ext && target.Ext.isReady) { if (target._layoutRuns && target.Ext._readyTime) { return states.ready; } if (target._hooking) { return states.hooking; } return states.loaded; } return states.disconnected; }, injectScript: function (scriptSrc) { var me = this, url = me.getHrefMinusHash().replace(/\/[^/]+$/, '/' + scriptSrc), target = me.targetFrame.getDoc(), head = target.head || target.getElementsByTagName('head')[0]; var script = target.createElement('script'); script.src = url; script.type = 'text/javascript'; head.appendChild(script); }, injectHooks: function() { var me = this, target = me.target, perfConsole = me.viewport.down('#perfcon'), accumulatorConfigs = perfConsole && perfConsole.getAccumulators(); Ext.log('injecting script hooks'); target._hooking = 3; if (accumulatorConfigs) { target._accumulatorCfg = accumulatorConfigs; } me.injectScript('hooks.js'); }, onLoadPage: function() { var me = this, target = me.targetFrame, doc = target.getDoc(), targetUrl = me.targetUrlField.getValue(); if (targetUrl && targetUrl != '' && doc) { // add a query parameter the target page url so it will pause at onReady so that // we can inject our code and resume it to capture the initial layout run // by setting a global override flag (in updateConnectedState): Ext.log('resetting target document state'); me.target._layoutRuns = null; me.target._syncComplete = false; if (me.target.Ext) { me.target.Ext._readyTime = 0; } me.reloading = true; var hasPound = targetUrl.indexOf('#'), hasQuest = targetUrl.indexOf('?') , qParm = (hasQuest > 0 ? '&' : '?') + 'ext-pauseReadyFire'; if (targetUrl != Ext.History.getToken()) { Ext.History.add(targetUrl); } if (hasPound > 0) { targetUrl = targetUrl.substring(0, hasPound) + qParm + targetUrl.substring(hasPound + 1); } else { targetUrl += qParm; } Ext.log('reloading target document'); me.targetFrame.load(targetUrl); me.currUrl = targetUrl; me.updateConnectedState(); me.statsGatherCount = 0; } else { me.targetFrame.load('about:blank'); } }, updateConnectedState: function() { var me = this, states = me.states, state = me.getState(); if (me.lastState != state) { me.lastState = state; me.stateText.el.setStyle(state.style); me.stateText.setText(state.text); } if (state == states.loaded) { me.injectHooks(); } else if (state == states.ready) { if (me.reloading) { Ext.log('firing ready event in target document'); me.reloading = false; me.target.Ext._continueFireReady = true; me.target.Ext.EventManager.readyEvent.fire(); } me.updateLayoutRuns(); } } }); (function() { function run () { Ext.QuickTips.init(); new PageAnalyzer.MainForm({ targetHref: window.opener ? window.opener.location.href : null }); } Ext.onReady(run); })();