Bug 1897746 - Update PDF.js to new version 63b66b412cb3be6919c14436487c667a1597a732 r=pdfjs-reviewers,marco

Differential Revision: https://phabricator.services.mozilla.com/D210903
This commit is contained in:
Calixte 2024-05-20 12:31:13 +00:00
parent b54796113c
commit ce181d5c3d
8 changed files with 484 additions and 413 deletions

View file

@ -1824,7 +1824,6 @@ function opacityToHex(opacity) {
}
class IdManager {
#id = 0;
constructor() {}
get id() {
return `${AnnotationEditorPrefix}${this.#id++}`;
}
@ -5028,7 +5027,6 @@ class FontLoader {
class FontFaceObject {
constructor(translatedData, {
disableFontFace = false,
ignoreErrors = false,
inspectFont = null
}) {
this.compiledGlyphs = Object.create(null);
@ -5036,7 +5034,6 @@ class FontFaceObject {
this[i] = translatedData[i];
}
this.disableFontFace = disableFontFace === true;
this.ignoreErrors = ignoreErrors === true;
this._inspectFont = inspectFont;
}
createNativeFontFace() {
@ -5085,9 +5082,6 @@ class FontFaceObject {
try {
cmds = objs.get(this.loadedName + "_path_" + character);
} catch (ex) {
if (!this.ignoreErrors) {
throw ex;
}
warn(`getPathGenerator - ignoring character: "${ex}".`);
}
if (!Array.isArray(cmds) || cmds.length === 0) {
@ -7886,7 +7880,8 @@ const DEFAULT_FONT_SIZE = 30;
const DEFAULT_FONT_ASCENT = 0.8;
const ascentCache = new Map();
let _canvasContext = null;
function getCtx() {
const pendingTextLayers = new Set();
function getCtx(lang = null) {
if (!_canvasContext) {
const canvas = document.createElement("canvas");
canvas.className = "hiddenCanvasElement";
@ -7898,15 +7893,18 @@ function getCtx() {
return _canvasContext;
}
function cleanupTextLayer() {
if (pendingTextLayers.size > 0) {
return;
}
_canvasContext?.canvas.remove();
_canvasContext = null;
}
function getAscent(fontFamily) {
function getAscent(fontFamily, lang) {
const cachedAscent = ascentCache.get(fontFamily);
if (cachedAscent) {
return cachedAscent;
}
const ctx = getCtx();
const ctx = getCtx(lang);
const savedFont = ctx.font;
ctx.canvas.width = ctx.canvas.height = DEFAULT_FONT_SIZE;
ctx.font = `${DEFAULT_FONT_SIZE}px ${fontFamily}`;
@ -7951,72 +7949,6 @@ function getAscent(fontFamily) {
ascentCache.set(fontFamily, DEFAULT_FONT_ASCENT);
return DEFAULT_FONT_ASCENT;
}
function appendText(task, geom, styles) {
const textDiv = document.createElement("span");
const textDivProperties = {
angle: 0,
canvasWidth: 0,
hasText: geom.str !== "",
hasEOL: geom.hasEOL,
fontSize: 0
};
task._textDivs.push(textDiv);
const tx = Util.transform(task._transform, geom.transform);
let angle = Math.atan2(tx[1], tx[0]);
const style = styles[geom.fontName];
if (style.vertical) {
angle += Math.PI / 2;
}
const fontFamily = task._fontInspectorEnabled && style.fontSubstitution || style.fontFamily;
const fontHeight = Math.hypot(tx[2], tx[3]);
const fontAscent = fontHeight * getAscent(fontFamily);
let left, top;
if (angle === 0) {
left = tx[4];
top = tx[5] - fontAscent;
} else {
left = tx[4] + fontAscent * Math.sin(angle);
top = tx[5] - fontAscent * Math.cos(angle);
}
const scaleFactorStr = "calc(var(--scale-factor)*";
const divStyle = textDiv.style;
if (task._container === task._rootContainer) {
divStyle.left = `${(100 * left / task._pageWidth).toFixed(2)}%`;
divStyle.top = `${(100 * top / task._pageHeight).toFixed(2)}%`;
} else {
divStyle.left = `${scaleFactorStr}${left.toFixed(2)}px)`;
divStyle.top = `${scaleFactorStr}${top.toFixed(2)}px)`;
}
divStyle.fontSize = `${scaleFactorStr}${fontHeight.toFixed(2)}px)`;
divStyle.fontFamily = fontFamily;
textDivProperties.fontSize = fontHeight;
textDiv.setAttribute("role", "presentation");
textDiv.textContent = geom.str;
textDiv.dir = geom.dir;
if (task._fontInspectorEnabled) {
textDiv.dataset.fontName = style.fontSubstitutionLoadedName || geom.fontName;
}
if (angle !== 0) {
textDivProperties.angle = angle * (180 / Math.PI);
}
let shouldScaleText = false;
if (geom.str.length > 1) {
shouldScaleText = true;
} else if (geom.str !== " " && geom.transform[0] !== geom.transform[3]) {
const absScaleX = Math.abs(geom.transform[0]),
absScaleY = Math.abs(geom.transform[3]);
if (absScaleX !== absScaleY && Math.max(absScaleX, absScaleY) / Math.min(absScaleX, absScaleY) > 1.5) {
shouldScaleText = true;
}
}
if (shouldScaleText) {
textDivProperties.canvasWidth = style.vertical ? geom.height : geom.width;
}
task._textDivProperties.set(textDiv, textDivProperties);
if (task._isReadableStream) {
task._layoutText(textDiv);
}
}
function layout(params) {
const {
div,
@ -8057,25 +7989,10 @@ function layout(params) {
style.transform = transform;
}
}
function render(task) {
if (task._canceled) {
return;
}
const textDivs = task._textDivs;
const capability = task._capability;
const textDivsLength = textDivs.length;
if (textDivsLength > MAX_TEXT_DIVS_TO_RENDER) {
capability.resolve();
return;
}
if (!task._isReadableStream) {
for (const textDiv of textDivs) {
task._layoutText(textDiv);
}
}
capability.resolve();
}
class TextLayerRenderTask {
#disableProcessItems = false;
#reader = null;
#textContentSource = null;
constructor({
textContentSource,
container,
@ -8084,13 +8001,15 @@ class TextLayerRenderTask {
textDivProperties,
textContentItemsStr
}) {
this._textContentSource = textContentSource;
this._isReadableStream = textContentSource instanceof ReadableStream;
if (textContentSource instanceof ReadableStream) {
this.#textContentSource = textContentSource;
} else {
throw new Error('No "textContentSource" parameter specified.');
}
this._container = this._rootContainer = container;
this._textDivs = textDivs || [];
this._textContentItemsStr = textContentItemsStr || [];
this._fontInspectorEnabled = !!globalThis.FontInspector?.enabled;
this._reader = null;
this._textDivProperties = textDivProperties || new WeakMap();
this._canceled = false;
this._capability = Promise.withResolvers();
@ -8100,8 +8019,9 @@ class TextLayerRenderTask {
div: null,
scale: viewport.scale * (globalThis.devicePixelRatio || 1),
properties: null,
ctx: getCtx()
ctx: null
};
this._styleCache = Object.create(null);
const {
pageWidth,
pageHeight,
@ -8112,8 +8032,11 @@ class TextLayerRenderTask {
this._pageWidth = pageWidth;
this._pageHeight = pageHeight;
setLayerDimensions(container, viewport);
pendingTextLayers.add(this);
this._capability.promise.finally(() => {
pendingTextLayers.delete(this);
this._layoutTextParams = null;
this._styleCache = null;
}).catch(() => {});
}
get promise() {
@ -8121,14 +8044,29 @@ class TextLayerRenderTask {
}
cancel() {
this._canceled = true;
if (this._reader) {
this._reader.cancel(new AbortException("TextLayer task cancelled.")).catch(() => {});
this._reader = null;
}
this._capability.reject(new AbortException("TextLayer task cancelled."));
const abortEx = new AbortException("TextLayer task cancelled.");
this.#reader?.cancel(abortEx).catch(() => {});
this.#reader = null;
this._capability.reject(abortEx);
}
_processItems(items, styleCache) {
#processItems(items, lang) {
if (this.#disableProcessItems) {
return;
}
if (!this._layoutTextParams.ctx) {
this._textDivProperties.set(this._rootContainer, {
lang
});
this._layoutTextParams.ctx = getCtx(lang);
}
const textDivs = this._textDivs,
textContentItemsStr = this._textContentItemsStr;
for (const item of items) {
if (textDivs.length > MAX_TEXT_DIVS_TO_RENDER) {
warn("Ignoring additional textDivs for performance reasons.");
this.#disableProcessItems = true;
return;
}
if (item.str === undefined) {
if (item.type === "beginMarkedContentProps" || item.type === "beginMarkedContent") {
const parent = this._container;
@ -8143,13 +8081,77 @@ class TextLayerRenderTask {
}
continue;
}
this._textContentItemsStr.push(item.str);
appendText(this, item, styleCache);
textContentItemsStr.push(item.str);
this.#appendText(item, lang);
}
}
_layoutText(textDiv) {
const textDivProperties = this._layoutTextParams.properties = this._textDivProperties.get(textDiv);
#appendText(geom, lang) {
const textDiv = document.createElement("span");
const textDivProperties = {
angle: 0,
canvasWidth: 0,
hasText: geom.str !== "",
hasEOL: geom.hasEOL,
fontSize: 0
};
this._textDivs.push(textDiv);
const tx = Util.transform(this._transform, geom.transform);
let angle = Math.atan2(tx[1], tx[0]);
const style = this._styleCache[geom.fontName];
if (style.vertical) {
angle += Math.PI / 2;
}
const fontFamily = this._fontInspectorEnabled && style.fontSubstitution || style.fontFamily;
const fontHeight = Math.hypot(tx[2], tx[3]);
const fontAscent = fontHeight * getAscent(fontFamily, lang);
let left, top;
if (angle === 0) {
left = tx[4];
top = tx[5] - fontAscent;
} else {
left = tx[4] + fontAscent * Math.sin(angle);
top = tx[5] - fontAscent * Math.cos(angle);
}
const scaleFactorStr = "calc(var(--scale-factor)*";
const divStyle = textDiv.style;
if (this._container === this._rootContainer) {
divStyle.left = `${(100 * left / this._pageWidth).toFixed(2)}%`;
divStyle.top = `${(100 * top / this._pageHeight).toFixed(2)}%`;
} else {
divStyle.left = `${scaleFactorStr}${left.toFixed(2)}px)`;
divStyle.top = `${scaleFactorStr}${top.toFixed(2)}px)`;
}
divStyle.fontSize = `${scaleFactorStr}${fontHeight.toFixed(2)}px)`;
divStyle.fontFamily = fontFamily;
textDivProperties.fontSize = fontHeight;
textDiv.setAttribute("role", "presentation");
textDiv.textContent = geom.str;
textDiv.dir = geom.dir;
if (this._fontInspectorEnabled) {
textDiv.dataset.fontName = style.fontSubstitutionLoadedName || geom.fontName;
}
if (angle !== 0) {
textDivProperties.angle = angle * (180 / Math.PI);
}
let shouldScaleText = false;
if (geom.str.length > 1) {
shouldScaleText = true;
} else if (geom.str !== " " && geom.transform[0] !== geom.transform[3]) {
const absScaleX = Math.abs(geom.transform[0]),
absScaleY = Math.abs(geom.transform[3]);
if (absScaleX !== absScaleY && Math.max(absScaleX, absScaleY) / Math.min(absScaleX, absScaleY) > 1.5) {
shouldScaleText = true;
}
}
if (shouldScaleText) {
textDivProperties.canvasWidth = style.vertical ? geom.height : geom.width;
}
this._textDivProperties.set(textDiv, textDivProperties);
this.#layoutText(textDiv, textDivProperties);
}
#layoutText(textDiv, textDivProperties) {
this._layoutTextParams.div = textDiv;
this._layoutTextParams.properties = textDivProperties;
layout(this._layoutTextParams);
if (textDivProperties.hasText) {
this._container.append(textDiv);
@ -8161,43 +8163,23 @@ class TextLayerRenderTask {
}
}
_render() {
const {
promise,
resolve,
reject
} = Promise.withResolvers();
let styleCache = Object.create(null);
if (this._isReadableStream) {
const pump = () => {
this._reader.read().then(({
value,
done
}) => {
if (done) {
resolve();
return;
}
Object.assign(styleCache, value.styles);
this._processItems(value.items, styleCache);
pump();
}, reject);
};
this._reader = this._textContentSource.getReader();
pump();
} else if (this._textContentSource) {
const {
items,
styles
} = this._textContentSource;
this._processItems(items, styles);
resolve();
} else {
throw new Error('No "textContentSource" parameter specified.');
}
promise.then(() => {
styleCache = null;
render(this);
}, this._capability.reject);
const styleCache = this._styleCache;
const pump = () => {
this.#reader.read().then(({
value,
done
}) => {
if (done) {
this._capability.resolve();
return;
}
Object.assign(styleCache, value.styles);
this.#processItems(value.items, value.lang);
pump();
}, this._capability.reject);
};
this.#reader = this.#textContentSource.getReader();
pump();
}
}
function renderTextLayer(params) {
@ -8219,7 +8201,7 @@ function updateTextLayer({
});
}
if (mustRescale) {
const ctx = getCtx();
const ctx = getCtx(textDivProperties.get(container)?.lang);
const scale = viewport.scale * (globalThis.devicePixelRatio || 1);
const params = {
prevFontSize: null,
@ -9349,9 +9331,9 @@ function getDocument(src) {
worker = workerParams.port ? PDFWorker.fromPort(workerParams) : new PDFWorker(workerParams);
task._worker = worker;
}
const fetchDocParams = {
const docParams = {
docId,
apiVersion: "4.3.27",
apiVersion: "4.3.77",
data,
password,
disableAutoFetch,
@ -9373,7 +9355,6 @@ function getDocument(src) {
}
};
const transportParams = {
ignoreErrors,
disableFontFace,
fontExtraProperties,
enableXfa,
@ -9386,23 +9367,26 @@ function getDocument(src) {
if (task.destroyed) {
throw new Error("Loading aborted");
}
const workerIdPromise = _fetchDocument(worker, fetchDocParams);
const networkStreamPromise = new Promise(function (resolve) {
let networkStream;
if (rangeTransport) {
networkStream = new PDFDataTransportStream(rangeTransport, {
disableRange,
disableStream
});
} else if (!data) {
throw new Error("Not implemented: createPDFNetworkStream");
}
resolve(networkStream);
});
return Promise.all([workerIdPromise, networkStreamPromise]).then(function ([workerId, networkStream]) {
if (worker.destroyed) {
throw new Error("Worker was destroyed");
}
const workerIdPromise = worker.messageHandler.sendWithPromise("GetDocRequest", docParams, data ? [data.buffer] : null);
let networkStream;
if (rangeTransport) {
networkStream = new PDFDataTransportStream(rangeTransport, {
disableRange,
disableStream
});
} else if (!data) {
throw new Error("Not implemented: createPDFNetworkStream");
}
return workerIdPromise.then(workerId => {
if (task.destroyed) {
throw new Error("Loading aborted");
}
if (worker.destroyed) {
throw new Error("Worker was destroyed");
}
const messageHandler = new MessageHandler(docId, workerId, worker.port);
const transport = new WorkerTransport(messageHandler, task, networkStream, transportParams, transportFactory);
task._transport = transport;
@ -9411,16 +9395,6 @@ function getDocument(src) {
}).catch(task._capability.reject);
return task;
}
async function _fetchDocument(worker, source) {
if (worker.destroyed) {
throw new Error("Worker was destroyed");
}
const workerId = await worker.messageHandler.sendWithPromise("GetDocRequest", source, source.data ? [source.data.buffer] : null);
if (worker.destroyed) {
throw new Error("Worker was destroyed");
}
return workerId;
}
function getUrlProp(val) {
return null;
}
@ -9764,8 +9738,13 @@ class PDFPageProxy {
} else {
internalRenderTask.capability.resolve();
}
this._stats?.timeEnd("Rendering");
this._stats?.timeEnd("Overall");
if (this._stats) {
this._stats.timeEnd("Rendering");
this._stats.timeEnd("Overall");
if (globalThis.Stats?.enabled) {
globalThis.Stats.add(this.pageNumber, this._stats);
}
}
};
const internalRenderTask = new InternalRenderTask({
callback: complete,
@ -9843,6 +9822,7 @@ class PDFPageProxy {
resolve(textContent);
return;
}
textContent.lang ??= value.lang;
Object.assign(textContent.styles, value.styles);
textContent.items.push(...value.items);
pump();
@ -9851,7 +9831,8 @@ class PDFPageProxy {
const reader = readableStream.getReader();
const textContent = {
items: [],
styles: Object.create(null)
styles: Object.create(null),
lang: null
};
pump();
});
@ -10522,23 +10503,26 @@ class WorkerTransport {
}
switch (type) {
case "Font":
const params = this._params;
const {
disableFontFace,
fontExtraProperties,
pdfBug
} = this._params;
if ("error" in exportedData) {
const exportedError = exportedData.error;
warn(`Error during font loading: ${exportedError}`);
this.commonObjs.resolve(id, exportedError);
break;
}
const inspectFont = params.pdfBug && globalThis.FontInspector?.enabled ? (font, url) => globalThis.FontInspector.fontAdded(font, url) : null;
const inspectFont = pdfBug && globalThis.FontInspector?.enabled ? (font, url) => globalThis.FontInspector.fontAdded(font, url) : null;
const font = new FontFaceObject(exportedData, {
disableFontFace: params.disableFontFace,
ignoreErrors: params.ignoreErrors,
disableFontFace,
inspectFont
});
this.fontLoader.bind(font).catch(() => messageHandler.sendWithPromise("FontFallback", {
id
})).finally(() => {
if (!params.fontExtraProperties && font.data) {
if (!fontExtraProperties && font.data) {
font.data = null;
}
this.commonObjs.resolve(id, font);
@ -10551,7 +10535,7 @@ class WorkerTransport {
assert(imageRef, "The imageRef must be defined.");
for (const pageProxy of this.#pageCache.values()) {
for (const [, data] of pageProxy.objs) {
if (data.ref !== imageRef) {
if (data?.ref !== imageRef) {
continue;
}
if (!data.dataLen) {
@ -11011,8 +10995,8 @@ class InternalRenderTask {
}
}
}
const version = "4.3.27";
const build = "df23679bc";
const version = "4.3.77";
const build = "63b66b412";
;// CONCATENATED MODULE: ./src/shared/scripting_utils.js
function makeColorComp(n) {
@ -17798,8 +17782,8 @@ class DrawLayer {
const pdfjsVersion = "4.3.27";
const pdfjsBuild = "df23679bc";
const pdfjsVersion = "4.3.77";
const pdfjsBuild = "63b66b412";
var __webpack_exports__AbortException = __webpack_exports__.AbortException;
var __webpack_exports__AnnotationEditorLayer = __webpack_exports__.AnnotationEditorLayer;

View file

@ -3956,8 +3956,8 @@ function initSandbox(params) {
;// CONCATENATED MODULE: ./src/pdf.scripting.js
const pdfjsVersion = "4.3.27";
const pdfjsBuild = "df23679bc";
const pdfjsVersion = "4.3.77";
const pdfjsBuild = "63b66b412";
globalThis.pdfjsScripting = {
initSandbox: initSandbox
};

File diff suppressed because one or more lines are too long

View file

@ -17,13 +17,14 @@
position:absolute;
text-align:initial;
inset:0;
overflow:hidden;
overflow:clip;
opacity:1;
line-height:1;
text-size-adjust:none;
forced-color-adjust:none;
transform-origin:0 0;
caret-color:CanvasText;
z-index:0;
&.highlighting{
touch-action:none;
@ -37,6 +38,11 @@
transform-origin:0% 0%;
}
> :not(.markedContent),
.markedContent span:not(.markedContent){
z-index:1;
}
.highlight{
--highlight-bg-color:rgb(180 0 170 / 0.25);
--highlight-selected-bg-color:rgb(0 100 0 / 0.25);
@ -88,7 +94,7 @@
display:block;
position:absolute;
inset:100% 0 0;
z-index:-1;
z-index:0;
cursor:default;
user-select:none;
@ -826,12 +832,30 @@
@media screen and (forced-colors: active){
--hcm-highlight-filter:invert(100%);
}
}
.pdfViewer .canvasWrapper{
overflow:hidden;
width:100%;
height:100%;
.canvasWrapper{
overflow:hidden;
width:100%;
height:100%;
canvas{
margin:0;
display:block;
&[hidden]{
display:none;
}
&[zooming]{
width:100%;
height:100%;
}
.structTree{
contain:strict;
}
}
}
}
.pdfViewer .page{
@ -882,24 +906,6 @@
margin-inline:var(--spreadHorizontalWrapped-margin-LR);
}
.pdfViewer .page canvas{
margin:0;
display:block;
}
.pdfViewer .page canvas .structTree{
contain:strict;
}
.pdfViewer .page canvas[hidden]{
display:none;
}
.pdfViewer .page canvas[zooming]{
width:100%;
height:100%;
}
.pdfViewer .page.loadingIcon::after{
position:absolute;
top:0;

View file

@ -4887,6 +4887,8 @@ class TextLayerBuilder {
#rotation = 0;
#scale = 0;
#textContentSource = null;
static #textLayers = new Map();
static #selectionChangeAbortController = null;
constructor({
highlighter = null,
accessibilityManager = null,
@ -4911,7 +4913,7 @@ class TextLayerBuilder {
const endOfContent = document.createElement("div");
endOfContent.className = "endOfContent";
this.div.append(endOfContent);
this.#bindMouse();
this.#bindMouse(endOfContent);
}
get numTextDivs() {
return this.textDivs.length;
@ -4984,29 +4986,19 @@ class TextLayerBuilder {
this.textContentItemsStr.length = 0;
this.textDivs.length = 0;
this.textDivProperties = new WeakMap();
TextLayerBuilder.#removeGlobalSelectionListener(this.div);
}
setTextContentSource(source) {
this.cancel();
this.#textContentSource = source;
}
#bindMouse() {
#bindMouse(end) {
const {
div
} = this;
div.addEventListener("mousedown", evt => {
const end = div.querySelector(".endOfContent");
if (!end) {
return;
}
end.classList.add("active");
});
div.addEventListener("mouseup", () => {
const end = div.querySelector(".endOfContent");
if (!end) {
return;
}
end.classList.remove("active");
});
div.addEventListener("copy", event => {
if (!this.#enablePermissions) {
const selection = document.getSelection();
@ -5015,6 +5007,54 @@ class TextLayerBuilder {
event.preventDefault();
event.stopPropagation();
});
TextLayerBuilder.#textLayers.set(div, end);
TextLayerBuilder.#enableGlobalSelectionListener();
}
static #removeGlobalSelectionListener(textLayerDiv) {
this.#textLayers.delete(textLayerDiv);
if (this.#textLayers.size === 0) {
this.#selectionChangeAbortController?.abort();
this.#selectionChangeAbortController = null;
}
}
static #enableGlobalSelectionListener() {
if (TextLayerBuilder.#selectionChangeAbortController) {
return;
}
TextLayerBuilder.#selectionChangeAbortController = new AbortController();
const reset = (end, textLayer) => {
end.classList.remove("active");
};
document.addEventListener("pointerup", () => {
TextLayerBuilder.#textLayers.forEach(reset);
}, {
signal: TextLayerBuilder.#selectionChangeAbortController.signal
});
document.addEventListener("selectionchange", () => {
const selection = document.getSelection();
if (selection.rangeCount === 0) {
TextLayerBuilder.#textLayers.forEach(reset);
return;
}
const activeTextLayers = new Set();
for (let i = 0; i < selection.rangeCount; i++) {
const range = selection.getRangeAt(i);
for (const textLayerDiv of TextLayerBuilder.#textLayers.keys()) {
if (!activeTextLayers.has(textLayerDiv) && range.intersectsNode(textLayerDiv)) {
activeTextLayers.add(textLayerDiv);
}
}
}
for (const [textLayerDiv, endDiv] of TextLayerBuilder.#textLayers) {
if (activeTextLayers.has(textLayerDiv)) {
endDiv.classList.add("active");
} else {
reset(endDiv, textLayerDiv);
}
}
}, {
signal: TextLayerBuilder.#selectionChangeAbortController.signal
});
}
}
@ -5405,9 +5445,9 @@ class PDFPageView {
onlyCssZoom = (Math.floor(width) * sx | 0) * (Math.floor(height) * sy | 0) > this.maxCanvasPixels;
}
}
const postponeDrawing = !onlyCssZoom && drawingDelay >= 0 && drawingDelay < 1000;
const postponeDrawing = drawingDelay >= 0 && drawingDelay < 1000;
if (postponeDrawing || onlyCssZoom) {
if (postponeDrawing && this.renderingState !== RenderingStates.FINISHED) {
if (postponeDrawing && !onlyCssZoom && this.renderingState !== RenderingStates.FINISHED) {
this.cancelRendering({
keepZoomLayer: true,
keepAnnotationLayer: true,
@ -5872,7 +5912,7 @@ class PDFViewer {
#scaleTimeoutId = null;
#textLayerMode = TextLayerMode.ENABLE;
constructor(options) {
const viewerVersion = "4.3.27";
const viewerVersion = "4.3.77";
if (version !== viewerVersion) {
throw new Error(`The API version "${version}" does not match the Viewer version "${viewerVersion}".`);
}
@ -7507,9 +7547,19 @@ const PDFViewerApplication = {
viewerContainer
} = this.appConfig,
params = parseQueryString(hash);
const loadPDFBug = async () => {
if (this._PDFBug) {
return;
}
const {
PDFBug
} = await import( /*webpackIgnore: true*/AppOptions.get("debuggerSrc"));
this._PDFBug = PDFBug;
};
if (params.get("disableworker") === "true") {
try {
await loadFakeWorker();
GlobalWorkerOptions.workerSrc ||= AppOptions.get("workerSrc");
await import( /*webpackIgnore: true*/PDFWorker.workerSrc);
} catch (ex) {
console.error(`_parseHashParams: "${ex.message}".`);
}
@ -7542,7 +7592,7 @@ const PDFViewerApplication = {
case "hover":
viewerContainer.classList.add(`textLayer-${params.get("textlayer")}`);
try {
await loadPDFBug(this);
await loadPDFBug();
this._PDFBug.loadCSS();
} catch (ex) {
console.error(`_parseHashParams: "${ex.message}".`);
@ -7551,11 +7601,13 @@ const PDFViewerApplication = {
}
}
if (params.has("pdfbug")) {
AppOptions.set("pdfBug", true);
AppOptions.set("fontExtraProperties", true);
AppOptions.setAll({
pdfBug: true,
fontExtraProperties: true
});
const enabled = params.get("pdfbug").split(",");
try {
await loadPDFBug(this);
await loadPDFBug();
this._PDFBug.init(mainContainer, enabled);
} catch (ex) {
console.error(`_parseHashParams: "${ex.message}".`);
@ -8610,14 +8662,6 @@ const PDFViewerApplication = {
eventBus._on("updatefindcontrolstate", webViewerUpdateFindControlState, {
signal
});
if (AppOptions.get("pdfBug")) {
eventBus._on("pagerendered", reportPageStatsPDFBug, {
signal
});
eventBus._on("pagechanging", reportPageStatsPDFBug, {
signal
});
}
eventBus._on("annotationeditorstateschanged", webViewerAnnotationEditorStatesChanged, {
signal
});
@ -8721,20 +8765,15 @@ const PDFViewerApplication = {
passive: true,
signal
});
mainContainer.removeEventListener("scrollend", scrollend, {
signal
});
mainContainer.removeEventListener("blur", scrollend, {
signal
});
mainContainer.removeEventListener("scrollend", scrollend);
mainContainer.removeEventListener("blur", scrollend);
};
const scroll = () => {
if (this._isCtrlKeyDown) {
return;
}
mainContainer.removeEventListener("scroll", scroll, {
passive: true,
signal
passive: true
});
this._isScrolling = true;
mainContainer.addEventListener("scrollend", scrollend, {
@ -8797,25 +8836,6 @@ const PDFViewerApplication = {
}
};
initCom(PDFViewerApplication);
async function loadFakeWorker() {
GlobalWorkerOptions.workerSrc ||= AppOptions.get("workerSrc");
await import( /*webpackIgnore: true*/PDFWorker.workerSrc);
}
async function loadPDFBug(self) {
const {
PDFBug
} = await import( /*webpackIgnore: true*/AppOptions.get("debuggerSrc"));
self._PDFBug = PDFBug;
}
function reportPageStatsPDFBug({
pageNumber
}) {
if (!globalThis.Stats?.enabled) {
return;
}
const pageView = PDFViewerApplication.pdfViewer.getPageView(pageNumber - 1);
globalThis.Stats.add(pageNumber, pageView?.pdfPage?.stats);
}
function webViewerPageRender({
pageNumber
}) {
@ -9556,8 +9576,8 @@ function webViewerReportTelemetry({
const pdfjsVersion = "4.3.27";
const pdfjsBuild = "df23679bc";
const pdfjsVersion = "4.3.77";
const pdfjsBuild = "63b66b412";
const AppConstants = null;
window.PDFViewerApplication = PDFViewerApplication;
window.PDFViewerApplicationConstants = AppConstants;

View file

@ -17,13 +17,14 @@
position:absolute;
text-align:initial;
inset:0;
overflow:hidden;
overflow:clip;
opacity:1;
line-height:1;
text-size-adjust:none;
forced-color-adjust:none;
transform-origin:0 0;
caret-color:CanvasText;
z-index:0;
&.highlighting{
touch-action:none;
@ -37,6 +38,11 @@
transform-origin:0% 0%;
}
> :not(.markedContent),
.markedContent span:not(.markedContent){
z-index:1;
}
.highlight{
--highlight-bg-color:rgb(180 0 170 / 0.25);
--highlight-selected-bg-color:rgb(0 100 0 / 0.25);
@ -88,7 +94,7 @@
display:block;
position:absolute;
inset:100% 0 0;
z-index:-1;
z-index:0;
cursor:default;
user-select:none;
@ -1529,11 +1535,13 @@
.annotationEditorLayer .stampEditor{
width:auto;
height:auto;
}
.annotationEditorLayer .stampEditor canvas{
width:100%;
height:100%;
canvas{
position:absolute;
width:100%;
height:100%;
margin:0;
}
}
.annotationEditorLayer{
@ -2359,12 +2367,30 @@
@media screen and (forced-colors: active){
--hcm-highlight-filter:invert(100%);
}
}
.pdfViewer .canvasWrapper{
overflow:hidden;
width:100%;
height:100%;
.canvasWrapper{
overflow:hidden;
width:100%;
height:100%;
canvas{
margin:0;
display:block;
&[hidden]{
display:none;
}
&[zooming]{
width:100%;
height:100%;
}
.structTree{
contain:strict;
}
}
}
}
.pdfViewer .page{
@ -2415,24 +2441,6 @@
margin-inline:var(--spreadHorizontalWrapped-margin-LR);
}
.pdfViewer .page canvas{
margin:0;
display:block;
}
.pdfViewer .page canvas .structTree{
contain:strict;
}
.pdfViewer .page canvas[hidden]{
display:none;
}
.pdfViewer .page canvas[zooming]{
width:100%;
height:100%;
}
.pdfViewer .page.loadingIcon::after{
position:absolute;
top:0;

View file

@ -7451,6 +7451,8 @@ class TextLayerBuilder {
#rotation = 0;
#scale = 0;
#textContentSource = null;
static #textLayers = new Map();
static #selectionChangeAbortController = null;
constructor({
highlighter = null,
accessibilityManager = null,
@ -7475,7 +7477,7 @@ class TextLayerBuilder {
const endOfContent = document.createElement("div");
endOfContent.className = "endOfContent";
this.div.append(endOfContent);
this.#bindMouse();
this.#bindMouse(endOfContent);
}
get numTextDivs() {
return this.textDivs.length;
@ -7548,29 +7550,19 @@ class TextLayerBuilder {
this.textContentItemsStr.length = 0;
this.textDivs.length = 0;
this.textDivProperties = new WeakMap();
TextLayerBuilder.#removeGlobalSelectionListener(this.div);
}
setTextContentSource(source) {
this.cancel();
this.#textContentSource = source;
}
#bindMouse() {
#bindMouse(end) {
const {
div
} = this;
div.addEventListener("mousedown", evt => {
const end = div.querySelector(".endOfContent");
if (!end) {
return;
}
end.classList.add("active");
});
div.addEventListener("mouseup", () => {
const end = div.querySelector(".endOfContent");
if (!end) {
return;
}
end.classList.remove("active");
});
div.addEventListener("copy", event => {
if (!this.#enablePermissions) {
const selection = document.getSelection();
@ -7579,6 +7571,54 @@ class TextLayerBuilder {
event.preventDefault();
event.stopPropagation();
});
TextLayerBuilder.#textLayers.set(div, end);
TextLayerBuilder.#enableGlobalSelectionListener();
}
static #removeGlobalSelectionListener(textLayerDiv) {
this.#textLayers.delete(textLayerDiv);
if (this.#textLayers.size === 0) {
this.#selectionChangeAbortController?.abort();
this.#selectionChangeAbortController = null;
}
}
static #enableGlobalSelectionListener() {
if (TextLayerBuilder.#selectionChangeAbortController) {
return;
}
TextLayerBuilder.#selectionChangeAbortController = new AbortController();
const reset = (end, textLayer) => {
end.classList.remove("active");
};
document.addEventListener("pointerup", () => {
TextLayerBuilder.#textLayers.forEach(reset);
}, {
signal: TextLayerBuilder.#selectionChangeAbortController.signal
});
document.addEventListener("selectionchange", () => {
const selection = document.getSelection();
if (selection.rangeCount === 0) {
TextLayerBuilder.#textLayers.forEach(reset);
return;
}
const activeTextLayers = new Set();
for (let i = 0; i < selection.rangeCount; i++) {
const range = selection.getRangeAt(i);
for (const textLayerDiv of TextLayerBuilder.#textLayers.keys()) {
if (!activeTextLayers.has(textLayerDiv) && range.intersectsNode(textLayerDiv)) {
activeTextLayers.add(textLayerDiv);
}
}
}
for (const [textLayerDiv, endDiv] of TextLayerBuilder.#textLayers) {
if (activeTextLayers.has(textLayerDiv)) {
endDiv.classList.add("active");
} else {
reset(endDiv, textLayerDiv);
}
}
}, {
signal: TextLayerBuilder.#selectionChangeAbortController.signal
});
}
}
@ -7969,9 +8009,9 @@ class PDFPageView {
onlyCssZoom = (Math.floor(width) * sx | 0) * (Math.floor(height) * sy | 0) > this.maxCanvasPixels;
}
}
const postponeDrawing = !onlyCssZoom && drawingDelay >= 0 && drawingDelay < 1000;
const postponeDrawing = drawingDelay >= 0 && drawingDelay < 1000;
if (postponeDrawing || onlyCssZoom) {
if (postponeDrawing && this.renderingState !== RenderingStates.FINISHED) {
if (postponeDrawing && !onlyCssZoom && this.renderingState !== RenderingStates.FINISHED) {
this.cancelRendering({
keepZoomLayer: true,
keepAnnotationLayer: true,
@ -8436,7 +8476,7 @@ class PDFViewer {
#scaleTimeoutId = null;
#textLayerMode = TextLayerMode.ENABLE;
constructor(options) {
const viewerVersion = "4.3.27";
const viewerVersion = "4.3.77";
if (version !== viewerVersion) {
throw new Error(`The API version "${version}" does not match the Viewer version "${viewerVersion}".`);
}
@ -10564,9 +10604,19 @@ const PDFViewerApplication = {
viewerContainer
} = this.appConfig,
params = parseQueryString(hash);
const loadPDFBug = async () => {
if (this._PDFBug) {
return;
}
const {
PDFBug
} = await import( /*webpackIgnore: true*/AppOptions.get("debuggerSrc"));
this._PDFBug = PDFBug;
};
if (params.get("disableworker") === "true") {
try {
await loadFakeWorker();
GlobalWorkerOptions.workerSrc ||= AppOptions.get("workerSrc");
await import( /*webpackIgnore: true*/PDFWorker.workerSrc);
} catch (ex) {
console.error(`_parseHashParams: "${ex.message}".`);
}
@ -10599,7 +10649,7 @@ const PDFViewerApplication = {
case "hover":
viewerContainer.classList.add(`textLayer-${params.get("textlayer")}`);
try {
await loadPDFBug(this);
await loadPDFBug();
this._PDFBug.loadCSS();
} catch (ex) {
console.error(`_parseHashParams: "${ex.message}".`);
@ -10608,11 +10658,13 @@ const PDFViewerApplication = {
}
}
if (params.has("pdfbug")) {
AppOptions.set("pdfBug", true);
AppOptions.set("fontExtraProperties", true);
AppOptions.setAll({
pdfBug: true,
fontExtraProperties: true
});
const enabled = params.get("pdfbug").split(",");
try {
await loadPDFBug(this);
await loadPDFBug();
this._PDFBug.init(mainContainer, enabled);
} catch (ex) {
console.error(`_parseHashParams: "${ex.message}".`);
@ -11700,14 +11752,6 @@ const PDFViewerApplication = {
eventBus._on("updatefindcontrolstate", webViewerUpdateFindControlState, {
signal
});
if (AppOptions.get("pdfBug")) {
eventBus._on("pagerendered", reportPageStatsPDFBug, {
signal
});
eventBus._on("pagechanging", reportPageStatsPDFBug, {
signal
});
}
eventBus._on("annotationeditorstateschanged", webViewerAnnotationEditorStatesChanged, {
signal
});
@ -11811,20 +11855,15 @@ const PDFViewerApplication = {
passive: true,
signal
});
mainContainer.removeEventListener("scrollend", scrollend, {
signal
});
mainContainer.removeEventListener("blur", scrollend, {
signal
});
mainContainer.removeEventListener("scrollend", scrollend);
mainContainer.removeEventListener("blur", scrollend);
};
const scroll = () => {
if (this._isCtrlKeyDown) {
return;
}
mainContainer.removeEventListener("scroll", scroll, {
passive: true,
signal
passive: true
});
this._isScrolling = true;
mainContainer.addEventListener("scrollend", scrollend, {
@ -11887,25 +11926,6 @@ const PDFViewerApplication = {
}
};
initCom(PDFViewerApplication);
async function loadFakeWorker() {
GlobalWorkerOptions.workerSrc ||= AppOptions.get("workerSrc");
await import( /*webpackIgnore: true*/PDFWorker.workerSrc);
}
async function loadPDFBug(self) {
const {
PDFBug
} = await import( /*webpackIgnore: true*/AppOptions.get("debuggerSrc"));
self._PDFBug = PDFBug;
}
function reportPageStatsPDFBug({
pageNumber
}) {
if (!globalThis.Stats?.enabled) {
return;
}
const pageView = PDFViewerApplication.pdfViewer.getPageView(pageNumber - 1);
globalThis.Stats.add(pageNumber, pageView?.pdfPage?.stats);
}
function webViewerPageRender({
pageNumber
}) {
@ -12646,8 +12666,8 @@ function webViewerReportTelemetry({
const pdfjsVersion = "4.3.27";
const pdfjsBuild = "df23679bc";
const pdfjsVersion = "4.3.77";
const pdfjsBuild = "63b66b412";
const AppConstants = null;
window.PDFViewerApplication = PDFViewerApplication;
window.PDFViewerApplicationConstants = AppConstants;

View file

@ -20,8 +20,8 @@ origin:
# Human-readable identifier for this version/release
# Generally "version NNN", "tag SSS", "bookmark SSS"
release: df23679bc68cf0c6fba37f2ab556758048f789cc (2024-05-13T14:45:03Z).
revision: df23679bc68cf0c6fba37f2ab556758048f789cc
release: 63b66b412cb3be6919c14436487c667a1597a732 (2024-05-17T12:10:33Z).
revision: 63b66b412cb3be6919c14436487c667a1597a732
# The package's license, where possible using the mnemonic from
# https://spdx.org/licenses/