CSS zoom handling (#2178)

* Refactor

* Handle CSS zoom when scanning
This commit is contained in:
toasted-nutbread 2022-08-20 11:20:23 -04:00 committed by GitHub
parent 310303ca1a
commit 0b1ad40347
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -24,6 +24,7 @@
class DocumentUtil { class DocumentUtil {
constructor() { constructor() {
this._transparentColorPattern = /rgba\s*\([^)]*,\s*0(?:\.0+)?\s*\)/; this._transparentColorPattern = /rgba\s*\([^)]*,\s*0(?:\.0+)?\s*\)/;
this._cssZoomSupported = (typeof document.createElement('div').style.zoom === 'string');
} }
getRangeFromPoint(x, y, deepContentScan) { getRangeFromPoint(x, y, deepContentScan) {
@ -436,15 +437,21 @@ class DocumentUtil {
_isPointInRange(x, y, range) { _isPointInRange(x, y, range) {
// Require a text node to start // Require a text node to start
if (range.startContainer.nodeType !== Node.TEXT_NODE) { const {startContainer} = range;
if (startContainer.nodeType !== Node.TEXT_NODE) {
return false; return false;
} }
// Convert CSS zoom coordinates
if (this._cssZoomSupported) {
({x, y} = this._convertCssZoomCoordinates(x, y, startContainer));
}
// Scan forward // Scan forward
const nodePre = range.endContainer; const nodePre = range.endContainer;
const offsetPre = range.endOffset; const offsetPre = range.endOffset;
try { 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); range.setEnd(node, offset);
if (!this._isWhitespace(content) && DocumentUtil.isPointInAnyRect(x, y, range.getClientRects())) { if (!this._isWhitespace(content) && DocumentUtil.isPointInAnyRect(x, y, range.getClientRects())) {
@ -455,7 +462,7 @@ class DocumentUtil {
} }
// Scan backward // 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); range.setStart(node, offset);
if (!this._isWhitespace(content) && DocumentUtil.isPointInAnyRect(x, y, range.getClientRects())) { if (!this._isWhitespace(content) && DocumentUtil.isPointInAnyRect(x, y, range.getClientRects())) {
@ -661,4 +668,18 @@ class DocumentUtil {
_isElementUserSelectAll(element) { _isElementUserSelectAll(element) {
return getComputedStyle(element).userSelect === 'all'; 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};
}
} }