UNPKG

siesta-lite

Version:

Stress-free JavaScript unit testing and functional testing tool, works in NodeJS and browsers

475 lines (334 loc) 13.1 kB
/* Siesta 5.6.1 Copyright(c) 2009-2022 Bryntum AB https://bryntum.com/contact https://bryntum.com/products/siesta/license */ Ext.define('Siesta.Project.Browser.UI.DomContainer', { extend : 'Ext.Panel', alias : 'widget.domcontainer', requires : [ 'Siesta.Project.Browser.UI.ComponentInspector' ], cls : 'siesta-domcontainer', header : false, collapsible : true, animCollapse : false, padding : 10, test : null, testListeners : null, scaleToFit : true, scaleToFitMode : 'full', maintainViewportSize : true, canManageDOM : true, suspendAfterLayoutAlign : false, inspector : null, inspectorConfig : null, enableConsole : true, trackMouse : true, initComponent : function () { var me = this; this.testListeners = [] this.title = Siesta.Resource('Siesta.Project.Browser.UI.DomContainer', 'title'); //this.addEvents( // 'inspectionstart', // 'inspectionstop', // 'targethover', // 'targetselected' //) if (this.enableConsole) { Ext.apply(this, { dockedItems : this.consoleCt = { xtype : 'component', dock : 'bottom', hidden : true, height : 20, cls : 'domcontainer-console', renderTpl : '<div><input type="text" /></div>' } }); } this.callParent() this.on({ afterlayout : this.onAfterLayout, expand : this.onExpand, collapse : this.onCollapse, scope : this }); this.inspector = new Siesta.Project.Browser.UI.ComponentInspector(this.inspectorConfig); if (this.trackMouse) { this.inspector.on({ start : this.onInspectionStart, stop : this.onInspectionStop, scope : this }); } this.relayEvents(this.inspector, ['start', 'stop'], 'inspection') this.enableBubble('statechange'); }, afterRender : function () { this.callParent(arguments); if (this.enableConsole) { var input = this.consoleInput = this.el.down('.domcontainer-console input'); this.inspector.on('targethover', function (dc, cmp) { input.dom.value = 'Ext.getCmp("' + cmp.id + '").'; }); this.inspector.on('targetselected', function (dc, cmp) { input.focus(true); }); input.on({ keyup : function (e, t) { var val = input.dom.value; if (e.getKey() === e.ENTER && val) { var frame = this.getIFrame(); try { var retVal = frame.contentWindow.eval(val); if (window.console) { console.log(retVal); } } catch (e) { window.console && console.log(e.message); } } }, scope : this }); } }, setScaleToFit : function (scaleToFit, mode) { if (this.scaleToFit == scaleToFit && (!mode || this.scaleToFitMode == mode)) return this.scaleToFit = scaleToFit if (mode) this.scaleToFitMode = mode if (scaleToFit) { this.doScaleToFit(); } else { this.undoScaleToFit(); } this.fireEvent('statechange') }, doScaleToFit : function (isInitial) { var iframe = this.getIFrame(); if (!iframe) return var mode = this.scaleToFitMode var scrollbarSize = Ext.getScrollbarSize() var innerWrapper = iframe.parentNode var scrollCanvas = innerWrapper.parentNode var wrapper = scrollCanvas.parentNode var availableWidth = this.body.dom.offsetWidth - (mode === 'width' ? scrollbarSize.width : 0) var availableHeight = this.body.dom.offsetHeight - (mode === 'height' ? scrollbarSize.height : 0) var contentWidth = iframe.offsetWidth var contentHeight = iframe.offsetHeight var widthScale = availableWidth / contentWidth var heightScale = availableHeight / contentHeight var scale = mode === 'width' ? widthScale : mode === 'height' ? heightScale : Math.min(widthScale, heightScale) var leftWidth = availableWidth - scale * contentWidth var leftHeight = availableHeight - scale * contentHeight var left = Math.max(0, leftWidth / 2) var top = Math.max(0, leftHeight / 2) innerWrapper.style.transition = isInitial ? 'none' : 'transform 0.3s' innerWrapper.style.transform = 'translate(' + left + 'px, ' + top + 'px) scale(' + scale + ') '; scrollCanvas.style.width = scale * contentWidth + 'px' scrollCanvas.style.height = scale * contentHeight + 'px' this.removeScaleToFitClasses(wrapper) Ext.fly(wrapper).addCls('scaleToFit' + Joose.S.uppercaseFirst(mode)); this.scrollTo(0, 0); // the "min" in the name should be removed var viewportSize = this.test.scopeProvider.minViewportSize innerWrapper.style.width = viewportSize.width + 'px' innerWrapper.style.height = viewportSize.height + 'px' }, removeScaleToFitClasses : function (wrapper) { Ext.fly(wrapper).removeCls('scaleToFitFull'); Ext.fly(wrapper).removeCls('scaleToFitWidth'); Ext.fly(wrapper).removeCls('scaleToFitHeight'); }, undoScaleToFit : function () { var iframe = this.getIFrame(); if (!iframe) return var innerWrapper = iframe.parentNode var scrollCanvas = innerWrapper.parentNode this.removeScaleToFitClasses(scrollCanvas.parentNode) innerWrapper.style.transform = '' innerWrapper.style.width = iframe.style.width innerWrapper.style.height = iframe.style.height innerWrapper.style.left = '' innerWrapper.style.top = '' scrollCanvas.style.width = iframe.style.width scrollCanvas.style.height = iframe.style.height }, setCanManageDOM : function (value) { this.canManageDOM = value if (value && !this.hidden) this.alignIFrame() }, getIFrameWrapper : function (force) { var test = this.test; if (test) return (this.canManageDOM || force) && test.scopeProvider && test.scopeProvider.wrapper || null else return null; }, getIFrame : function (force) { var test = this.test; if (test) return (this.canManageDOM || force) && test.scopeProvider && test.scopeProvider.iframe || null else return null; }, onAfterLayout : function () { if (!this.suspendAfterLayoutAlign) this.alignIFrame(); }, alignIFrame : function (force, isInitial) { var wrapper = this.getIFrameWrapper(force); if (!this.isFrameVisible() || !wrapper) return Ext.fly(wrapper).removeCls('tr-iframe-hidden') Ext.fly(wrapper).removeCls('tr-iframe-forced') var box = this.body.getBox() Ext.fly(wrapper).setBox(box) if (!this.maintainViewportSize) { Ext.fly(this.getIFrame(force)).setSize(this.body.getSize()) } if (this.scaleToFit) this.doScaleToFit(isInitial) else this.undoScaleToFit() var test = this.test test && test.fireEvent('testframeshow') }, onCollapse : function () { this.hideIFrame(); }, onExpand : function () { this.alignIFrame(); }, hideIFrame : function () { var iframe = this.getIFrameWrapper() iframe && Ext.fly(iframe).setStyle({ left : '-10000px', top : '-10000px' }) var test = this.test test && test.fireEvent('testframehide') }, isFrameVisible : function () { return !(this.hidden || this.collapsed) }, showTest : function (test) { this.stopInspection(); if (this.test) { Joose.A.each(this.testListeners, function (listener) { listener.remove() }) this.testListeners = [] this.hideIFrame() } this.test = test this.testListeners = [ test.on('testfinalize', this.onTestFinalize, this) ] // when starting the test with forcedIframe - do not allow the assertion grid to change the location of the iframe // (canManageDOM is set to false) this.setCanManageDOM(!test.hasForcedIframe()) this.alignIFrame(false, true); }, onTestFinalize : function (event, test) { this.setCanManageDOM(true) // this prevents project from hiding the iframe, because "test.hasForcedIframe()" will return null // we've moved the iframe to the correct position, and it can never be "forced" again anyway if (this.isFrameVisible()) { test.forceDOMVisible = false test.isDOMForced = false } }, destroy : function () { Ext.destroy(this.boxIndicator); this.boxIndicator = null; // just in case this.hideIFrame() Joose.A.each(this.testListeners, function (listener) { listener.remove() }) this.test = null this.callParent(arguments) }, // BEGIN Inspection related code // ----------------------------- inspectedComponent : null, inspectedComponentXType : null, boxIndicator : null, inspecting : false, toggleInspectionMode : function (on) { if (!this.test) return; if (on) { this.startInspection(); } else { this.stopInspection(); } }, startInspection : function (showConsole) { if (!this.test || !this.test.global) return; var wrap = Ext.get(this.getIFrameWrapper()); this.inspector.start(this.test.global, wrap.down('.tr-iframe-wrapper-inner', true)); if (this.trackMouse) { wrap.un('mouseout', this.onMouseLeave, this); wrap.on('mouseout', this.onMouseLeave, this); } if (this.enableConsole && showConsole !== false) { if (!(this.consoleCt instanceof Ext.Component)) { this.consoleCt = Ext.widget(this.consoleCt); } this.consoleCt.show(); } this.addCls('inspection-mode'); }, stopInspection : function () { this.inspector.stop(); this.removeCls('inspection-mode'); if (this.enableConsole && this.consoleCt.rendered) { this.consoleCt.hide(); } }, onMouseLeave : function (e, t) { if (!this.el.contains(e.relatedTarget) && !Ext.fly(this.getIFrameWrapper()).contains(e.relatedTarget)) { this.stopInspection(); } }, onInspectionStart : function () { var wrap = Ext.get(this.getIFrameWrapper()); if (wrap) { wrap.on('mouseout', this.onMouseLeave, this); } }, onInspectionStop : function () { var wrap = Ext.get(this.getIFrameWrapper()); if (wrap) { wrap.un('mouseout', this.onMouseLeave, this); } }, clearHighlight : function () { this.stopInspection(); }, highlightTarget : function (target, content, offset) { var targetIsPoint = target instanceof Array; if (!this.inspector.active) { this.startInspection(); } if (targetIsPoint) { offset = target; target = null; } else { target = this.test.normalizeElement(target, true, true, false); if (target) { // Detect if we're trying to highlight a hidden target, then skip the target if (!target.offsetWidth && !target.offsetHeight) { target = offset = null; } else if (offset) { offset = this.test.normalizeOffset(offset, $(target)); } } } this.inspector.highlightTarget(target, content, offset); } });