Remove unnecessary closure in src/display/text_layer.js
, and use standard classes
With modern JavaScript modules, where you explicitly list the properties that should be exported, it's no longer necessary to wrap all of the code in a closure.[1] This patch also tries to clean-up/improve a couple of the existing JSDoc-comments. --- [1] This reduces the size, even of the *built* `pdf.js` file, since there's now a lot less unnecessary whitespace.
This commit is contained in:
parent
52961197d3
commit
9a1758c6b8
@ -42,24 +42,13 @@ import {
|
|||||||
* selection enhancement.
|
* selection enhancement.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
const MAX_TEXT_DIVS_TO_RENDER = 100000;
|
||||||
* @typedef {Object} TextLayerRenderTask
|
const DEFAULT_FONT_SIZE = 30;
|
||||||
* @property {Promise<void>} promise
|
const DEFAULT_FONT_ASCENT = 0.8;
|
||||||
* @property {() => void} cancel
|
const ascentCache = new Map();
|
||||||
* @property {(expandDivs: boolean) => void} expandTextDivs
|
const AllWhitespaceRegexp = /^\s+$/g;
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
function getAscent(fontFamily, ctx) {
|
||||||
* @type {(renderParameters: TextLayerRenderParameters) => TextLayerRenderTask}
|
|
||||||
*/
|
|
||||||
const renderTextLayer = (function renderTextLayerClosure() {
|
|
||||||
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);
|
const cachedAscent = ascentCache.get(fontFamily);
|
||||||
if (cachedAscent) {
|
if (cachedAscent) {
|
||||||
return cachedAscent;
|
return cachedAscent;
|
||||||
@ -120,9 +109,9 @@ const renderTextLayer = (function renderTextLayerClosure() {
|
|||||||
|
|
||||||
ascentCache.set(fontFamily, DEFAULT_FONT_ASCENT);
|
ascentCache.set(fontFamily, DEFAULT_FONT_ASCENT);
|
||||||
return DEFAULT_FONT_ASCENT;
|
return DEFAULT_FONT_ASCENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
function appendText(task, geom, styles, ctx) {
|
function appendText(task, geom, styles, ctx) {
|
||||||
// Initialize all used properties to keep the caches monomorphic.
|
// Initialize all used properties to keep the caches monomorphic.
|
||||||
const textDiv = document.createElement("span");
|
const textDiv = document.createElement("span");
|
||||||
const textDivProperties = {
|
const textDivProperties = {
|
||||||
@ -138,7 +127,6 @@ const renderTextLayer = (function renderTextLayerClosure() {
|
|||||||
scale: 1,
|
scale: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
textDiv.textContent = geom.str;
|
|
||||||
task._textDivs.push(textDiv);
|
task._textDivs.push(textDiv);
|
||||||
|
|
||||||
const tx = Util.transform(task._viewport.transform, geom.transform);
|
const tx = Util.transform(task._viewport.transform, geom.transform);
|
||||||
@ -168,6 +156,7 @@ const renderTextLayer = (function renderTextLayerClosure() {
|
|||||||
// Keeps screen readers from pausing on every new text span.
|
// Keeps screen readers from pausing on every new text span.
|
||||||
textDiv.setAttribute("role", "presentation");
|
textDiv.setAttribute("role", "presentation");
|
||||||
|
|
||||||
|
textDiv.textContent = geom.str;
|
||||||
// geom.dir may be 'ttb' for vertical texts.
|
// geom.dir may be 'ttb' for vertical texts.
|
||||||
textDiv.dir = geom.dir;
|
textDiv.dir = geom.dir;
|
||||||
|
|
||||||
@ -241,9 +230,9 @@ const renderTextLayer = (function renderTextLayerClosure() {
|
|||||||
m,
|
m,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function render(task) {
|
function render(task) {
|
||||||
if (task._canceled) {
|
if (task._canceled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -267,9 +256,9 @@ const renderTextLayer = (function renderTextLayerClosure() {
|
|||||||
|
|
||||||
task._renderingDone = true;
|
task._renderingDone = true;
|
||||||
capability.resolve();
|
capability.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
function findPositiveMin(ts, offset, count) {
|
function findPositiveMin(ts, offset, count) {
|
||||||
let result = 0;
|
let result = 0;
|
||||||
for (let i = 0; i < count; i++) {
|
for (let i = 0; i < count; i++) {
|
||||||
const t = ts[offset++];
|
const t = ts[offset++];
|
||||||
@ -278,9 +267,9 @@ const renderTextLayer = (function renderTextLayerClosure() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function expand(task) {
|
function expand(task) {
|
||||||
const bounds = task._bounds;
|
const bounds = task._bounds;
|
||||||
const viewport = task._viewport;
|
const viewport = task._viewport;
|
||||||
|
|
||||||
@ -337,9 +326,9 @@ const renderTextLayer = (function renderTextLayerClosure() {
|
|||||||
divProperties.paddingBottom = findPositiveMin(ts, 16, 16) / boxScale;
|
divProperties.paddingBottom = findPositiveMin(ts, 16, 16) / boxScale;
|
||||||
task._textDivProperties.set(div, divProperties);
|
task._textDivProperties.set(div, divProperties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function expandBounds(width, height, boxes) {
|
function expandBounds(width, height, boxes) {
|
||||||
const bounds = boxes.map(function (box, i) {
|
const bounds = boxes.map(function (box, i) {
|
||||||
return {
|
return {
|
||||||
x1: box.left,
|
x1: box.left,
|
||||||
@ -385,9 +374,9 @@ const renderTextLayer = (function renderTextLayerClosure() {
|
|||||||
expanded[i].bottom = b.x2New;
|
expanded[i].bottom = b.x2New;
|
||||||
}
|
}
|
||||||
return expanded;
|
return expanded;
|
||||||
}
|
}
|
||||||
|
|
||||||
function expandBoundsLTR(width, bounds) {
|
function expandBoundsLTR(width, bounds) {
|
||||||
// Sorting by x1 coordinate and walk by the bounds in the same order.
|
// Sorting by x1 coordinate and walk by the bounds in the same order.
|
||||||
bounds.sort(function (a, b) {
|
bounds.sort(function (a, b) {
|
||||||
return a.x1 - b.x1 || a.index - b.index;
|
return a.x1 - b.x1 || a.index - b.index;
|
||||||
@ -559,19 +548,10 @@ const renderTextLayer = (function renderTextLayerClosure() {
|
|||||||
affectedBoundary.x2New = Math.max(width, affectedBoundary.x2);
|
affectedBoundary.x2New = Math.max(width, affectedBoundary.x2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
class TextLayerRenderTask {
|
||||||
* Text layer rendering task.
|
constructor({
|
||||||
*
|
|
||||||
* @param {TextContent} textContent
|
|
||||||
* @param {HTMLElement} container
|
|
||||||
* @param {PageViewport} viewport
|
|
||||||
* @param {Array} textDivs
|
|
||||||
* @param {boolean} enhanceTextSelection
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
function TextLayerRenderTask({
|
|
||||||
textContent,
|
textContent,
|
||||||
textContentStream,
|
textContentStream,
|
||||||
container,
|
container,
|
||||||
@ -616,12 +596,19 @@ const renderTextLayer = (function renderTextLayerClosure() {
|
|||||||
/* Avoid "Uncaught promise" messages in the console. */
|
/* Avoid "Uncaught promise" messages in the console. */
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
TextLayerRenderTask.prototype = {
|
|
||||||
|
/**
|
||||||
|
* Promise for textLayer rendering task completion.
|
||||||
|
* @type {Promise<void>}
|
||||||
|
*/
|
||||||
get promise() {
|
get promise() {
|
||||||
return this._capability.promise;
|
return this._capability.promise;
|
||||||
},
|
}
|
||||||
|
|
||||||
cancel: function TextLayer_cancel() {
|
/**
|
||||||
|
* Cancel rendering of the textLayer.
|
||||||
|
*/
|
||||||
|
cancel() {
|
||||||
this._canceled = true;
|
this._canceled = true;
|
||||||
if (this._reader) {
|
if (this._reader) {
|
||||||
this._reader.cancel(new AbortException("TextLayer task cancelled."));
|
this._reader.cancel(new AbortException("TextLayer task cancelled."));
|
||||||
@ -632,8 +619,11 @@ const renderTextLayer = (function renderTextLayerClosure() {
|
|||||||
this._renderTimer = null;
|
this._renderTimer = null;
|
||||||
}
|
}
|
||||||
this._capability.reject(new Error("TextLayer task cancelled."));
|
this._capability.reject(new Error("TextLayer task cancelled."));
|
||||||
},
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
_processItems(items, styleCache) {
|
_processItems(items, styleCache) {
|
||||||
for (let i = 0, len = items.length; i < len; i++) {
|
for (let i = 0, len = items.length; i < len; i++) {
|
||||||
if (items[i].str === undefined) {
|
if (items[i].str === undefined) {
|
||||||
@ -656,8 +646,11 @@ const renderTextLayer = (function renderTextLayerClosure() {
|
|||||||
this._textContentItemsStr.push(items[i].str);
|
this._textContentItemsStr.push(items[i].str);
|
||||||
appendText(this, items[i], styleCache, this._layoutTextCtx);
|
appendText(this, items[i], styleCache, this._layoutTextCtx);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
_layoutText(textDiv) {
|
_layoutText(textDiv) {
|
||||||
const textDivProperties = this._textDivProperties.get(textDiv);
|
const textDivProperties = this._textDivProperties.get(textDiv);
|
||||||
|
|
||||||
@ -700,9 +693,12 @@ const renderTextLayer = (function renderTextLayerClosure() {
|
|||||||
br.setAttribute("role", "presentation");
|
br.setAttribute("role", "presentation");
|
||||||
this._container.appendChild(br);
|
this._container.appendChild(br);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
_render: function TextLayer_render(timeout) {
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_render(timeout = 0) {
|
||||||
const capability = createPromiseCapability();
|
const capability = createPromiseCapability();
|
||||||
let styleCache = Object.create(null);
|
let styleCache = Object.create(null);
|
||||||
|
|
||||||
@ -759,9 +755,12 @@ const renderTextLayer = (function renderTextLayerClosure() {
|
|||||||
}, timeout);
|
}, timeout);
|
||||||
}
|
}
|
||||||
}, this._capability.reject);
|
}, this._capability.reject);
|
||||||
},
|
}
|
||||||
|
|
||||||
expandTextDivs: function TextLayer_expandTextDivs(expandDivs) {
|
/**
|
||||||
|
* @param {boolean} [expandDivs]
|
||||||
|
*/
|
||||||
|
expandTextDivs(expandDivs = false) {
|
||||||
if (!this._enhanceTextSelection || !this._renderingDone) {
|
if (!this._enhanceTextSelection || !this._renderingDone) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -820,11 +819,14 @@ const renderTextLayer = (function renderTextLayerClosure() {
|
|||||||
div.style.transform = divProps.originalTransform;
|
div.style.transform = divProps.originalTransform;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-shadow
|
/**
|
||||||
function renderTextLayer(renderParameters) {
|
* @param {TextLayerRenderParameters} renderParameters
|
||||||
|
* @returns {TextLayerRenderTask}
|
||||||
|
*/
|
||||||
|
function renderTextLayer(renderParameters) {
|
||||||
const task = new TextLayerRenderTask({
|
const task = new TextLayerRenderTask({
|
||||||
textContent: renderParameters.textContent,
|
textContent: renderParameters.textContent,
|
||||||
textContentStream: renderParameters.textContentStream,
|
textContentStream: renderParameters.textContentStream,
|
||||||
@ -836,9 +838,6 @@ const renderTextLayer = (function renderTextLayerClosure() {
|
|||||||
});
|
});
|
||||||
task._render(renderParameters.timeout);
|
task._render(renderParameters.timeout);
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
return renderTextLayer;
|
|
||||||
})();
|
|
||||||
|
|
||||||
export { renderTextLayer };
|
export { renderTextLayer };
|
||||||
|
Loading…
Reference in New Issue
Block a user