mirror of
https://github.com/mozilla/pdf.js.git
synced 2026-08-02 20:37:21 +02:00
Compare commits
9 Commits
a8c77633a1
...
c6b9338f6f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c6b9338f6f | ||
|
|
74ab29544e | ||
|
|
22107145df | ||
|
|
532406427b | ||
|
|
3c93d63731 | ||
|
|
d4c7aaa9d3 | ||
|
|
dee80cb082 | ||
|
|
9456b88f6b | ||
|
|
abcddb51e0 |
@ -228,7 +228,7 @@
|
|||||||
"enableAutoLinking": {
|
"enableAutoLinking": {
|
||||||
"description": "Enable creation of hyperlinks from text that look like URLs.",
|
"description": "Enable creation of hyperlinks from text that look like URLs.",
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false
|
"default": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -262,7 +262,7 @@ class Catalog {
|
|||||||
get structTreeRoot() {
|
get structTreeRoot() {
|
||||||
let structTree = null;
|
let structTree = null;
|
||||||
try {
|
try {
|
||||||
structTree = this._readStructTreeRoot();
|
structTree = this.#readStructTreeRoot();
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
if (ex instanceof MissingDataException) {
|
if (ex instanceof MissingDataException) {
|
||||||
throw ex;
|
throw ex;
|
||||||
@ -272,17 +272,14 @@ class Catalog {
|
|||||||
return shadow(this, "structTreeRoot", structTree);
|
return shadow(this, "structTreeRoot", structTree);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
#readStructTreeRoot() {
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
_readStructTreeRoot() {
|
|
||||||
const rawObj = this._catDict.getRaw("StructTreeRoot");
|
const rawObj = this._catDict.getRaw("StructTreeRoot");
|
||||||
const obj = this.xref.fetchIfRef(rawObj);
|
const obj = this.xref.fetchIfRef(rawObj);
|
||||||
if (!(obj instanceof Dict)) {
|
if (!(obj instanceof Dict)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const root = new StructTreeRoot(obj, rawObj);
|
const root = new StructTreeRoot(this.xref, obj, rawObj);
|
||||||
root.init();
|
root.init();
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,7 +29,8 @@ const StructElementType = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class StructTreeRoot {
|
class StructTreeRoot {
|
||||||
constructor(rootDict, rootRef) {
|
constructor(xref, rootDict, rootRef) {
|
||||||
|
this.xref = xref;
|
||||||
this.dict = rootDict;
|
this.dict = rootDict;
|
||||||
this.ref = rootRef instanceof Ref ? rootRef : null;
|
this.ref = rootRef instanceof Ref ? rootRef : null;
|
||||||
this.roleMap = new Map();
|
this.roleMap = new Map();
|
||||||
@ -158,7 +159,7 @@ class StructTreeRoot {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async canUpdateStructTree({ pdfManager, xref, newAnnotationsByPage }) {
|
async canUpdateStructTree({ pdfManager, newAnnotationsByPage }) {
|
||||||
if (!this.ref) {
|
if (!this.ref) {
|
||||||
warn("Cannot update the struct tree: no root reference.");
|
warn("Cannot update the struct tree: no root reference.");
|
||||||
return false;
|
return false;
|
||||||
@ -180,7 +181,7 @@ class StructTreeRoot {
|
|||||||
warn("Cannot update the struct tree: nums isn't an array.");
|
warn("Cannot update the struct tree: nums isn't an array.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const numberTree = new NumberTree(parentTree, xref);
|
const numberTree = new NumberTree(parentTree, this.xref);
|
||||||
|
|
||||||
for (const pageIndex of newAnnotationsByPage.keys()) {
|
for (const pageIndex of newAnnotationsByPage.keys()) {
|
||||||
const { pageDict } = await pdfManager.getPage(pageIndex);
|
const { pageDict } = await pdfManager.getPage(pageIndex);
|
||||||
@ -201,7 +202,7 @@ class StructTreeRoot {
|
|||||||
const { pageDict } = await pdfManager.getPage(pageIndex);
|
const { pageDict } = await pdfManager.getPage(pageIndex);
|
||||||
StructTreeRoot.#collectParents({
|
StructTreeRoot.#collectParents({
|
||||||
elements,
|
elements,
|
||||||
xref: this.dict.xref,
|
xref: this.xref,
|
||||||
pageDict,
|
pageDict,
|
||||||
numberTree,
|
numberTree,
|
||||||
});
|
});
|
||||||
@ -233,9 +234,8 @@ class StructTreeRoot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async updateStructureTree({ newAnnotationsByPage, pdfManager, changes }) {
|
async updateStructureTree({ newAnnotationsByPage, pdfManager, changes }) {
|
||||||
const xref = this.dict.xref;
|
const { ref: structTreeRootRef, xref } = this;
|
||||||
const structTreeRoot = this.dict.clone();
|
const structTreeRoot = this.dict.clone();
|
||||||
const structTreeRootRef = this.ref;
|
|
||||||
const cache = new RefSetCache();
|
const cache = new RefSetCache();
|
||||||
cache.put(structTreeRootRef, structTreeRoot);
|
cache.put(structTreeRootRef, structTreeRoot);
|
||||||
|
|
||||||
@ -541,6 +541,7 @@ class StructTreeRoot {
|
|||||||
class StructElementNode {
|
class StructElementNode {
|
||||||
constructor(tree, dict) {
|
constructor(tree, dict) {
|
||||||
this.tree = tree;
|
this.tree = tree;
|
||||||
|
this.xref = tree.xref;
|
||||||
this.dict = dict;
|
this.dict = dict;
|
||||||
this.kids = [];
|
this.kids = [];
|
||||||
this.parseKids();
|
this.parseKids();
|
||||||
@ -550,10 +551,7 @@ class StructElementNode {
|
|||||||
const nameObj = this.dict.get("S");
|
const nameObj = this.dict.get("S");
|
||||||
const name = nameObj instanceof Name ? nameObj.name : "";
|
const name = nameObj instanceof Name ? nameObj.name : "";
|
||||||
const { root } = this.tree;
|
const { root } = this.tree;
|
||||||
if (root.roleMap.has(name)) {
|
return root.roleMap.get(name) ?? name;
|
||||||
return root.roleMap.get(name);
|
|
||||||
}
|
|
||||||
return name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parseKids() {
|
parseKids() {
|
||||||
@ -565,7 +563,7 @@ class StructElementNode {
|
|||||||
const kids = this.dict.get("K");
|
const kids = this.dict.get("K");
|
||||||
if (Array.isArray(kids)) {
|
if (Array.isArray(kids)) {
|
||||||
for (const kid of kids) {
|
for (const kid of kids) {
|
||||||
const element = this.parseKid(pageObjId, kid);
|
const element = this.parseKid(pageObjId, this.xref.fetchIfRef(kid));
|
||||||
if (element) {
|
if (element) {
|
||||||
this.kids.push(element);
|
this.kids.push(element);
|
||||||
}
|
}
|
||||||
@ -592,33 +590,26 @@ class StructElementNode {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the dictionary for the kid.
|
if (!(kid instanceof Dict)) {
|
||||||
let kidDict = null;
|
|
||||||
if (kid instanceof Ref) {
|
|
||||||
kidDict = this.dict.xref.fetch(kid);
|
|
||||||
} else if (kid instanceof Dict) {
|
|
||||||
kidDict = kid;
|
|
||||||
}
|
|
||||||
if (!kidDict) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const pageRef = kidDict.getRaw("Pg");
|
|
||||||
|
const pageRef = kid.getRaw("Pg");
|
||||||
if (pageRef instanceof Ref) {
|
if (pageRef instanceof Ref) {
|
||||||
pageObjId = pageRef.toString();
|
pageObjId = pageRef.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
const type =
|
const type = kid.get("Type") instanceof Name ? kid.get("Type").name : null;
|
||||||
kidDict.get("Type") instanceof Name ? kidDict.get("Type").name : null;
|
|
||||||
if (type === "MCR") {
|
if (type === "MCR") {
|
||||||
if (this.tree.pageDict.objId !== pageObjId) {
|
if (this.tree.pageDict.objId !== pageObjId) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const kidRef = kidDict.getRaw("Stm");
|
const kidRef = kid.getRaw("Stm");
|
||||||
return new StructElement({
|
return new StructElement({
|
||||||
type: StructElementType.STREAM_CONTENT,
|
type: StructElementType.STREAM_CONTENT,
|
||||||
refObjId: kidRef instanceof Ref ? kidRef.toString() : null,
|
refObjId: kidRef instanceof Ref ? kidRef.toString() : null,
|
||||||
pageObjId,
|
pageObjId,
|
||||||
mcid: kidDict.get("MCID"),
|
mcid: kid.get("MCID"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,7 +617,7 @@ class StructElementNode {
|
|||||||
if (this.tree.pageDict.objId !== pageObjId) {
|
if (this.tree.pageDict.objId !== pageObjId) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const kidRef = kidDict.getRaw("Obj");
|
const kidRef = kid.getRaw("Obj");
|
||||||
return new StructElement({
|
return new StructElement({
|
||||||
type: StructElementType.OBJECT,
|
type: StructElementType.OBJECT,
|
||||||
refObjId: kidRef instanceof Ref ? kidRef.toString() : null,
|
refObjId: kidRef instanceof Ref ? kidRef.toString() : null,
|
||||||
@ -636,7 +627,7 @@ class StructElementNode {
|
|||||||
|
|
||||||
return new StructElement({
|
return new StructElement({
|
||||||
type: StructElementType.ELEMENT,
|
type: StructElementType.ELEMENT,
|
||||||
dict: kidDict,
|
dict: kid,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -661,7 +652,8 @@ class StructElement {
|
|||||||
class StructTreePage {
|
class StructTreePage {
|
||||||
constructor(structTreeRoot, pageDict) {
|
constructor(structTreeRoot, pageDict) {
|
||||||
this.root = structTreeRoot;
|
this.root = structTreeRoot;
|
||||||
this.rootDict = structTreeRoot ? structTreeRoot.dict : null;
|
this.xref = structTreeRoot?.xref ?? null;
|
||||||
|
this.rootDict = structTreeRoot?.dict ?? null;
|
||||||
this.pageDict = pageDict;
|
this.pageDict = pageDict;
|
||||||
this.nodes = [];
|
this.nodes = [];
|
||||||
}
|
}
|
||||||
@ -687,7 +679,7 @@ class StructTreePage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const map = new Map();
|
const map = new Map();
|
||||||
const numberTree = new NumberTree(parentTree, this.rootDict.xref);
|
const numberTree = new NumberTree(parentTree, this.xref);
|
||||||
|
|
||||||
for (const [elemId] of ids) {
|
for (const [elemId] of ids) {
|
||||||
const obj = numberTree.getRaw(elemId);
|
const obj = numberTree.getRaw(elemId);
|
||||||
@ -714,14 +706,14 @@ class StructTreePage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const map = new Map();
|
const map = new Map();
|
||||||
const numberTree = new NumberTree(parentTree, this.rootDict.xref);
|
const numberTree = new NumberTree(parentTree, this.xref);
|
||||||
|
|
||||||
if (Number.isInteger(id)) {
|
if (Number.isInteger(id)) {
|
||||||
const parentArray = numberTree.get(id);
|
const parentArray = numberTree.get(id);
|
||||||
if (Array.isArray(parentArray)) {
|
if (Array.isArray(parentArray)) {
|
||||||
for (const ref of parentArray) {
|
for (const ref of parentArray) {
|
||||||
if (ref instanceof Ref) {
|
if (ref instanceof Ref) {
|
||||||
this.addNode(this.rootDict.xref.fetch(ref), map);
|
this.addNode(this.xref.fetch(ref), map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -733,7 +725,7 @@ class StructTreePage {
|
|||||||
for (const [elemId, type] of ids) {
|
for (const [elemId, type] of ids) {
|
||||||
const obj = numberTree.get(elemId);
|
const obj = numberTree.get(elemId);
|
||||||
if (obj) {
|
if (obj) {
|
||||||
const elem = this.addNode(this.rootDict.xref.fetchIfRef(obj), map);
|
const elem = this.addNode(this.xref.fetchIfRef(obj), map);
|
||||||
if (
|
if (
|
||||||
elem?.kids?.length === 1 &&
|
elem?.kids?.length === 1 &&
|
||||||
elem.kids[0].type === StructElementType.OBJECT
|
elem.kids[0].type === StructElementType.OBJECT
|
||||||
|
|||||||
@ -558,7 +558,6 @@ class WorkerMessageHandler {
|
|||||||
} else if (
|
} else if (
|
||||||
await _structTreeRoot.canUpdateStructTree({
|
await _structTreeRoot.canUpdateStructTree({
|
||||||
pdfManager,
|
pdfManager,
|
||||||
xref,
|
|
||||||
newAnnotationsByPage,
|
newAnnotationsByPage,
|
||||||
})
|
})
|
||||||
) {
|
) {
|
||||||
|
|||||||
@ -5721,12 +5721,7 @@ class Text extends ContentObject {
|
|||||||
if (typeof this[$content] === "string") {
|
if (typeof this[$content] === "string") {
|
||||||
return this[$content]
|
return this[$content]
|
||||||
.split(/[\u2029\u2028\n]/)
|
.split(/[\u2029\u2028\n]/)
|
||||||
.reduce((acc, line) => {
|
.filter(line => !!line)
|
||||||
if (line) {
|
|
||||||
acc.push(line);
|
|
||||||
}
|
|
||||||
return acc;
|
|
||||||
}, [])
|
|
||||||
.join("\n");
|
.join("\n");
|
||||||
}
|
}
|
||||||
return this[$content][$text]();
|
return this[$content][$text]();
|
||||||
@ -5748,18 +5743,15 @@ class Text extends ContentObject {
|
|||||||
.map(para =>
|
.map(para =>
|
||||||
// Convert a paragraph into a set of <span> (for lines)
|
// Convert a paragraph into a set of <span> (for lines)
|
||||||
// separated by <br>.
|
// separated by <br>.
|
||||||
para.split(/[\u2028\n]/).reduce((acc, line) => {
|
para.split(/[\u2028\n]/).flatMap(line => [
|
||||||
acc.push(
|
{
|
||||||
{
|
name: "span",
|
||||||
name: "span",
|
value: line,
|
||||||
value: line,
|
},
|
||||||
},
|
{
|
||||||
{
|
name: "br",
|
||||||
name: "br",
|
},
|
||||||
}
|
])
|
||||||
);
|
|
||||||
return acc;
|
|
||||||
}, [])
|
|
||||||
)
|
)
|
||||||
.forEach(lines => {
|
.forEach(lines => {
|
||||||
html.children.push({
|
html.children.push({
|
||||||
|
|||||||
@ -202,7 +202,7 @@ const defaultOptions = {
|
|||||||
},
|
},
|
||||||
enableAutoLinking: {
|
enableAutoLinking: {
|
||||||
/** @type {boolean} */
|
/** @type {boolean} */
|
||||||
value: typeof PDFJSDev === "undefined" || PDFJSDev.test("MOZCENTRAL"),
|
value: true,
|
||||||
kind: OptionKind.VIEWER + OptionKind.PREFERENCE,
|
kind: OptionKind.VIEWER + OptionKind.PREFERENCE,
|
||||||
},
|
},
|
||||||
enableDetailCanvas: {
|
enableDetailCanvas: {
|
||||||
|
|||||||
@ -95,7 +95,7 @@ import { XfaLayerBuilder } from "./xfa_layer_builder.js";
|
|||||||
* @property {boolean} [enableHWA] - Enables hardware acceleration for
|
* @property {boolean} [enableHWA] - Enables hardware acceleration for
|
||||||
* rendering. The default value is `false`.
|
* rendering. The default value is `false`.
|
||||||
* @property {boolean} [enableAutoLinking] - Enable creation of hyperlinks from
|
* @property {boolean} [enableAutoLinking] - Enable creation of hyperlinks from
|
||||||
* text that look like URLs. The default value is `false`.
|
* text that look like URLs. The default value is `true`.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const DEFAULT_LAYER_PROPERTIES =
|
const DEFAULT_LAYER_PROPERTIES =
|
||||||
@ -130,7 +130,7 @@ class PDFPageView extends BasePDFPageView {
|
|||||||
|
|
||||||
#canvasWrapper = null;
|
#canvasWrapper = null;
|
||||||
|
|
||||||
#enableAutoLinking = false;
|
#enableAutoLinking = true;
|
||||||
|
|
||||||
#hasRestrictedScaling = false;
|
#hasRestrictedScaling = false;
|
||||||
|
|
||||||
@ -188,7 +188,7 @@ class PDFPageView extends BasePDFPageView {
|
|||||||
this.maxCanvasPixels =
|
this.maxCanvasPixels =
|
||||||
options.maxCanvasPixels ?? AppOptions.get("maxCanvasPixels");
|
options.maxCanvasPixels ?? AppOptions.get("maxCanvasPixels");
|
||||||
this.maxCanvasDim = options.maxCanvasDim || AppOptions.get("maxCanvasDim");
|
this.maxCanvasDim = options.maxCanvasDim || AppOptions.get("maxCanvasDim");
|
||||||
this.#enableAutoLinking = options.enableAutoLinking || false;
|
this.#enableAutoLinking = options.enableAutoLinking !== false;
|
||||||
|
|
||||||
this.l10n = options.l10n;
|
this.l10n = options.l10n;
|
||||||
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
|
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
|
||||||
|
|||||||
@ -137,7 +137,7 @@ function isValidAnnotationEditorMode(mode) {
|
|||||||
* @property {boolean} [supportsPinchToZoom] - Enable zooming on pinch gesture.
|
* @property {boolean} [supportsPinchToZoom] - Enable zooming on pinch gesture.
|
||||||
* The default value is `true`.
|
* The default value is `true`.
|
||||||
* @property {boolean} [enableAutoLinking] - Enable creation of hyperlinks from
|
* @property {boolean} [enableAutoLinking] - Enable creation of hyperlinks from
|
||||||
* text that look like URLs. The default value is `false`.
|
* text that look like URLs. The default value is `true`.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class PDFPageViewBuffer {
|
class PDFPageViewBuffer {
|
||||||
@ -238,7 +238,7 @@ class PDFViewer {
|
|||||||
|
|
||||||
#enableNewAltTextWhenAddingImage = false;
|
#enableNewAltTextWhenAddingImage = false;
|
||||||
|
|
||||||
#enableAutoLinking = false;
|
#enableAutoLinking = true;
|
||||||
|
|
||||||
#eventAbortController = null;
|
#eventAbortController = null;
|
||||||
|
|
||||||
@ -340,7 +340,7 @@ class PDFViewer {
|
|||||||
this.#mlManager = options.mlManager || null;
|
this.#mlManager = options.mlManager || null;
|
||||||
this.#enableHWA = options.enableHWA || false;
|
this.#enableHWA = options.enableHWA || false;
|
||||||
this.#supportsPinchToZoom = options.supportsPinchToZoom !== false;
|
this.#supportsPinchToZoom = options.supportsPinchToZoom !== false;
|
||||||
this.#enableAutoLinking = options.enableAutoLinking || false;
|
this.#enableAutoLinking = options.enableAutoLinking !== false;
|
||||||
|
|
||||||
this.defaultRenderingQueue = !options.renderingQueue;
|
this.defaultRenderingQueue = !options.renderingQueue;
|
||||||
if (
|
if (
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user