UNPKG

siesta-lite

Version:

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

336 lines (244 loc) 11.3 kB
<!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">/* Siesta 5.6.1 Copyright(c) 2009-2022 Bryntum AB https://bryntum.com/contact https://bryntum.com/products/siesta/license */ Role(&#39;Siesta.Util.Role.Dom&#39;, { does : [ Siesta.Util.Role.CanCalculatePageScroll ], has : { doesNotIncludeMarginInBodyOffset : false }, methods : { // Returns document or shadowRoot for a child element of a nested context (iframe / web component) which provides API for querySelector and elementFromPoint getQueryableContainer : function (el) { return el ? (el.getRootNode ? el.getRootNode() : el.ownerDocument) : this.global.document; }, // Returns the queryable root of an iframe or web component getQueryableContainerForNestedContext : function (el) { return el.shadowRoot || el.contentWindow.document; }, // Returns the root element of an element, the document (&lt;HTML&gt;) node or a shadowroot getRootElement : function (el) { if (el.getRootNode) { var rootNode = el.getRootNode(); if (rootNode.constructor.name === &#39;ShadowRoot&#39; || rootNode.nodeType === 11) { return rootNode; } } return el.ownerDocument.documentElement; }, // Returns top most parent node of the visible DOM of an element, the body (&lt;BODY&gt;) node for non-web components getBodyElement : function (el) { var doc = this.getQueryableContainer(el); if (doc.constructor.name === &#39;ShadowRoot&#39; || doc.nodeType === 11) { return doc; } return doc.body; }, isCrossOriginWindow : function (win) { try { var doc = win.document; } catch (e) { return true } // Safari doesn&#39;t throw exception when trying to access x-domain frames return !doc }, closest : function (elem, selector, maxLevels) { maxLevels = maxLevels || Number.MAX_VALUE; var rootEl = this.getRootElement(elem); // Get closest match for (var i = 0; i &lt; maxLevels &amp;&amp; elem &amp;&amp; elem !== rootEl; elem = elem.parentNode) { if (Siesta.Sizzle.matchesSelector(elem, selector)) { return elem; } i++; } return false; }, contains : function (parentEl, childEl) { if (!parentEl) return false if (parentEl.contains) return parentEl.contains(childEl) // SVG elements in IE does not have &quot;contains&quot; method if (parentEl.compareDocumentPosition) return parentEl === childEl || Boolean(parentEl.compareDocumentPosition(childEl) &amp; 16) throw new Error(&quot;Can&#39;t determine `contains` status&quot;) }, matches : function (node, selector) { return Siesta.Sizzle.matchesSelector(node, selector); }, // returns { left : Number, top : Number } object in page coordinates offset : function (elem) { if (!elem) return null var doc = elem.ownerDocument; if (!doc) return null if (elem === doc.body) return this.bodyOffset(elem); var box = this.getBoundingClientRect(elem) var win = doc.defaultView || doc.parentWindow return box ? { left : this.viewportXtoPageX(Math.floor(box.left), win), top : this.viewportYtoPageY(Math.floor(box.top), win) } : { left : 0, top : 0 } }, bodyOffset: function (body) { var top = body.offsetTop, left = body.offsetLeft; this.initializeOffset(); if (this.doesNotIncludeMarginInBodyOffset) { var style = getComputedStyle(body); top += parseFloat(style.marginTop) || 0; left += parseFloat(style.marginLeft) || 0; } return { top: top, left: left }; }, initializeOffset: function () { var body = document.body, container = document.createElement(&quot;div&quot;), bodyMarginTop = parseFloat(getComputedStyle(body).marginTop) || 0, html = &quot;&lt;div style=&#39;position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;&#39;&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;table style=&#39;position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;&#39; cellpadding=&#39;0&#39; cellspacing=&#39;0&#39;&gt;&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&quot;; var styles = { position: &quot;absolute&quot;, top: 0, left: 0, margin: 0, border: 0, width: &quot;1px&quot;, height: &quot;1px&quot;, visibility: &quot;hidden&quot; }; for (var o in styles) { container.style[ o ] = styles[ o ]; } container.innerHTML = html; body.insertBefore(container, body.firstChild); var innerDiv = container.firstChild; var checkDiv = innerDiv.firstChild; var td = innerDiv.nextSibling.firstChild.firstChild; checkDiv.style.position = &quot;fixed&quot;; checkDiv.style.top = &quot;20px&quot;; checkDiv.style.position = checkDiv.style.top = &quot;&quot;; innerDiv.style.overflow = &quot;hidden&quot;; innerDiv.style.position = &quot;relative&quot;; this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop); body.removeChild(container); this.initializeOffset = function () {}; }, getElementWidth : function (el) { return this.getBoundingClientRect(el).width; }, getElementHeight : function (el) { return this.getBoundingClientRect(el).height; }, getWindowSize : function (win) { var doc = win.document return { width : win.innerWidth || doc.documentElement.clientWidth || doc.body.clientWidth, height : win.innerHeight || doc.documentElement.clientHeight || doc.body.clientHeight } }, isPointWithinElement : function (x, y, el) { var rect = this.getBoundingClientRect(el); return x &gt;= rect.left &amp;&amp; x &lt;= rect.right &amp;&amp; y &gt;= rect.top &amp;&amp; y &lt;= rect.bottom; }, isElementReachableAt : function (el, pageX, pageY, allowChild) { allowChild = allowChild !== false var doc = el.ownerDocument var win = doc.defaultView || doc.parentWindow var foundEl = this.getQueryableContainer(el).elementFromPoint(this.pageXtoViewportX(pageX, win), this.pageYtoViewportY(pageY, win)) return foundEl &amp;&amp; (foundEl === el || allowChild &amp;&amp; this.contains(el, foundEl)) }, isElementReachableAtCenter : function (el, allowChild) { allowChild = allowChild !== false var offsets = this.offset(el); return this.isElementReachableAt( el, offsets.left + (this.getElementWidth(el) / 2), offsets.top + (this.getElementHeight(el) / 2), allowChild ); }, // patched version to support SVG in IE11/Edge getBoundingClientRect : function (el) { var svgEl = el.ownerSVGElement; if (svgEl &amp;&amp; (bowser.msie || bowser.msedge || bowser.gecko)) { var elBox = el.getBBox(), svgRect = svgEl.getBoundingClientRect(), left = svgRect.left + elBox.x, top = svgRect.top + elBox.y, right = left + elBox.width, bottom = top + elBox.height; return { x : left, y : top, left : left, top : top, bottom : bottom, height : elBox.height, width : elBox.width }; } else { return el.getBoundingClientRect(); } }, nodeIsUnloaded : function (el) { try { // throws if accessed when element belonged to an iframe that&#39;s no longer in DOM el &amp;&amp; el.tagName var doc = el.ownerDocument var win = doc &amp;&amp; (doc.defaultView || doc.parentWindow) return !Boolean(win) } catch (e) { // exception here probably means the &quot;lastOverEl&quot; is from freed context (unloaded page) // access to such elements throws exceptions in IE el = null return true } }, nodeIsOrphan : function (el) { if (el.constructor.name === &#39;ShadowRoot&#39; || el.nodeType === 11) { el = el.host; } var docOrHtmlFragment = this.getRootElement(el) // Detached doc fragment ? if (docOrHtmlFragment &amp;&amp; docOrHtmlFragment.nodeType === 11) { return !docOrHtmlFragment.isConnected; } return !docOrHtmlFragment || !docOrHtmlFragment.contains(el); }, getNodeParents : function (node) { var nodes = []; for (; node &amp;&amp; node.parentNode; node = node.parentNode) { nodes.unshift(node); } return nodes; }, getCommonAncestor : function (node1, node2) { var parents1 = this.getNodeParents(node1); var parents2 = this.getNodeParents(node2); // Make sure both nodes are part of same DOM tree if (parents1[ 0 ] != parents2[ 0 ]) return null; for (var i = 0; i &lt; parents1.length; i++) { if (parents1[ i ] !== parents2[ i ]) { return parents1[ i - 1 ]; } } } } }) </pre> </body> </html>