diff --git a/test/integration/text_layer_spec.mjs b/test/integration/text_layer_spec.mjs index 1bb8099fe..063c1969e 100644 --- a/test/integration/text_layer_spec.mjs +++ b/test/integration/text_layer_spec.mjs @@ -757,7 +757,7 @@ describe("Text layer", () => { .withContext(`In ${browserName}`) .toHaveRoughlySelected( "rs as the railway projects under\n" + - "development enter the construction phase (estimated at" + "development enter the construction phase (estimated a" ); }) ); @@ -801,7 +801,7 @@ describe("Text layer", () => { .withContext(`In ${browserName}`) .toHaveRoughlySelected( "quarters as the railway projects under\n" + - "development enter the construction phase (estimated at around" + "development enter the construction phase (estimated at" ); }) ); diff --git a/web/text_layer_builder.js b/web/text_layer_builder.js index 62c8e5fd3..0275e961b 100644 --- a/web/text_layer_builder.js +++ b/web/text_layer_builder.js @@ -264,7 +264,7 @@ class TextLayerBuilder { if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) { // eslint-disable-next-line no-var - var isFirefox, prevRange; + var isFirefoxOrModernChromium, prevRange; } document.addEventListener( @@ -304,22 +304,38 @@ class TextLayerBuilder { if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) { return; } - if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("CHROME")) { - isFirefox ??= - getComputedStyle( - this.#textLayers.values().next().value - ).getPropertyValue("-moz-user-select") === "none"; + if (isFirefoxOrModernChromium === undefined) { + if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("CHROME")) { + isFirefoxOrModernChromium = + getComputedStyle( + this.#textLayers.values().next().value + ).getPropertyValue("-moz-user-select") === "none"; + } + if ( + (typeof PDFJSDev !== "undefined" && PDFJSDev.test("CHROME")) || + !isFirefoxOrModernChromium + ) { + // navigator.userAgentData is only available in secure contexts + const chromiumVersion = navigator.userAgentData + ? navigator.userAgentData.brands.find( + ({ brand }) => brand === "Chromium" + )?.version + : /\bChrome\/(\d+)\b/.exec(navigator.userAgent)?.[1]; - if (isFirefox) { - return; + isFirefoxOrModernChromium = + !!chromiumVersion && parseInt(chromiumVersion, 10) >= 148; } } - // In non-Firefox browsers, when hovering over an empty space (thus, - // on .endOfContent), the selection will expand to cover all the - // text between the current selection and .endOfContent. By moving - // .endOfContent to right after (or before, depending on which side - // of the selection the user is moving), we limit the selection jump - // to at most cover the enteirety of the where the selection + if (isFirefoxOrModernChromium) { + return; + } + + // In browsers other than Firefox or Chromium 148+, when hovering over + // an empty space (thus, on .endOfContent), the selection will expand to + // cover all the text between the current selection and .endOfContent. + // By moving .endOfContent to right after (or before, depending on which + // side of the selection the user is moving), we limit the selection + // jump to at most cover the entirety of the where the selection // is being modified. const range = selection.getRangeAt(0); const modifyStart =