diff --git a/extensions/chromium/options/migration.js b/extensions/chromium/options/migration.js index 9d73ef205..dd8fb6ef7 100644 --- a/extensions/chromium/options/migration.js +++ b/extensions/chromium/options/migration.js @@ -109,17 +109,10 @@ limitations under the License. } // Migration code for https://github.com/mozilla/pdf.js/pull/9479. if (typeof items.disableTextLayer === "boolean") { - var textLayerMode = 1; if (items.disableTextLayer) { - textLayerMode = 0; - } else if (items.enhanceTextSelection) { - textLayerMode = 2; - } - if (textLayerMode !== 1) { - // Overwrite if computed textLayerMode is not the default value (1). storageSync.set( { - textLayerMode, + textLayerMode: 0, }, function () { if (!chrome.runtime.lastError) { diff --git a/extensions/chromium/options/options.html b/extensions/chromium/options/options.html index 059e5700d..8d5661fcb 100644 --- a/extensions/chromium/options/options.html +++ b/extensions/chromium/options/options.html @@ -126,7 +126,6 @@ body { diff --git a/extensions/chromium/preferences_schema.json b/extensions/chromium/preferences_schema.json index 799b0eaed..798e32956 100644 --- a/extensions/chromium/preferences_schema.json +++ b/extensions/chromium/preferences_schema.json @@ -102,19 +102,13 @@ "type": "boolean", "default": false }, - "enhanceTextSelection": { - "description": "DEPRECATED. Set textLayerMode to 2 to use the enhanced text selection layer by default.", - "type": "boolean", - "default": false - }, "textLayerMode": { "title": "Text layer mode", - "description": "Controls if the text layer is enabled, and the selection mode that is used.\n 0 = Disabled.\n 1 = Enabled.\n 2 = (Experimental) Enabled, with enhanced text selection.", + "description": "Controls if the text layer is enabled, and the selection mode that is used.\n 0 = Disabled.\n 1 = Enabled.", "type": "integer", "enum": [ 0, - 1, - 2 + 1 ], "default": 1 }, diff --git a/src/display/text_layer.js b/src/display/text_layer.js index 9f5756dd0..031e50341 100644 --- a/src/display/text_layer.js +++ b/src/display/text_layer.js @@ -18,7 +18,6 @@ import { createPromiseCapability, Util, } from "../shared/util.js"; -import { deprecated } from "./display_utils.js"; /** * Text layer render parameters. @@ -40,15 +39,12 @@ import { deprecated } from "./display_utils.js"; * This is output and shall initially be set to an empty array. * @property {number} [timeout] - Delay in milliseconds before rendering of the * text runs occurs. - * @property {boolean} [enhanceTextSelection] - Whether to turn on the text - * selection enhancement. */ const MAX_TEXT_DIVS_TO_RENDER = 100000; const DEFAULT_FONT_SIZE = 30; const DEFAULT_FONT_ASCENT = 0.8; const ascentCache = new Map(); -const AllWhitespaceRegexp = /^\s+$/g; function getAscent(fontFamily, ctx) { const cachedAscent = ascentCache.get(fontFamily); @@ -120,28 +116,13 @@ function getAscent(fontFamily, ctx) { function appendText(task, geom, styles, ctx) { // Initialize all used properties to keep the caches monomorphic. const textDiv = document.createElement("span"); - const textDivProperties = task._enhanceTextSelection - ? { - angle: 0, - canvasWidth: 0, - hasText: geom.str !== "", - hasEOL: geom.hasEOL, - originalTransform: null, - paddingBottom: 0, - paddingLeft: 0, - paddingRight: 0, - paddingTop: 0, - scale: 1, - fontSize: 0, - } - : { - angle: 0, - canvasWidth: 0, - hasText: geom.str !== "", - hasEOL: geom.hasEOL, - fontSize: 0, - }; - + const textDivProperties = { + angle: 0, + canvasWidth: 0, + hasText: geom.str !== "", + hasEOL: geom.hasEOL, + fontSize: 0, + }; task._textDivs.push(textDiv); const tx = Util.transform(task._viewport.transform, geom.transform); @@ -189,10 +170,7 @@ function appendText(task, geom, styles, ctx) { // little effect on text highlighting. This makes scrolling on docs with // lots of such divs a lot faster. let shouldScaleText = false; - if ( - geom.str.length > 1 || - (task._enhanceTextSelection && AllWhitespaceRegexp.test(geom.str)) - ) { + if (geom.str.length > 1) { shouldScaleText = true; } else if (geom.str !== " " && geom.transform[0] !== geom.transform[3]) { const absScaleX = Math.abs(geom.transform[0]), @@ -217,36 +195,6 @@ function appendText(task, geom, styles, ctx) { if (task._textContentStream) { task._layoutText(textDiv); } - - if (task._enhanceTextSelection && textDivProperties.hasText) { - let angleCos = 1, - angleSin = 0; - if (angle !== 0) { - angleCos = Math.cos(angle); - angleSin = Math.sin(angle); - } - const divWidth = - (style.vertical ? geom.height : geom.width) * task._viewport.scale; - const divHeight = fontHeight; - - let m, b; - if (angle !== 0) { - m = [angleCos, angleSin, -angleSin, angleCos, left, top]; - b = Util.getAxialAlignedBoundingBox([0, 0, divWidth, divHeight], m); - } else { - b = [left, top, left + divWidth, top + divHeight]; - } - - task._bounds.push({ - left: b[0], - top: b[1], - right: b[2], - bottom: b[3], - div: textDiv, - size: [divWidth, divHeight], - m, - }); - } } function render(task) { @@ -275,295 +223,6 @@ function render(task) { capability.resolve(); } -function findPositiveMin(ts, offset, count) { - let result = 0; - for (let i = 0; i < count; i++) { - const t = ts[offset++]; - if (t > 0) { - result = result ? Math.min(t, result) : t; - } - } - return result; -} - -function expand(task) { - const bounds = task._bounds; - const viewport = task._viewport; - - const expanded = expandBounds(viewport.width, viewport.height, bounds); - for (let i = 0; i < expanded.length; i++) { - const div = bounds[i].div; - const divProperties = task._textDivProperties.get(div); - if (divProperties.angle === 0) { - divProperties.paddingLeft = bounds[i].left - expanded[i].left; - divProperties.paddingTop = bounds[i].top - expanded[i].top; - divProperties.paddingRight = expanded[i].right - bounds[i].right; - divProperties.paddingBottom = expanded[i].bottom - bounds[i].bottom; - task._textDivProperties.set(div, divProperties); - continue; - } - // Box is rotated -- trying to find padding so rotated div will not - // exceed its expanded bounds. - const e = expanded[i], - b = bounds[i]; - const m = b.m, - c = m[0], - s = m[1]; - // Finding intersections with expanded box. - const points = [[0, 0], [0, b.size[1]], [b.size[0], 0], b.size]; - const ts = new Float64Array(64); - for (let j = 0, jj = points.length; j < jj; j++) { - const t = Util.applyTransform(points[j], m); - ts[j + 0] = c && (e.left - t[0]) / c; - ts[j + 4] = s && (e.top - t[1]) / s; - ts[j + 8] = c && (e.right - t[0]) / c; - ts[j + 12] = s && (e.bottom - t[1]) / s; - - ts[j + 16] = s && (e.left - t[0]) / -s; - ts[j + 20] = c && (e.top - t[1]) / c; - ts[j + 24] = s && (e.right - t[0]) / -s; - ts[j + 28] = c && (e.bottom - t[1]) / c; - - ts[j + 32] = c && (e.left - t[0]) / -c; - ts[j + 36] = s && (e.top - t[1]) / -s; - ts[j + 40] = c && (e.right - t[0]) / -c; - ts[j + 44] = s && (e.bottom - t[1]) / -s; - - ts[j + 48] = s && (e.left - t[0]) / s; - ts[j + 52] = c && (e.top - t[1]) / -c; - ts[j + 56] = s && (e.right - t[0]) / s; - ts[j + 60] = c && (e.bottom - t[1]) / -c; - } - // Not based on math, but to simplify calculations, using cos and sin - // absolute values to not exceed the box (it can but insignificantly). - const boxScale = 1 + Math.min(Math.abs(c), Math.abs(s)); - divProperties.paddingLeft = findPositiveMin(ts, 32, 16) / boxScale; - divProperties.paddingTop = findPositiveMin(ts, 48, 16) / boxScale; - divProperties.paddingRight = findPositiveMin(ts, 0, 16) / boxScale; - divProperties.paddingBottom = findPositiveMin(ts, 16, 16) / boxScale; - task._textDivProperties.set(div, divProperties); - } -} - -function expandBounds(width, height, boxes) { - const bounds = boxes.map(function (box, i) { - return { - x1: box.left, - y1: box.top, - x2: box.right, - y2: box.bottom, - index: i, - x1New: undefined, - x2New: undefined, - }; - }); - expandBoundsLTR(width, bounds); - - const expanded = new Array(boxes.length); - for (const b of bounds) { - const i = b.index; - expanded[i] = { - left: b.x1New, - top: 0, - right: b.x2New, - bottom: 0, - }; - } - - // Rotating on 90 degrees and extending extended boxes. Reusing the bounds - // array and objects. - boxes.map(function (box, i) { - const e = expanded[i], - b = bounds[i]; - b.x1 = box.top; - b.y1 = width - e.right; - b.x2 = box.bottom; - b.y2 = width - e.left; - b.index = i; - b.x1New = undefined; - b.x2New = undefined; - }); - expandBoundsLTR(height, bounds); - - for (const b of bounds) { - const i = b.index; - expanded[i].top = b.x1New; - expanded[i].bottom = b.x2New; - } - return expanded; -} - -function expandBoundsLTR(width, bounds) { - // Sorting by x1 coordinate and walk by the bounds in the same order. - bounds.sort(function (a, b) { - return a.x1 - b.x1 || a.index - b.index; - }); - - // First we see on the horizon is a fake boundary. - const fakeBoundary = { - x1: -Infinity, - y1: -Infinity, - x2: 0, - y2: Infinity, - index: -1, - x1New: 0, - x2New: 0, - }; - const horizon = [ - { - start: -Infinity, - end: Infinity, - boundary: fakeBoundary, - }, - ]; - - for (const boundary of bounds) { - // Searching for the affected part of horizon. - // TODO red-black tree or simple binary search - let i = 0; - while (i < horizon.length && horizon[i].end <= boundary.y1) { - i++; - } - let j = horizon.length - 1; - while (j >= 0 && horizon[j].start >= boundary.y2) { - j--; - } - - let horizonPart, affectedBoundary; - let q, - k, - maxXNew = -Infinity; - for (q = i; q <= j; q++) { - horizonPart = horizon[q]; - affectedBoundary = horizonPart.boundary; - let xNew; - if (affectedBoundary.x2 > boundary.x1) { - // In the middle of the previous element, new x shall be at the - // boundary start. Extending if further if the affected boundary - // placed on top of the current one. - xNew = - affectedBoundary.index > boundary.index - ? affectedBoundary.x1New - : boundary.x1; - } else if (affectedBoundary.x2New === undefined) { - // We have some space in between, new x in middle will be a fair - // choice. - xNew = (affectedBoundary.x2 + boundary.x1) / 2; - } else { - // Affected boundary has x2new set, using it as new x. - xNew = affectedBoundary.x2New; - } - if (xNew > maxXNew) { - maxXNew = xNew; - } - } - - // Set new x1 for current boundary. - boundary.x1New = maxXNew; - - // Adjusts new x2 for the affected boundaries. - for (q = i; q <= j; q++) { - horizonPart = horizon[q]; - affectedBoundary = horizonPart.boundary; - if (affectedBoundary.x2New === undefined) { - // Was not set yet, choosing new x if possible. - if (affectedBoundary.x2 > boundary.x1) { - // Current and affected boundaries intersect. If affected boundary - // is placed on top of the current, shrinking the affected. - if (affectedBoundary.index > boundary.index) { - affectedBoundary.x2New = affectedBoundary.x2; - } - } else { - affectedBoundary.x2New = maxXNew; - } - } else if (affectedBoundary.x2New > maxXNew) { - // Affected boundary is touching new x, pushing it back. - affectedBoundary.x2New = Math.max(maxXNew, affectedBoundary.x2); - } - } - - // Fixing the horizon. - const changedHorizon = []; - let lastBoundary = null; - for (q = i; q <= j; q++) { - horizonPart = horizon[q]; - affectedBoundary = horizonPart.boundary; - // Checking which boundary will be visible. - const useBoundary = - affectedBoundary.x2 > boundary.x2 ? affectedBoundary : boundary; - if (lastBoundary === useBoundary) { - // Merging with previous. - changedHorizon.at(-1).end = horizonPart.end; - } else { - changedHorizon.push({ - start: horizonPart.start, - end: horizonPart.end, - boundary: useBoundary, - }); - lastBoundary = useBoundary; - } - } - if (horizon[i].start < boundary.y1) { - changedHorizon[0].start = boundary.y1; - changedHorizon.unshift({ - start: horizon[i].start, - end: boundary.y1, - boundary: horizon[i].boundary, - }); - } - if (boundary.y2 < horizon[j].end) { - changedHorizon.at(-1).end = boundary.y2; - changedHorizon.push({ - start: boundary.y2, - end: horizon[j].end, - boundary: horizon[j].boundary, - }); - } - - // Set x2 new of boundary that is no longer visible (see overlapping case - // above). - // TODO more efficient, e.g. via reference counting. - for (q = i; q <= j; q++) { - horizonPart = horizon[q]; - affectedBoundary = horizonPart.boundary; - if (affectedBoundary.x2New !== undefined) { - continue; - } - let used = false; - for ( - k = i - 1; - !used && k >= 0 && horizon[k].start >= affectedBoundary.y1; - k-- - ) { - used = horizon[k].boundary === affectedBoundary; - } - for ( - k = j + 1; - !used && k < horizon.length && horizon[k].end <= affectedBoundary.y2; - k++ - ) { - used = horizon[k].boundary === affectedBoundary; - } - for (k = 0; !used && k < changedHorizon.length; k++) { - used = changedHorizon[k].boundary === affectedBoundary; - } - if (!used) { - affectedBoundary.x2New = maxXNew; - } - } - - Array.prototype.splice.apply(horizon, [i, j - i + 1, ...changedHorizon]); - } - - // Set new x2 for all unset boundaries. - for (const horizonPart of horizon) { - const affectedBoundary = horizonPart.boundary; - if (affectedBoundary.x2New === undefined) { - affectedBoundary.x2New = Math.max(width, affectedBoundary.x2); - } - } -} - class TextLayerRenderTask { constructor({ textContent, @@ -572,13 +231,7 @@ class TextLayerRenderTask { viewport, textDivs, textContentItemsStr, - enhanceTextSelection, }) { - if (enhanceTextSelection) { - deprecated( - "The `enhanceTextSelection` functionality will be removed in the future." - ); - } this._textContent = textContent; this._textContentStream = textContentStream; this._container = container; @@ -586,7 +239,6 @@ class TextLayerRenderTask { this._viewport = viewport; this._textDivs = textDivs || []; this._textContentItemsStr = textContentItemsStr || []; - this._enhanceTextSelection = !!enhanceTextSelection; this._fontInspectorEnabled = !!globalThis.FontInspector?.enabled; this._reader = null; @@ -604,10 +256,8 @@ class TextLayerRenderTask { // Always clean-up the temporary canvas once rendering is no longer pending. this._capability.promise .finally(() => { - if (!this._enhanceTextSelection) { - // The `textDiv` properties are no longer needed. - this._textDivProperties = null; - } + // The `textDiv` properties are no longer needed. + this._textDivProperties = null; if (this._layoutTextCtx) { // Zeroing the width and height cause Firefox to release graphics @@ -703,21 +353,15 @@ class TextLayerRenderTask { const { width } = this._layoutTextCtx.measureText(textDiv.textContent); if (width > 0) { - const scale = - (this._devicePixelRatio * textDivProperties.canvasWidth) / width; - if (this._enhanceTextSelection) { - textDivProperties.scale = scale; - } - transform = `scaleX(${scale})`; + transform = `scaleX(${ + (this._devicePixelRatio * textDivProperties.canvasWidth) / width + })`; } } if (textDivProperties.angle !== 0) { transform = `rotate(${textDivProperties.angle}deg) ${transform}`; } if (transform.length > 0) { - if (this._enhanceTextSelection) { - textDivProperties.originalTransform = transform; - } textDiv.style.transform = transform; } @@ -785,70 +429,6 @@ class TextLayerRenderTask { } }, this._capability.reject); } - - /** - * @param {boolean} [expandDivs] - */ - expandTextDivs(expandDivs = false) { - if (!this._enhanceTextSelection || !this._renderingDone) { - return; - } - if (this._bounds !== null) { - expand(this); - this._bounds = null; - } - const transformBuf = [], - paddingBuf = []; - - for (let i = 0, ii = this._textDivs.length; i < ii; i++) { - const div = this._textDivs[i]; - const divProps = this._textDivProperties.get(div); - - if (!divProps.hasText) { - continue; - } - if (expandDivs) { - transformBuf.length = 0; - paddingBuf.length = 0; - - if (divProps.originalTransform) { - transformBuf.push(divProps.originalTransform); - } - if (divProps.paddingTop > 0) { - paddingBuf.push(`${divProps.paddingTop}px`); - transformBuf.push(`translateY(${-divProps.paddingTop}px)`); - } else { - paddingBuf.push(0); - } - if (divProps.paddingRight > 0) { - paddingBuf.push(`${divProps.paddingRight / divProps.scale}px`); - } else { - paddingBuf.push(0); - } - if (divProps.paddingBottom > 0) { - paddingBuf.push(`${divProps.paddingBottom}px`); - } else { - paddingBuf.push(0); - } - if (divProps.paddingLeft > 0) { - paddingBuf.push(`${divProps.paddingLeft / divProps.scale}px`); - transformBuf.push( - `translateX(${-divProps.paddingLeft / divProps.scale}px)` - ); - } else { - paddingBuf.push(0); - } - - div.style.padding = paddingBuf.join(" "); - if (transformBuf.length) { - div.style.transform = transformBuf.join(" "); - } - } else { - div.style.padding = null; - div.style.transform = divProps.originalTransform; - } - } - } } /** @@ -863,7 +443,6 @@ function renderTextLayer(renderParameters) { viewport: renderParameters.viewport, textDivs: renderParameters.textDivs, textContentItemsStr: renderParameters.textContentItemsStr, - enhanceTextSelection: renderParameters.enhanceTextSelection, }); task._render(renderParameters.timeout); return task; diff --git a/test/driver.js b/test/driver.js index 3543ba91a..9af37977c 100644 --- a/test/driver.js +++ b/test/driver.js @@ -244,7 +244,7 @@ class Rasterize { } } - static async textLayer(ctx, viewport, textContent, enhanceTextSelection) { + static async textLayer(ctx, viewport, textContent) { try { const { svg, foreignObject, style, div } = this.createContainer(viewport); div.className = "textLayer"; @@ -260,11 +260,8 @@ class Rasterize { textContent, container: div, viewport, - enhanceTextSelection, }); await task.promise; - - task.expandTextDivs(true); svg.append(foreignObject); await writeSVG(svg, ctx); @@ -674,7 +671,6 @@ class Driver { textLayerCanvas.height ); textLayerContext.scale(outputScale, outputScale); - const enhanceText = !!task.enhance; // The text builder will draw its content on the test canvas initPromise = page .getTextContent({ @@ -684,8 +680,7 @@ class Driver { return Rasterize.textLayer( textLayerContext, viewport, - textContent, - enhanceText + textContent ); }); } else { diff --git a/test/test_manifest.json b/test/test_manifest.json index 797c19a87..0318eb54f 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -53,13 +53,6 @@ "rounds": 1, "type": "text" }, - { "id": "tracemonkey-text-enhance", - "file": "pdfs/tracemonkey.pdf", - "md5": "9a192d8b1a7dc652a19835f6f08098bd", - "rounds": 1, - "enhance": true, - "type": "text" - }, { "id": "tracemonkey-forced-colors-eq", "file": "pdfs/tracemonkey.pdf", "md5": "9a192d8b1a7dc652a19835f6f08098bd", @@ -596,28 +589,12 @@ "lastPage": 4, "type": "text" }, - { "id": "taro-text-enhance", - "file": "pdfs/TaroUTR50SortedList112.pdf", - "md5": "ce63eab622ff473a43f8a8de85ef8a46", - "link":true, - "rounds": 1, - "lastPage": 4, - "enhance": true, - "type": "text" - }, { "id": "rotated-text", "file": "pdfs/rotated.pdf", "md5": "aed187f53e969ccdcbab0bb4c59f9e46", "rounds": 1, "type": "text" }, - { "id": "rotated-text-enhance", - "file": "pdfs/rotated.pdf", - "md5": "aed187f53e969ccdcbab0bb4c59f9e46", - "rounds": 1, - "enhance": true, - "type": "text" - }, { "id": "issue3115", "file": "pdfs/issue3115r.pdf", diff --git a/web/base_viewer.js b/web/base_viewer.js index 5ff689585..456384077 100644 --- a/web/base_viewer.js +++ b/web/base_viewer.js @@ -110,9 +110,8 @@ function isValidAnnotationEditorMode(mode) { * @property {boolean} [removePageBorders] - Removes the border shadow around * the pages. The default value is `false`. * @property {number} [textLayerMode] - Controls if the text layer used for - * selection and searching is created, and if the improved text selection - * behaviour is enabled. The constants from {TextLayerMode} should be used. - * The default value is `TextLayerMode.ENABLE`. + * selection and searching is created. The constants from {TextLayerMode} + * should be used. The default value is `TextLayerMode.ENABLE`. * @property {number} [annotationMode] - Controls if the annotation layer is * created, and if interactive form elements or `AnnotationStorage`-data are * being rendered. The constants from {@link AnnotationMode} should be used; @@ -1636,7 +1635,6 @@ class BaseViewer { * @property {HTMLDivElement} textLayerDiv * @property {number} pageIndex * @property {PageViewport} viewport - * @property {boolean} [enhanceTextSelection] * @property {EventBus} eventBus * @property {TextHighlighter} highlighter * @property {TextAccessibilityManager} [accessibilityManager] @@ -1650,7 +1648,6 @@ class BaseViewer { textLayerDiv, pageIndex, viewport, - enhanceTextSelection = false, eventBus, highlighter, accessibilityManager = null, @@ -1660,9 +1657,6 @@ class BaseViewer { eventBus, pageIndex, viewport, - enhanceTextSelection: this.isInPresentationMode - ? false - : enhanceTextSelection, highlighter, accessibilityManager, }); diff --git a/web/chromecom.js b/web/chromecom.js index 64b5ee042..8334a6d9a 100644 --- a/web/chromecom.js +++ b/web/chromecom.js @@ -374,12 +374,8 @@ class ChromePreferences extends BasePreferences { delete items.enableHandToolOnLoad; // Migration code for https://github.com/mozilla/pdf.js/pull/9479. - if (items.textLayerMode !== 1) { - if (items.disableTextLayer) { - items.textLayerMode = 0; - } else if (items.enhanceTextSelection) { - items.textLayerMode = 2; - } + if (items.textLayerMode !== 1 && items.disableTextLayer) { + items.textLayerMode = 0; } delete items.disableTextLayer; delete items.enhanceTextSelection; diff --git a/web/default_factory.js b/web/default_factory.js index b4b09ef52..532002317 100644 --- a/web/default_factory.js +++ b/web/default_factory.js @@ -168,7 +168,6 @@ class DefaultTextLayerFactory { * @property {HTMLDivElement} textLayerDiv * @property {number} pageIndex * @property {PageViewport} viewport - * @property {boolean} [enhanceTextSelection] * @property {EventBus} eventBus * @property {TextHighlighter} highlighter * @property {TextAccessibilityManager} [accessibilityManager] @@ -182,7 +181,6 @@ class DefaultTextLayerFactory { textLayerDiv, pageIndex, viewport, - enhanceTextSelection = false, eventBus, highlighter, accessibilityManager = null, @@ -191,7 +189,6 @@ class DefaultTextLayerFactory { textLayerDiv, pageIndex, viewport, - enhanceTextSelection, eventBus, highlighter, accessibilityManager, diff --git a/web/interfaces.js b/web/interfaces.js index 71d9232cc..8131a6cfc 100644 --- a/web/interfaces.js +++ b/web/interfaces.js @@ -161,7 +161,6 @@ class IPDFTextLayerFactory { * @property {HTMLDivElement} textLayerDiv * @property {number} pageIndex * @property {PageViewport} viewport - * @property {boolean} [enhanceTextSelection] * @property {EventBus} eventBus * @property {TextHighlighter} highlighter * @property {TextAccessibilityManager} [accessibilityManager] @@ -175,7 +174,6 @@ class IPDFTextLayerFactory { textLayerDiv, pageIndex, viewport, - enhanceTextSelection = false, eventBus, highlighter, accessibilityManager, diff --git a/web/pdf_page_view.js b/web/pdf_page_view.js index cbeba8634..f8b4bdb8a 100644 --- a/web/pdf_page_view.js +++ b/web/pdf_page_view.js @@ -66,9 +66,8 @@ import { TextAccessibilityManager } from "./text_accessibility.js"; * @property {PDFRenderingQueue} [renderingQueue] - The rendering queue object. * @property {IPDFTextLayerFactory} [textLayerFactory] * @property {number} [textLayerMode] - Controls if the text layer used for - * selection and searching is created, and if the improved text selection - * behaviour is enabled. The constants from {TextLayerMode} should be used. - * The default value is `TextLayerMode.ENABLE`. + * selection and searching is created. The constants from {TextLayerMode} + * should be used. The default value is `TextLayerMode.ENABLE`. * @property {number} [annotationMode] - Controls if the annotation layer is * created, and if interactive form elements or `AnnotationStorage`-data are * being rendered. The constants from {@link AnnotationMode} should be used; @@ -717,8 +716,6 @@ class PDFPageView { textLayerDiv, pageIndex: this.id - 1, viewport: this.viewport, - enhanceTextSelection: - this.textLayerMode === TextLayerMode.ENABLE_ENHANCE, eventBus: this.eventBus, highlighter: this.textHighlighter, accessibilityManager: this._accessibilityManager, diff --git a/web/text_layer_builder.js b/web/text_layer_builder.js index 592dcd55c..070cd1b17 100644 --- a/web/text_layer_builder.js +++ b/web/text_layer_builder.js @@ -22,8 +22,6 @@ import { renderTextLayer } from "pdfjs-lib"; -const EXPAND_DIVS_TIMEOUT = 300; // ms - /** * @typedef {Object} TextLayerBuilderOptions * @property {HTMLDivElement} textLayerDiv - The text layer container. @@ -32,8 +30,6 @@ const EXPAND_DIVS_TIMEOUT = 300; // ms * @property {PageViewport} viewport - The viewport of the text layer. * @property {TextHighlighter} highlighter - Optional object that will handle * highlighting text from the find controller. - * @property {boolean} enhanceTextSelection - Option to turn on improved - * text selection. * @property {TextAccessibilityManager} [accessibilityManager] */ @@ -49,7 +45,6 @@ class TextLayerBuilder { pageIndex, viewport, highlighter = null, - enhanceTextSelection = false, accessibilityManager = null, }) { this.textLayerDiv = textLayerDiv; @@ -63,23 +58,17 @@ class TextLayerBuilder { this.textDivs = []; this.textLayerRenderTask = null; this.highlighter = highlighter; - this.enhanceTextSelection = enhanceTextSelection; this.accessibilityManager = accessibilityManager; - this._bindMouse(); + this.#bindMouse(); } - /** - * @private - */ - _finishRendering() { + #finishRendering() { this.renderingDone = true; - if (!this.enhanceTextSelection) { - const endOfContent = document.createElement("div"); - endOfContent.className = "endOfContent"; - this.textLayerDiv.append(endOfContent); - } + const endOfContent = document.createElement("div"); + endOfContent.className = "endOfContent"; + this.textLayerDiv.append(endOfContent); this.eventBus.dispatch("textlayerrendered", { source: this, @@ -113,12 +102,11 @@ class TextLayerBuilder { textDivs: this.textDivs, textContentItemsStr: this.textContentItemsStr, timeout, - enhanceTextSelection: this.enhanceTextSelection, }); this.textLayerRenderTask.promise.then( () => { this.textLayerDiv.append(textLayerFrag); - this._finishRendering(); + this.#finishRendering(); this.highlighter?.enable(); this.accessibilityManager?.enable(); }, @@ -154,26 +142,11 @@ class TextLayerBuilder { * Improves text selection by adding an additional div where the mouse was * clicked. This reduces flickering of the content if the mouse is slowly * dragged up or down. - * - * @private */ - _bindMouse() { + #bindMouse() { const div = this.textLayerDiv; - let expandDivsTimer = null; div.addEventListener("mousedown", evt => { - if (this.enhanceTextSelection && this.textLayerRenderTask) { - this.textLayerRenderTask.expandTextDivs(true); - if ( - (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) && - expandDivsTimer - ) { - clearTimeout(expandDivsTimer); - expandDivsTimer = null; - } - return; - } - const end = div.querySelector(".endOfContent"); if (!end) { return; @@ -185,11 +158,9 @@ class TextLayerBuilder { // However it does not work when selection is started on empty space. let adjustTop = evt.target !== div; if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) { - adjustTop = - adjustTop && - window - .getComputedStyle(end) - .getPropertyValue("-moz-user-select") !== "none"; + adjustTop &&= + getComputedStyle(end).getPropertyValue("-moz-user-select") !== + "none"; } if (adjustTop) { const divBounds = div.getBoundingClientRect(); @@ -201,20 +172,6 @@ class TextLayerBuilder { }); div.addEventListener("mouseup", () => { - if (this.enhanceTextSelection && this.textLayerRenderTask) { - if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) { - expandDivsTimer = setTimeout(() => { - if (this.textLayerRenderTask) { - this.textLayerRenderTask.expandTextDivs(false); - } - expandDivsTimer = null; - }, EXPAND_DIVS_TIMEOUT); - } else { - this.textLayerRenderTask.expandTextDivs(false); - } - return; - } - const end = div.querySelector(".endOfContent"); if (!end) { return; diff --git a/web/ui_utils.js b/web/ui_utils.js index 8f3256bde..054557a4f 100644 --- a/web/ui_utils.js +++ b/web/ui_utils.js @@ -57,7 +57,6 @@ const RendererType = const TextLayerMode = { DISABLE: 0, ENABLE: 1, - ENABLE_ENHANCE: 2, }; const ScrollMode = {