diff options
author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2022-08-20 11:20:23 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-20 11:20:23 -0400 |
commit | 0b1ad403471c0c097d08af59717a34691d8bf5b7 (patch) | |
tree | ea812b07ec3b279985c52a3129204ee390b11ae9 /ext/js/dom/document-util.js | |
parent | 310303ca1a123a77f9bd116af4dc64ad9c3256c5 (diff) |
CSS zoom handling (#2178)
* Refactor
* Handle CSS zoom when scanning
Diffstat (limited to 'ext/js/dom/document-util.js')
-rw-r--r-- | ext/js/dom/document-util.js | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/ext/js/dom/document-util.js b/ext/js/dom/document-util.js index f5cf194b..b974387e 100644 --- a/ext/js/dom/document-util.js +++ b/ext/js/dom/document-util.js @@ -24,6 +24,7 @@ class DocumentUtil { constructor() { this._transparentColorPattern = /rgba\s*\([^)]*,\s*0(?:\.0+)?\s*\)/; + this._cssZoomSupported = (typeof document.createElement('div').style.zoom === 'string'); } getRangeFromPoint(x, y, deepContentScan) { @@ -436,15 +437,21 @@ class DocumentUtil { _isPointInRange(x, y, range) { // Require a text node to start - if (range.startContainer.nodeType !== Node.TEXT_NODE) { + const {startContainer} = range; + if (startContainer.nodeType !== Node.TEXT_NODE) { return false; } + // Convert CSS zoom coordinates + if (this._cssZoomSupported) { + ({x, y} = this._convertCssZoomCoordinates(x, y, startContainer)); + } + // Scan forward const nodePre = range.endContainer; const offsetPre = range.endOffset; try { - const {node, offset, content} = new DOMTextScanner(range.endContainer, range.endOffset, true, false).seek(1); + const {node, offset, content} = new DOMTextScanner(nodePre, offsetPre, true, false).seek(1); range.setEnd(node, offset); if (!this._isWhitespace(content) && DocumentUtil.isPointInAnyRect(x, y, range.getClientRects())) { @@ -455,7 +462,7 @@ class DocumentUtil { } // Scan backward - const {node, offset, content} = new DOMTextScanner(range.startContainer, range.startOffset, true, false).seek(-1); + const {node, offset, content} = new DOMTextScanner(startContainer, range.startOffset, true, false).seek(-1); range.setStart(node, offset); if (!this._isWhitespace(content) && DocumentUtil.isPointInAnyRect(x, y, range.getClientRects())) { @@ -661,4 +668,18 @@ class DocumentUtil { _isElementUserSelectAll(element) { return getComputedStyle(element).userSelect === 'all'; } + + _convertCssZoomCoordinates(x, y, node) { + const ELEMENT_NODE = Node.ELEMENT_NODE; + for (; node !== null; node = node.parentNode) { + if (node.nodeType !== ELEMENT_NODE) { continue; } + let {zoom} = getComputedStyle(node); + if (typeof zoom !== 'string') { continue; } + zoom = Number.parseFloat(zoom); + if (!Number.isFinite(zoom) || zoom === 0) { continue; } + x /= zoom; + y /= zoom; + } + return {x, y}; + } } |