Exclude documentElement from zoom calculation (#2227)
* Exclude documentElement from zoom calculation * Add an option * Refactor zoom coordinate conversion functions * Convert zoom coordinates for text sources * Rename variable * Convert rect coordinate spaces * Handle shadow DOM
This commit is contained in:
parent
ac373a6794
commit
480869c3d1
@ -438,7 +438,8 @@
|
|||||||
"layoutAwareScan",
|
"layoutAwareScan",
|
||||||
"matchTypePrefix",
|
"matchTypePrefix",
|
||||||
"hidePopupOnCursorExit",
|
"hidePopupOnCursorExit",
|
||||||
"hidePopupOnCursorExitDelay"
|
"hidePopupOnCursorExitDelay",
|
||||||
|
"normalizeCssZoom"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
@ -706,6 +707,10 @@
|
|||||||
"type": "number",
|
"type": "number",
|
||||||
"minimum": 0,
|
"minimum": 0,
|
||||||
"default": 0
|
"default": 0
|
||||||
|
},
|
||||||
|
"normalizeCssZoom": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -395,6 +395,7 @@ class Frontend {
|
|||||||
this._textScanner.setOptions({
|
this._textScanner.setOptions({
|
||||||
inputs: scanningOptions.inputs,
|
inputs: scanningOptions.inputs,
|
||||||
deepContentScan: scanningOptions.deepDomScan,
|
deepContentScan: scanningOptions.deepDomScan,
|
||||||
|
normalizeCssZoom: scanningOptions.normalizeCssZoom,
|
||||||
selectText: scanningOptions.selectText,
|
selectText: scanningOptions.selectText,
|
||||||
delay: scanningOptions.delay,
|
delay: scanningOptions.delay,
|
||||||
touchInputEnabled: scanningOptions.touchInputEnabled,
|
touchInputEnabled: scanningOptions.touchInputEnabled,
|
||||||
|
@ -368,7 +368,7 @@ class Popup extends EventDispatcher {
|
|||||||
* `valid` is `false` for `PopupProxy`, since the DOM node is hosted in a different frame.
|
* `valid` is `false` for `PopupProxy`, since the DOM node is hosted in a different frame.
|
||||||
*/
|
*/
|
||||||
getFrameRect() {
|
getFrameRect() {
|
||||||
const {left, top, right, bottom} = this._frame.getBoundingClientRect();
|
const {left, top, right, bottom} = this._getFrameBoundingClientRect();
|
||||||
return {left, top, right, bottom, valid: true};
|
return {left, top, right, bottom, valid: true};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,7 +377,7 @@ class Popup extends EventDispatcher {
|
|||||||
* @returns {Promise<{width: number, height: number, valid: boolean}>} The size and whether or not it is valid.
|
* @returns {Promise<{width: number, height: number, valid: boolean}>} The size and whether or not it is valid.
|
||||||
*/
|
*/
|
||||||
async getFrameSize() {
|
async getFrameSize() {
|
||||||
const {width, height} = this._frame.getBoundingClientRect();
|
const {width, height} = this._getFrameBoundingClientRect();
|
||||||
return {width, height, valid: true};
|
return {width, height, valid: true};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -680,12 +680,13 @@ class Popup extends EventDispatcher {
|
|||||||
* @returns {SizeRect} The calculated rectangle for where to position the popup.
|
* @returns {SizeRect} The calculated rectangle for where to position the popup.
|
||||||
*/
|
*/
|
||||||
_getPosition(sourceRects, writingMode, viewport) {
|
_getPosition(sourceRects, writingMode, viewport) {
|
||||||
const scale = this._contentScale;
|
sourceRects = this._convertSourceRectsCoordinateSpace(sourceRects);
|
||||||
const scaleRatio = this._frameSizeContentScale === null ? 1.0 : scale / this._frameSizeContentScale;
|
const contentScale = this._contentScale;
|
||||||
this._frameSizeContentScale = scale;
|
const scaleRatio = this._frameSizeContentScale === null ? 1.0 : contentScale / this._frameSizeContentScale;
|
||||||
|
this._frameSizeContentScale = contentScale;
|
||||||
const frameRect = this._frame.getBoundingClientRect();
|
const frameRect = this._frame.getBoundingClientRect();
|
||||||
const frameWidth = Math.max(frameRect.width * scaleRatio, this._initialWidth * scale);
|
const frameWidth = Math.max(frameRect.width * scaleRatio, this._initialWidth * contentScale);
|
||||||
const frameHeight = Math.max(frameRect.height * scaleRatio, this._initialHeight * scale);
|
const frameHeight = Math.max(frameRect.height * scaleRatio, this._initialHeight * contentScale);
|
||||||
|
|
||||||
const horizontal = (writingMode === 'horizontal-tb' || this._verticalTextPosition === 'default');
|
const horizontal = (writingMode === 'horizontal-tb' || this._verticalTextPosition === 'default');
|
||||||
let preferAfter;
|
let preferAfter;
|
||||||
@ -700,8 +701,8 @@ class Popup extends EventDispatcher {
|
|||||||
horizontalOffset = this._horizontalOffset2;
|
horizontalOffset = this._horizontalOffset2;
|
||||||
verticalOffset = this._verticalOffset2;
|
verticalOffset = this._verticalOffset2;
|
||||||
}
|
}
|
||||||
horizontalOffset *= scale;
|
horizontalOffset *= contentScale;
|
||||||
verticalOffset *= scale;
|
verticalOffset *= contentScale;
|
||||||
|
|
||||||
let best = null;
|
let best = null;
|
||||||
const sourceRectsLength = sourceRects.length;
|
const sourceRectsLength = sourceRects.length;
|
||||||
@ -955,4 +956,43 @@ class Popup extends EventDispatcher {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the bounding client rect for the frame element, with a coordinate conversion applied.
|
||||||
|
* @returns {DOMRect} The rectangle of the frame.
|
||||||
|
*/
|
||||||
|
_getFrameBoundingClientRect() {
|
||||||
|
return DocumentUtil.convertRectZoomCoordinates(this._frame.getBoundingClientRect(), this._container);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the coordinate space of source rectangles.
|
||||||
|
* @param {Rect[]} sourceRects The list of rectangles to convert.
|
||||||
|
* @returns {Rect[]} Either an updated list of rectangles, or `sourceRects` if no change is required.
|
||||||
|
*/
|
||||||
|
_convertSourceRectsCoordinateSpace(sourceRects) {
|
||||||
|
let scale = DocumentUtil.computeZoomScale(this._container);
|
||||||
|
if (scale === 1) { return sourceRects; }
|
||||||
|
scale = 1 / scale;
|
||||||
|
const sourceRects2 = [];
|
||||||
|
for (const rect of sourceRects) {
|
||||||
|
sourceRects2.push(this._createScaledRect(rect, scale));
|
||||||
|
}
|
||||||
|
return sourceRects2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a scaled rectangle.
|
||||||
|
* @param {Rect} rect The rectangle to scale.
|
||||||
|
* @param {number} scale The scale factor.
|
||||||
|
* @returns {Rect} A new rectangle which has been scaled.
|
||||||
|
*/
|
||||||
|
_createScaledRect(rect, scale) {
|
||||||
|
return {
|
||||||
|
left: rect.left * scale,
|
||||||
|
top: rect.top * scale,
|
||||||
|
right: rect.right * scale,
|
||||||
|
bottom: rect.bottom * scale
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -980,10 +980,12 @@ class OptionsUtil {
|
|||||||
_updateVersion20(options) {
|
_updateVersion20(options) {
|
||||||
// Version 20 changes:
|
// Version 20 changes:
|
||||||
// Added anki.downloadTimeout.
|
// Added anki.downloadTimeout.
|
||||||
|
// Added scanning.normalizeCssZoom.
|
||||||
// Fixed general.popupTheme invalid default.
|
// Fixed general.popupTheme invalid default.
|
||||||
// Fixed general.popupOuterTheme invalid default.
|
// Fixed general.popupOuterTheme invalid default.
|
||||||
for (const profile of options.profiles) {
|
for (const profile of options.profiles) {
|
||||||
profile.options.anki.downloadTimeout = 0;
|
profile.options.anki.downloadTimeout = 0;
|
||||||
|
profile.options.scanning.normalizeCssZoom = true;
|
||||||
const {general} = profile.options;
|
const {general} = profile.options;
|
||||||
if (general.popupTheme === 'default') {
|
if (general.popupTheme === 'default') {
|
||||||
general.popupTheme = 'light';
|
general.popupTheme = 'light';
|
||||||
|
@ -367,6 +367,7 @@ class Display extends EventDispatcher {
|
|||||||
scanning: {
|
scanning: {
|
||||||
inputs: scanningOptions.inputs,
|
inputs: scanningOptions.inputs,
|
||||||
deepContentScan: scanningOptions.deepDomScan,
|
deepContentScan: scanningOptions.deepDomScan,
|
||||||
|
normalizeCssZoom: scanningOptions.normalizeCssZoom,
|
||||||
selectText: scanningOptions.selectText,
|
selectText: scanningOptions.selectText,
|
||||||
delay: scanningOptions.delay,
|
delay: scanningOptions.delay,
|
||||||
touchInputEnabled: scanningOptions.touchInputEnabled,
|
touchInputEnabled: scanningOptions.touchInputEnabled,
|
||||||
@ -1532,6 +1533,7 @@ class Display extends EventDispatcher {
|
|||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
deepContentScan: scanningOptions.deepDomScan,
|
deepContentScan: scanningOptions.deepDomScan,
|
||||||
|
normalizeCssZoom: scanningOptions.normalizeCssZoom,
|
||||||
selectText: false,
|
selectText: false,
|
||||||
delay: scanningOptions.delay,
|
delay: scanningOptions.delay,
|
||||||
touchInputEnabled: false,
|
touchInputEnabled: false,
|
||||||
|
@ -24,10 +24,9 @@
|
|||||||
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, normalizeCssZoom}) {
|
||||||
const elements = this._getElementsFromPoint(x, y, deepContentScan);
|
const elements = this._getElementsFromPoint(x, y, deepContentScan);
|
||||||
let imposter = null;
|
let imposter = null;
|
||||||
let imposterContainer = null;
|
let imposterContainer = null;
|
||||||
@ -52,7 +51,7 @@ class DocumentUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const range = this._caretRangeFromPointExt(x, y, deepContentScan ? elements : []);
|
const range = this._caretRangeFromPointExt(x, y, deepContentScan ? elements : [], normalizeCssZoom);
|
||||||
if (range !== null) {
|
if (range !== null) {
|
||||||
if (imposter !== null) {
|
if (imposter !== null) {
|
||||||
this._setImposterStyle(imposterContainer.style, 'z-index', '-2147483646');
|
this._setImposterStyle(imposterContainer.style, 'z-index', '-2147483646');
|
||||||
@ -175,6 +174,60 @@ class DocumentUtil {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the scaling adjustment that is necessary for client space coordinates based on the
|
||||||
|
* CSS zoom level.
|
||||||
|
* @param {Node} node A node in the document.
|
||||||
|
* @returns {number} The scaling factor.
|
||||||
|
*/
|
||||||
|
static computeZoomScale(node) {
|
||||||
|
if (this._cssZoomSupported === null) {
|
||||||
|
this._cssZoomSupported = (typeof document.createElement('div').style.zoom === 'string');
|
||||||
|
}
|
||||||
|
if (!this._cssZoomSupported) { return 1; }
|
||||||
|
// documentElement must be excluded because the computer style of its zoom property is inconsistent.
|
||||||
|
// * If CSS `:root{zoom:X;}` is specified, the computed zoom will always report `X`.
|
||||||
|
// * If CSS `:root{zoom:X;}` is not specified, the computed zoom report the browser's zoom level.
|
||||||
|
// Therefor, if CSS root zoom is specified as a value other than 1, the adjusted {x, y} values
|
||||||
|
// would be incorrect, which is not new behaviour.
|
||||||
|
let scale = 1;
|
||||||
|
const {ELEMENT_NODE, DOCUMENT_FRAGMENT_NODE} = Node;
|
||||||
|
const {documentElement} = document;
|
||||||
|
for (; node !== null && node !== documentElement; node = node.parentNode) {
|
||||||
|
const {nodeType} = node;
|
||||||
|
if (nodeType === DOCUMENT_FRAGMENT_NODE) {
|
||||||
|
const {host} = node;
|
||||||
|
if (typeof host !== 'undefined') {
|
||||||
|
node = host;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
} else if (nodeType !== ELEMENT_NODE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let {zoom} = getComputedStyle(node);
|
||||||
|
if (typeof zoom !== 'string') { continue; }
|
||||||
|
zoom = Number.parseFloat(zoom);
|
||||||
|
if (!Number.isFinite(zoom) || zoom === 0) { continue; }
|
||||||
|
scale *= zoom;
|
||||||
|
}
|
||||||
|
return scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
static convertRectZoomCoordinates(rect, node) {
|
||||||
|
const scale = this.computeZoomScale(node);
|
||||||
|
return (scale === 1 ? rect : new DOMRect(rect.left * scale, rect.top * scale, rect.width * scale, rect.height * scale));
|
||||||
|
}
|
||||||
|
|
||||||
|
static convertMultipleRectZoomCoordinates(rects, node) {
|
||||||
|
const scale = this.computeZoomScale(node);
|
||||||
|
if (scale === 1) { return rects; }
|
||||||
|
const results = [];
|
||||||
|
for (const rect of rects) {
|
||||||
|
results.push(new DOMRect(rect.left * scale, rect.top * scale, rect.width * scale, rect.height * scale));
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
static isPointInRect(x, y, rect) {
|
static isPointInRect(x, y, rect) {
|
||||||
return (
|
return (
|
||||||
x >= rect.left && x < rect.right &&
|
x >= rect.left && x < rect.right &&
|
||||||
@ -435,7 +488,7 @@ class DocumentUtil {
|
|||||||
return e !== null ? [e] : [];
|
return e !== null ? [e] : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
_isPointInRange(x, y, range) {
|
_isPointInRange(x, y, range, normalizeCssZoom) {
|
||||||
// Require a text node to start
|
// Require a text node to start
|
||||||
const {startContainer} = range;
|
const {startContainer} = range;
|
||||||
if (startContainer.nodeType !== Node.TEXT_NODE) {
|
if (startContainer.nodeType !== Node.TEXT_NODE) {
|
||||||
@ -443,8 +496,10 @@ class DocumentUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert CSS zoom coordinates
|
// Convert CSS zoom coordinates
|
||||||
if (this._cssZoomSupported) {
|
if (normalizeCssZoom) {
|
||||||
({x, y} = this._convertCssZoomCoordinates(x, y, startContainer));
|
const scale = DocumentUtil.computeZoomScale(startContainer);
|
||||||
|
x /= scale;
|
||||||
|
y /= scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan forward
|
// Scan forward
|
||||||
@ -583,7 +638,7 @@ class DocumentUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_caretRangeFromPointExt(x, y, elements) {
|
_caretRangeFromPointExt(x, y, elements, normalizeCssZoom) {
|
||||||
let previousStyles = null;
|
let previousStyles = null;
|
||||||
try {
|
try {
|
||||||
let i = 0;
|
let i = 0;
|
||||||
@ -596,7 +651,7 @@ class DocumentUtil {
|
|||||||
|
|
||||||
const startContainer = range.startContainer;
|
const startContainer = range.startContainer;
|
||||||
if (startContinerPre !== startContainer) {
|
if (startContinerPre !== startContainer) {
|
||||||
if (this._isPointInRange(x, y, range)) {
|
if (this._isPointInRange(x, y, range, normalizeCssZoom)) {
|
||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
startContinerPre = startContainer;
|
startContinerPre = startContainer;
|
||||||
@ -668,18 +723,6 @@ 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};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// eslint-disable-next-line no-underscore-dangle
|
||||||
|
DocumentUtil._cssZoomSupported = null;
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* global
|
/* global
|
||||||
|
* DocumentUtil
|
||||||
* StringUtil
|
* StringUtil
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -95,11 +96,11 @@ class TextSourceElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getRect() {
|
getRect() {
|
||||||
return this._element.getBoundingClientRect();
|
return DocumentUtil.convertRectZoomCoordinates(this._element.getBoundingClientRect(), this._element);
|
||||||
}
|
}
|
||||||
|
|
||||||
getRects() {
|
getRects() {
|
||||||
return this._element.getClientRects();
|
return DocumentUtil.convertMultipleRectZoomCoordinates(this._element.getClientRects(), this._element);
|
||||||
}
|
}
|
||||||
|
|
||||||
getWritingMode() {
|
getWritingMode() {
|
||||||
|
@ -91,11 +91,11 @@ class TextSourceRange {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getRect() {
|
getRect() {
|
||||||
return this._range.getBoundingClientRect();
|
return DocumentUtil.convertRectZoomCoordinates(this._range.getBoundingClientRect(), this._range.startContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
getRects() {
|
getRects() {
|
||||||
return this._range.getClientRects();
|
return DocumentUtil.convertMultipleRectZoomCoordinates(this._range.getClientRects(), this._range.startContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
getWritingMode() {
|
getWritingMode() {
|
||||||
|
@ -54,6 +54,7 @@ class TextScanner extends EventDispatcher {
|
|||||||
this._selectionRestoreInfo = null;
|
this._selectionRestoreInfo = null;
|
||||||
|
|
||||||
this._deepContentScan = false;
|
this._deepContentScan = false;
|
||||||
|
this._normalizeCssZoom = true;
|
||||||
this._selectText = false;
|
this._selectText = false;
|
||||||
this._delay = 0;
|
this._delay = 0;
|
||||||
this._touchInputEnabled = false;
|
this._touchInputEnabled = false;
|
||||||
@ -151,6 +152,7 @@ class TextScanner extends EventDispatcher {
|
|||||||
setOptions({
|
setOptions({
|
||||||
inputs,
|
inputs,
|
||||||
deepContentScan,
|
deepContentScan,
|
||||||
|
normalizeCssZoom,
|
||||||
selectText,
|
selectText,
|
||||||
delay,
|
delay,
|
||||||
touchInputEnabled,
|
touchInputEnabled,
|
||||||
@ -167,6 +169,9 @@ class TextScanner extends EventDispatcher {
|
|||||||
if (typeof deepContentScan === 'boolean') {
|
if (typeof deepContentScan === 'boolean') {
|
||||||
this._deepContentScan = deepContentScan;
|
this._deepContentScan = deepContentScan;
|
||||||
}
|
}
|
||||||
|
if (typeof normalizeCssZoom === 'boolean') {
|
||||||
|
this._normalizeCssZoom = normalizeCssZoom;
|
||||||
|
}
|
||||||
if (typeof selectText === 'boolean') {
|
if (typeof selectText === 'boolean') {
|
||||||
this._selectText = selectText;
|
this._selectText = selectText;
|
||||||
}
|
}
|
||||||
@ -932,7 +937,10 @@ class TextScanner extends EventDispatcher {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const textSource = this._documentUtil.getRangeFromPoint(x, y, this._deepContentScan);
|
const textSource = this._documentUtil.getRangeFromPoint(x, y, {
|
||||||
|
deepContentScan: this._deepContentScan,
|
||||||
|
normalizeCssZoom: this._normalizeCssZoom
|
||||||
|
});
|
||||||
try {
|
try {
|
||||||
await this._search(textSource, searchTerms, searchKanji, inputInfo);
|
await this._search(textSource, searchTerms, searchKanji, inputInfo);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -511,6 +511,34 @@
|
|||||||
<label class="toggle"><input type="checkbox" data-setting="scanning.deepDomScan"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label>
|
<label class="toggle"><input type="checkbox" data-setting="scanning.deepDomScan"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label>
|
||||||
</div>
|
</div>
|
||||||
</div></div>
|
</div></div>
|
||||||
|
<div class="settings-item advanced-only">
|
||||||
|
<div class="settings-item-inner">
|
||||||
|
<div class="settings-item-left">
|
||||||
|
<div class="settings-item-label">Normalize CSS zoom</div>
|
||||||
|
<div class="settings-item-description">
|
||||||
|
Correct the pointer location on webpages where CSS <code>zoom</code> is used.
|
||||||
|
<a tabindex="0" class="more-toggle more-only" data-parent-distance="4">More…</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="settings-item-right">
|
||||||
|
<label class="toggle"><input type="checkbox" data-setting="scanning.normalizeCssZoom"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="settings-item-children more" hidden>
|
||||||
|
<p>
|
||||||
|
The non-standard CSS <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/zoom" target="_blank" rel="noopener noreferrer"><code>zoom</code></a> property interferes with the normal calculation of the pointer coordinates when scanning webpages. This property is discouraged from being used and its use is rare, but some webpages may still use it.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Enabling this option, which is on by default, will take the value of this property into account when scanning webpage content. It is currently put behind an option in case there are unforeseen negative side effects.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
This setting does not have any effect in Firefox, as it does not implement the <code>zoom</code> property.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a tabindex="0" class="more-toggle" data-parent-distance="3">Less…</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="settings-item advanced-only">
|
<div class="settings-item advanced-only">
|
||||||
<div class="settings-item-inner">
|
<div class="settings-item-inner">
|
||||||
<div class="settings-item-left">
|
<div class="settings-item-left">
|
||||||
|
@ -167,7 +167,10 @@ async function testDocumentTextScanningFunctions(dom, {DocumentUtil, TextSourceR
|
|||||||
|
|
||||||
// Test docRangeFromPoint
|
// Test docRangeFromPoint
|
||||||
const documentUtil = new DocumentUtil();
|
const documentUtil = new DocumentUtil();
|
||||||
const source = documentUtil.getRangeFromPoint(0, 0, false);
|
const source = documentUtil.getRangeFromPoint(0, 0, {
|
||||||
|
deepContentScan: false,
|
||||||
|
normalizeCssZoom: true
|
||||||
|
});
|
||||||
switch (resultType) {
|
switch (resultType) {
|
||||||
case 'TextSourceRange':
|
case 'TextSourceRange':
|
||||||
assert.strictEqual(getPrototypeOfOrNull(source), TextSourceRange.prototype);
|
assert.strictEqual(getPrototypeOfOrNull(source), TextSourceRange.prototype);
|
||||||
|
@ -347,6 +347,7 @@ function createProfileOptionsUpdatedTestData1() {
|
|||||||
matchTypePrefix: false,
|
matchTypePrefix: false,
|
||||||
hidePopupOnCursorExit: false,
|
hidePopupOnCursorExit: false,
|
||||||
hidePopupOnCursorExitDelay: 0,
|
hidePopupOnCursorExitDelay: 0,
|
||||||
|
normalizeCssZoom: true,
|
||||||
preventMiddleMouse: {
|
preventMiddleMouse: {
|
||||||
onWebPages: false,
|
onWebPages: false,
|
||||||
onPopupPages: false,
|
onPopupPages: false,
|
||||||
|
Loading…
Reference in New Issue
Block a user