|
@@ -2,7 +2,7 @@
|
|
|
* @licstart The following is the entire license notice for the
|
|
|
* Javascript code in this page
|
|
|
*
|
|
|
- * Copyright 2021 Mozilla Foundation
|
|
|
+ * Copyright 2022 Mozilla Foundation
|
|
|
*
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
* you may not use this file except in compliance with the License.
|
|
@@ -26,16 +26,18 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
});
|
|
|
exports.Catalog = void 0;
|
|
|
|
|
|
-var _primitives = require("./primitives.js");
|
|
|
-
|
|
|
var _core_utils = require("./core_utils.js");
|
|
|
|
|
|
var _util = require("../shared/util.js");
|
|
|
|
|
|
+var _primitives = require("./primitives.js");
|
|
|
+
|
|
|
var _name_number_tree = require("./name_number_tree.js");
|
|
|
|
|
|
var _base_stream = require("./base_stream.js");
|
|
|
|
|
|
+var _cleanup_helper = require("./cleanup_helper.js");
|
|
|
+
|
|
|
var _colorspace = require("./colorspace.js");
|
|
|
|
|
|
var _file_spec = require("./file_spec.js");
|
|
@@ -99,7 +101,7 @@ class Catalog {
|
|
|
try {
|
|
|
const obj = this._catDict.get("Collection");
|
|
|
|
|
|
- if ((0, _primitives.isDict)(obj) && obj.size > 0) {
|
|
|
+ if (obj instanceof _primitives.Dict && obj.size > 0) {
|
|
|
collection = obj;
|
|
|
}
|
|
|
} catch (ex) {
|
|
@@ -119,7 +121,7 @@ class Catalog {
|
|
|
try {
|
|
|
const obj = this._catDict.get("AcroForm");
|
|
|
|
|
|
- if ((0, _primitives.isDict)(obj) && obj.size > 0) {
|
|
|
+ if (obj instanceof _primitives.Dict && obj.size > 0) {
|
|
|
acroForm = obj;
|
|
|
}
|
|
|
} catch (ex) {
|
|
@@ -136,7 +138,7 @@ class Catalog {
|
|
|
get acroFormRef() {
|
|
|
const value = this._catDict.getRaw("AcroForm");
|
|
|
|
|
|
- return (0, _util.shadow)(this, "acroFormRef", (0, _primitives.isRef)(value) ? value : null);
|
|
|
+ return (0, _util.shadow)(this, "acroFormRef", value instanceof _primitives.Ref ? value : null);
|
|
|
}
|
|
|
|
|
|
get metadata() {
|
|
@@ -194,7 +196,7 @@ class Catalog {
|
|
|
_readMarkInfo() {
|
|
|
const obj = this._catDict.get("MarkInfo");
|
|
|
|
|
|
- if (!(0, _primitives.isDict)(obj)) {
|
|
|
+ if (!(obj instanceof _primitives.Dict)) {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
@@ -211,7 +213,7 @@ class Catalog {
|
|
|
|
|
|
const value = obj.get(key);
|
|
|
|
|
|
- if (!(0, _util.isBool)(value)) {
|
|
|
+ if (typeof value !== "boolean") {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
@@ -240,7 +242,7 @@ class Catalog {
|
|
|
_readStructTreeRoot() {
|
|
|
const obj = this._catDict.get("StructTreeRoot");
|
|
|
|
|
|
- if (!(0, _primitives.isDict)(obj)) {
|
|
|
+ if (!(obj instanceof _primitives.Dict)) {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
@@ -252,7 +254,7 @@ class Catalog {
|
|
|
get toplevelPagesDict() {
|
|
|
const pagesObj = this._catDict.get("Pages");
|
|
|
|
|
|
- if (!(0, _primitives.isDict)(pagesObj)) {
|
|
|
+ if (!(pagesObj instanceof _primitives.Dict)) {
|
|
|
throw new _util.FormatError("Invalid top-level pages dictionary.");
|
|
|
}
|
|
|
|
|
@@ -278,13 +280,13 @@ class Catalog {
|
|
|
_readDocumentOutline() {
|
|
|
let obj = this._catDict.get("Outlines");
|
|
|
|
|
|
- if (!(0, _primitives.isDict)(obj)) {
|
|
|
+ if (!(obj instanceof _primitives.Dict)) {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
obj = obj.getRaw("First");
|
|
|
|
|
|
- if (!(0, _primitives.isRef)(obj)) {
|
|
|
+ if (!(obj instanceof _primitives.Ref)) {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
@@ -346,7 +348,7 @@ class Catalog {
|
|
|
i.parent.items.push(outlineItem);
|
|
|
obj = outlineDict.getRaw("First");
|
|
|
|
|
|
- if ((0, _primitives.isRef)(obj) && !processed.has(obj)) {
|
|
|
+ if (obj instanceof _primitives.Ref && !processed.has(obj)) {
|
|
|
queue.push({
|
|
|
obj,
|
|
|
parent: outlineItem
|
|
@@ -356,7 +358,7 @@ class Catalog {
|
|
|
|
|
|
obj = outlineDict.getRaw("Next");
|
|
|
|
|
|
- if ((0, _primitives.isRef)(obj) && !processed.has(obj)) {
|
|
|
+ if (obj instanceof _primitives.Ref && !processed.has(obj)) {
|
|
|
queue.push({
|
|
|
obj,
|
|
|
parent: i.parent
|
|
@@ -387,13 +389,13 @@ class Catalog {
|
|
|
_readPermissions() {
|
|
|
const encrypt = this.xref.trailer.get("Encrypt");
|
|
|
|
|
|
- if (!(0, _primitives.isDict)(encrypt)) {
|
|
|
+ if (!(encrypt instanceof _primitives.Dict)) {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
let flags = encrypt.get("P");
|
|
|
|
|
|
- if (!(0, _util.isNum)(flags)) {
|
|
|
+ if (typeof flags !== "number") {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
@@ -437,7 +439,7 @@ class Catalog {
|
|
|
const groupRefs = [];
|
|
|
|
|
|
for (const groupRef of groupsData) {
|
|
|
- if (!(0, _primitives.isRef)(groupRef)) {
|
|
|
+ if (!(groupRef instanceof _primitives.Ref)) {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
@@ -445,8 +447,8 @@ class Catalog {
|
|
|
const group = this.xref.fetchIfRef(groupRef);
|
|
|
groups.push({
|
|
|
id: groupRef.toString(),
|
|
|
- name: (0, _util.isString)(group.get("Name")) ? (0, _util.stringToPDFString)(group.get("Name")) : null,
|
|
|
- intent: (0, _util.isString)(group.get("Intent")) ? (0, _util.stringToPDFString)(group.get("Intent")) : null
|
|
|
+ name: typeof group.get("Name") === "string" ? (0, _util.stringToPDFString)(group.get("Name")) : null,
|
|
|
+ intent: typeof group.get("Intent") === "string" ? (0, _util.stringToPDFString)(group.get("Intent")) : null
|
|
|
});
|
|
|
}
|
|
|
|
|
@@ -469,7 +471,7 @@ class Catalog {
|
|
|
|
|
|
if (Array.isArray(refs)) {
|
|
|
for (const value of refs) {
|
|
|
- if (!(0, _primitives.isRef)(value)) {
|
|
|
+ if (!(value instanceof _primitives.Ref)) {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
@@ -490,7 +492,7 @@ class Catalog {
|
|
|
const order = [];
|
|
|
|
|
|
for (const value of refs) {
|
|
|
- if ((0, _primitives.isRef)(value) && contentGroupRefs.includes(value)) {
|
|
|
+ if (value instanceof _primitives.Ref && contentGroupRefs.includes(value)) {
|
|
|
parsedOrderRefs.put(value);
|
|
|
order.push(value.toString());
|
|
|
continue;
|
|
@@ -561,9 +563,9 @@ class Catalog {
|
|
|
parsedOrderRefs = new _primitives.RefSet(),
|
|
|
MAX_NESTED_LEVELS = 10;
|
|
|
return {
|
|
|
- name: (0, _util.isString)(config.get("Name")) ? (0, _util.stringToPDFString)(config.get("Name")) : null,
|
|
|
- creator: (0, _util.isString)(config.get("Creator")) ? (0, _util.stringToPDFString)(config.get("Creator")) : null,
|
|
|
- baseState: (0, _primitives.isName)(config.get("BaseState")) ? config.get("BaseState").name : null,
|
|
|
+ name: typeof config.get("Name") === "string" ? (0, _util.stringToPDFString)(config.get("Name")) : null,
|
|
|
+ creator: typeof config.get("Creator") === "string" ? (0, _util.stringToPDFString)(config.get("Creator")) : null,
|
|
|
+ baseState: config.get("BaseState") instanceof _primitives.Name ? config.get("BaseState").name : null,
|
|
|
on: parseOnOff(config.get("ON")),
|
|
|
off: parseOnOff(config.get("OFF")),
|
|
|
order: parseOrder(config.get("Order")),
|
|
@@ -692,7 +694,7 @@ class Catalog {
|
|
|
const labelDict = nums.get(i);
|
|
|
|
|
|
if (labelDict !== undefined) {
|
|
|
- if (!(0, _primitives.isDict)(labelDict)) {
|
|
|
+ if (!(labelDict instanceof _primitives.Dict)) {
|
|
|
throw new _util.FormatError("PageLabel is not a dictionary.");
|
|
|
}
|
|
|
|
|
@@ -703,7 +705,7 @@ class Catalog {
|
|
|
if (labelDict.has("S")) {
|
|
|
const s = labelDict.get("S");
|
|
|
|
|
|
- if (!(0, _primitives.isName)(s)) {
|
|
|
+ if (!(s instanceof _primitives.Name)) {
|
|
|
throw new _util.FormatError("Invalid style in PageLabel dictionary.");
|
|
|
}
|
|
|
|
|
@@ -715,7 +717,7 @@ class Catalog {
|
|
|
if (labelDict.has("P")) {
|
|
|
const p = labelDict.get("P");
|
|
|
|
|
|
- if (!(0, _util.isString)(p)) {
|
|
|
+ if (typeof p !== "string") {
|
|
|
throw new _util.FormatError("Invalid prefix in PageLabel dictionary.");
|
|
|
}
|
|
|
|
|
@@ -784,7 +786,7 @@ class Catalog {
|
|
|
|
|
|
let pageLayout = "";
|
|
|
|
|
|
- if ((0, _primitives.isName)(obj)) {
|
|
|
+ if (obj instanceof _primitives.Name) {
|
|
|
switch (obj.name) {
|
|
|
case "SinglePage":
|
|
|
case "OneColumn":
|
|
@@ -804,7 +806,7 @@ class Catalog {
|
|
|
|
|
|
let pageMode = "UseNone";
|
|
|
|
|
|
- if ((0, _primitives.isName)(obj)) {
|
|
|
+ if (obj instanceof _primitives.Name) {
|
|
|
switch (obj.name) {
|
|
|
case "UseNone":
|
|
|
case "UseOutlines":
|
|
@@ -820,47 +822,34 @@ class Catalog {
|
|
|
}
|
|
|
|
|
|
get viewerPreferences() {
|
|
|
- const ViewerPreferencesValidators = {
|
|
|
- HideToolbar: _util.isBool,
|
|
|
- HideMenubar: _util.isBool,
|
|
|
- HideWindowUI: _util.isBool,
|
|
|
- FitWindow: _util.isBool,
|
|
|
- CenterWindow: _util.isBool,
|
|
|
- DisplayDocTitle: _util.isBool,
|
|
|
- NonFullScreenPageMode: _primitives.isName,
|
|
|
- Direction: _primitives.isName,
|
|
|
- ViewArea: _primitives.isName,
|
|
|
- ViewClip: _primitives.isName,
|
|
|
- PrintArea: _primitives.isName,
|
|
|
- PrintClip: _primitives.isName,
|
|
|
- PrintScaling: _primitives.isName,
|
|
|
- Duplex: _primitives.isName,
|
|
|
- PickTrayByPDFSize: _util.isBool,
|
|
|
- PrintPageRange: Array.isArray,
|
|
|
- NumCopies: Number.isInteger
|
|
|
- };
|
|
|
-
|
|
|
const obj = this._catDict.get("ViewerPreferences");
|
|
|
|
|
|
- let prefs = null;
|
|
|
-
|
|
|
- if ((0, _primitives.isDict)(obj)) {
|
|
|
- for (const key in ViewerPreferencesValidators) {
|
|
|
- if (!obj.has(key)) {
|
|
|
- continue;
|
|
|
- }
|
|
|
+ if (!(obj instanceof _primitives.Dict)) {
|
|
|
+ return (0, _util.shadow)(this, "viewerPreferences", null);
|
|
|
+ }
|
|
|
|
|
|
- const value = obj.get(key);
|
|
|
+ let prefs = null;
|
|
|
|
|
|
- if (!ViewerPreferencesValidators[key](value)) {
|
|
|
- (0, _util.info)(`Bad value in ViewerPreferences for "${key}".`);
|
|
|
- continue;
|
|
|
- }
|
|
|
+ for (const key of obj.getKeys()) {
|
|
|
+ const value = obj.get(key);
|
|
|
+ let prefValue;
|
|
|
+
|
|
|
+ switch (key) {
|
|
|
+ case "HideToolbar":
|
|
|
+ case "HideMenubar":
|
|
|
+ case "HideWindowUI":
|
|
|
+ case "FitWindow":
|
|
|
+ case "CenterWindow":
|
|
|
+ case "DisplayDocTitle":
|
|
|
+ case "PickTrayByPDFSize":
|
|
|
+ if (typeof value === "boolean") {
|
|
|
+ prefValue = value;
|
|
|
+ }
|
|
|
|
|
|
- let prefValue;
|
|
|
+ break;
|
|
|
|
|
|
- switch (key) {
|
|
|
- case "NonFullScreenPageMode":
|
|
|
+ case "NonFullScreenPageMode":
|
|
|
+ if (value instanceof _primitives.Name) {
|
|
|
switch (value.name) {
|
|
|
case "UseNone":
|
|
|
case "UseOutlines":
|
|
@@ -872,10 +861,12 @@ class Catalog {
|
|
|
default:
|
|
|
prefValue = "UseNone";
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- break;
|
|
|
+ break;
|
|
|
|
|
|
- case "Direction":
|
|
|
+ case "Direction":
|
|
|
+ if (value instanceof _primitives.Name) {
|
|
|
switch (value.name) {
|
|
|
case "L2R":
|
|
|
case "R2L":
|
|
@@ -885,13 +876,15 @@ class Catalog {
|
|
|
default:
|
|
|
prefValue = "L2R";
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- break;
|
|
|
+ break;
|
|
|
|
|
|
- case "ViewArea":
|
|
|
- case "ViewClip":
|
|
|
- case "PrintArea":
|
|
|
- case "PrintClip":
|
|
|
+ case "ViewArea":
|
|
|
+ case "ViewClip":
|
|
|
+ case "PrintArea":
|
|
|
+ case "PrintClip":
|
|
|
+ if (value instanceof _primitives.Name) {
|
|
|
switch (value.name) {
|
|
|
case "MediaBox":
|
|
|
case "CropBox":
|
|
@@ -904,10 +897,12 @@ class Catalog {
|
|
|
default:
|
|
|
prefValue = "CropBox";
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- break;
|
|
|
+ break;
|
|
|
|
|
|
- case "PrintScaling":
|
|
|
+ case "PrintScaling":
|
|
|
+ if (value instanceof _primitives.Name) {
|
|
|
switch (value.name) {
|
|
|
case "None":
|
|
|
case "AppDefault":
|
|
@@ -917,10 +912,12 @@ class Catalog {
|
|
|
default:
|
|
|
prefValue = "AppDefault";
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- break;
|
|
|
+ break;
|
|
|
|
|
|
- case "Duplex":
|
|
|
+ case "Duplex":
|
|
|
+ if (value instanceof _primitives.Name) {
|
|
|
switch (value.name) {
|
|
|
case "Simplex":
|
|
|
case "DuplexFlipShortEdge":
|
|
@@ -931,16 +928,12 @@ class Catalog {
|
|
|
default:
|
|
|
prefValue = "None";
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- break;
|
|
|
-
|
|
|
- case "PrintPageRange":
|
|
|
- const length = value.length;
|
|
|
-
|
|
|
- if (length % 2 !== 0) {
|
|
|
- break;
|
|
|
- }
|
|
|
+ break;
|
|
|
|
|
|
+ case "PrintPageRange":
|
|
|
+ if (Array.isArray(value) && value.length % 2 === 0) {
|
|
|
const isValid = value.every((page, i, arr) => {
|
|
|
return Number.isInteger(page) && page > 0 && (i === 0 || page >= arr[i - 1]) && page <= this.numPages;
|
|
|
});
|
|
@@ -948,34 +941,32 @@ class Catalog {
|
|
|
if (isValid) {
|
|
|
prefValue = value;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- break;
|
|
|
-
|
|
|
- case "NumCopies":
|
|
|
- if (value > 0) {
|
|
|
- prefValue = value;
|
|
|
- }
|
|
|
+ break;
|
|
|
|
|
|
- break;
|
|
|
+ case "NumCopies":
|
|
|
+ if (Number.isInteger(value) && value > 0) {
|
|
|
+ prefValue = value;
|
|
|
+ }
|
|
|
|
|
|
- default:
|
|
|
- if (typeof value !== "boolean") {
|
|
|
- throw new _util.FormatError(`viewerPreferences - expected a boolean value for: ${key}`);
|
|
|
- }
|
|
|
+ break;
|
|
|
|
|
|
- prefValue = value;
|
|
|
- }
|
|
|
+ default:
|
|
|
+ (0, _util.warn)(`Ignoring non-standard key in ViewerPreferences: ${key}.`);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- if (prefValue !== undefined) {
|
|
|
- if (!prefs) {
|
|
|
- prefs = Object.create(null);
|
|
|
- }
|
|
|
+ if (prefValue === undefined) {
|
|
|
+ (0, _util.warn)(`Bad value, for key "${key}", in ViewerPreferences: ${value}.`);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- prefs[key] = prefValue;
|
|
|
- } else {
|
|
|
- (0, _util.info)(`Bad value in ViewerPreferences for "${key}".`);
|
|
|
- }
|
|
|
+ if (!prefs) {
|
|
|
+ prefs = Object.create(null);
|
|
|
}
|
|
|
+
|
|
|
+ prefs[key] = prefValue;
|
|
|
}
|
|
|
|
|
|
return (0, _util.shadow)(this, "viewerPreferences", prefs);
|
|
@@ -986,7 +977,7 @@ class Catalog {
|
|
|
|
|
|
const openAction = Object.create(null);
|
|
|
|
|
|
- if ((0, _primitives.isDict)(obj)) {
|
|
|
+ if (obj instanceof _primitives.Dict) {
|
|
|
const destDict = new _primitives.Dict(this.xref);
|
|
|
destDict.set("A", obj);
|
|
|
const resultObj = {
|
|
@@ -1069,7 +1060,7 @@ class Catalog {
|
|
|
|
|
|
let js = jsDict.get("JS");
|
|
|
|
|
|
- if ((0, _primitives.isStream)(js)) {
|
|
|
+ if (js instanceof _base_stream.BaseStream) {
|
|
|
js = js.getString();
|
|
|
} else if (typeof js !== "string") {
|
|
|
return;
|
|
@@ -1143,7 +1134,7 @@ class Catalog {
|
|
|
}
|
|
|
|
|
|
cleanup(manuallyTriggered = false) {
|
|
|
- (0, _primitives.clearPrimitiveCaches)();
|
|
|
+ (0, _cleanup_helper.clearGlobalCaches)();
|
|
|
this.globalImageCache.clear(manuallyTriggered);
|
|
|
this.pageKidsCountCache.clear();
|
|
|
this.pageIndexCache.clear();
|
|
@@ -1165,8 +1156,7 @@ class Catalog {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- getPageDict(pageIndex) {
|
|
|
- const capability = (0, _util.createPromiseCapability)();
|
|
|
+ async getPageDict(pageIndex) {
|
|
|
const nodesToVisit = [this.toplevelPagesDict];
|
|
|
const visitedNodes = new _primitives.RefSet();
|
|
|
|
|
@@ -1177,125 +1167,115 @@ class Catalog {
|
|
|
}
|
|
|
|
|
|
const xref = this.xref,
|
|
|
- pageKidsCountCache = this.pageKidsCountCache;
|
|
|
+ pageKidsCountCache = this.pageKidsCountCache,
|
|
|
+ pageIndexCache = this.pageIndexCache;
|
|
|
let currentPageIndex = 0;
|
|
|
|
|
|
- function next() {
|
|
|
- while (nodesToVisit.length) {
|
|
|
- const currentNode = nodesToVisit.pop();
|
|
|
+ while (nodesToVisit.length) {
|
|
|
+ const currentNode = nodesToVisit.pop();
|
|
|
|
|
|
- if (currentNode instanceof _primitives.Ref) {
|
|
|
- const count = pageKidsCountCache.get(currentNode);
|
|
|
+ if (currentNode instanceof _primitives.Ref) {
|
|
|
+ const count = pageKidsCountCache.get(currentNode);
|
|
|
|
|
|
- if (count >= 0 && currentPageIndex + count <= pageIndex) {
|
|
|
- currentPageIndex += count;
|
|
|
- continue;
|
|
|
- }
|
|
|
+ if (count >= 0 && currentPageIndex + count <= pageIndex) {
|
|
|
+ currentPageIndex += count;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- if (visitedNodes.has(currentNode)) {
|
|
|
- capability.reject(new _util.FormatError("Pages tree contains circular reference."));
|
|
|
- return;
|
|
|
- }
|
|
|
+ if (visitedNodes.has(currentNode)) {
|
|
|
+ throw new _util.FormatError("Pages tree contains circular reference.");
|
|
|
+ }
|
|
|
|
|
|
- visitedNodes.put(currentNode);
|
|
|
- xref.fetchAsync(currentNode).then(function (obj) {
|
|
|
- if ((0, _primitives.isDict)(obj, "Page") || (0, _primitives.isDict)(obj) && !obj.has("Kids")) {
|
|
|
- if (currentNode && !pageKidsCountCache.has(currentNode)) {
|
|
|
- pageKidsCountCache.put(currentNode, 1);
|
|
|
- }
|
|
|
+ visitedNodes.put(currentNode);
|
|
|
+ const obj = await xref.fetchAsync(currentNode);
|
|
|
|
|
|
- if (pageIndex === currentPageIndex) {
|
|
|
- capability.resolve([obj, currentNode]);
|
|
|
- } else {
|
|
|
- currentPageIndex++;
|
|
|
- next();
|
|
|
- }
|
|
|
+ if (obj instanceof _primitives.Dict) {
|
|
|
+ let type = obj.getRaw("Type");
|
|
|
|
|
|
- return;
|
|
|
- }
|
|
|
+ if (type instanceof _primitives.Ref) {
|
|
|
+ type = await xref.fetchAsync(type);
|
|
|
+ }
|
|
|
|
|
|
- nodesToVisit.push(obj);
|
|
|
- next();
|
|
|
- }, capability.reject);
|
|
|
- return;
|
|
|
- }
|
|
|
+ if ((0, _primitives.isName)(type, "Page") || !obj.has("Kids")) {
|
|
|
+ if (!pageKidsCountCache.has(currentNode)) {
|
|
|
+ pageKidsCountCache.put(currentNode, 1);
|
|
|
+ }
|
|
|
|
|
|
- if (!(currentNode instanceof _primitives.Dict)) {
|
|
|
- capability.reject(new _util.FormatError("Page dictionary kid reference points to wrong type of object."));
|
|
|
- return;
|
|
|
- }
|
|
|
+ if (!pageIndexCache.has(currentNode)) {
|
|
|
+ pageIndexCache.put(currentNode, currentPageIndex);
|
|
|
+ }
|
|
|
|
|
|
- let count;
|
|
|
+ if (currentPageIndex === pageIndex) {
|
|
|
+ return [obj, currentNode];
|
|
|
+ }
|
|
|
|
|
|
- try {
|
|
|
- count = currentNode.get("Count");
|
|
|
- } catch (ex) {
|
|
|
- if (ex instanceof _core_utils.MissingDataException) {
|
|
|
- throw ex;
|
|
|
+ currentPageIndex++;
|
|
|
+ continue;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (Number.isInteger(count) && count >= 0) {
|
|
|
- const objId = currentNode.objId;
|
|
|
+ nodesToVisit.push(obj);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- if (objId && !pageKidsCountCache.has(objId)) {
|
|
|
- pageKidsCountCache.put(objId, count);
|
|
|
- }
|
|
|
+ if (!(currentNode instanceof _primitives.Dict)) {
|
|
|
+ throw new _util.FormatError("Page dictionary kid reference points to wrong type of object.");
|
|
|
+ }
|
|
|
|
|
|
- if (currentPageIndex + count <= pageIndex) {
|
|
|
- currentPageIndex += count;
|
|
|
- continue;
|
|
|
- }
|
|
|
- }
|
|
|
+ const {
|
|
|
+ objId
|
|
|
+ } = currentNode;
|
|
|
+ let count = currentNode.getRaw("Count");
|
|
|
|
|
|
- let kids;
|
|
|
+ if (count instanceof _primitives.Ref) {
|
|
|
+ count = await xref.fetchAsync(count);
|
|
|
+ }
|
|
|
|
|
|
- try {
|
|
|
- kids = currentNode.get("Kids");
|
|
|
- } catch (ex) {
|
|
|
- if (ex instanceof _core_utils.MissingDataException) {
|
|
|
- throw ex;
|
|
|
- }
|
|
|
+ if (Number.isInteger(count) && count >= 0) {
|
|
|
+ if (objId && !pageKidsCountCache.has(objId)) {
|
|
|
+ pageKidsCountCache.put(objId, count);
|
|
|
}
|
|
|
|
|
|
- if (!Array.isArray(kids)) {
|
|
|
- let type;
|
|
|
+ if (currentPageIndex + count <= pageIndex) {
|
|
|
+ currentPageIndex += count;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- try {
|
|
|
- type = currentNode.get("Type");
|
|
|
- } catch (ex) {
|
|
|
- if (ex instanceof _core_utils.MissingDataException) {
|
|
|
- throw ex;
|
|
|
- }
|
|
|
- }
|
|
|
+ let kids = currentNode.getRaw("Kids");
|
|
|
|
|
|
- if ((0, _primitives.isName)(type, "Page") || !currentNode.has("Type") && currentNode.has("Contents")) {
|
|
|
- if (currentPageIndex === pageIndex) {
|
|
|
- capability.resolve([currentNode, null]);
|
|
|
- return;
|
|
|
- }
|
|
|
+ if (kids instanceof _primitives.Ref) {
|
|
|
+ kids = await xref.fetchAsync(kids);
|
|
|
+ }
|
|
|
|
|
|
- currentPageIndex++;
|
|
|
- continue;
|
|
|
- }
|
|
|
+ if (!Array.isArray(kids)) {
|
|
|
+ let type = currentNode.getRaw("Type");
|
|
|
|
|
|
- capability.reject(new _util.FormatError("Page dictionary kids object is not an array."));
|
|
|
- return;
|
|
|
+ if (type instanceof _primitives.Ref) {
|
|
|
+ type = await xref.fetchAsync(type);
|
|
|
}
|
|
|
|
|
|
- for (let last = kids.length - 1; last >= 0; last--) {
|
|
|
- nodesToVisit.push(kids[last]);
|
|
|
+ if ((0, _primitives.isName)(type, "Page") || !currentNode.has("Kids")) {
|
|
|
+ if (currentPageIndex === pageIndex) {
|
|
|
+ return [currentNode, null];
|
|
|
+ }
|
|
|
+
|
|
|
+ currentPageIndex++;
|
|
|
+ continue;
|
|
|
}
|
|
|
+
|
|
|
+ throw new _util.FormatError("Page dictionary kids object is not an array.");
|
|
|
}
|
|
|
|
|
|
- capability.reject(new Error(`Page index ${pageIndex} not found.`));
|
|
|
+ for (let last = kids.length - 1; last >= 0; last--) {
|
|
|
+ nodesToVisit.push(kids[last]);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- next();
|
|
|
- return capability.promise;
|
|
|
+ throw new Error(`Page index ${pageIndex} not found.`);
|
|
|
}
|
|
|
|
|
|
- getAllPageDicts(recoveryMode = false) {
|
|
|
+ async getAllPageDicts(recoveryMode = false) {
|
|
|
const queue = [{
|
|
|
currentNode: this.toplevelPagesDict,
|
|
|
posInKids: 0
|
|
@@ -1308,14 +1288,24 @@ class Catalog {
|
|
|
visitedNodes.put(pagesRef);
|
|
|
}
|
|
|
|
|
|
- const map = new Map();
|
|
|
+ const map = new Map(),
|
|
|
+ xref = this.xref,
|
|
|
+ pageIndexCache = this.pageIndexCache;
|
|
|
let pageIndex = 0;
|
|
|
|
|
|
function addPageDict(pageDict, pageRef) {
|
|
|
+ if (pageRef && !pageIndexCache.has(pageRef)) {
|
|
|
+ pageIndexCache.put(pageRef, pageIndex);
|
|
|
+ }
|
|
|
+
|
|
|
map.set(pageIndex++, [pageDict, pageRef]);
|
|
|
}
|
|
|
|
|
|
function addPageError(error) {
|
|
|
+ if (error instanceof _core_utils.XRefEntryException && !recoveryMode) {
|
|
|
+ throw error;
|
|
|
+ }
|
|
|
+
|
|
|
map.set(pageIndex++, [error, null]);
|
|
|
}
|
|
|
|
|
@@ -1325,21 +1315,15 @@ class Catalog {
|
|
|
currentNode,
|
|
|
posInKids
|
|
|
} = queueItem;
|
|
|
- let kids;
|
|
|
+ let kids = currentNode.getRaw("Kids");
|
|
|
|
|
|
- try {
|
|
|
- kids = currentNode.get("Kids");
|
|
|
- } catch (ex) {
|
|
|
- if (ex instanceof _core_utils.MissingDataException) {
|
|
|
- throw ex;
|
|
|
- }
|
|
|
-
|
|
|
- if (ex instanceof _core_utils.XRefEntryException && !recoveryMode) {
|
|
|
- throw ex;
|
|
|
+ if (kids instanceof _primitives.Ref) {
|
|
|
+ try {
|
|
|
+ kids = await xref.fetchAsync(kids);
|
|
|
+ } catch (ex) {
|
|
|
+ addPageError(ex);
|
|
|
+ break;
|
|
|
}
|
|
|
-
|
|
|
- addPageError(ex);
|
|
|
- break;
|
|
|
}
|
|
|
|
|
|
if (!Array.isArray(kids)) {
|
|
@@ -1356,27 +1340,19 @@ class Catalog {
|
|
|
let obj;
|
|
|
|
|
|
if (kidObj instanceof _primitives.Ref) {
|
|
|
- try {
|
|
|
- obj = this.xref.fetch(kidObj);
|
|
|
- } catch (ex) {
|
|
|
- if (ex instanceof _core_utils.MissingDataException) {
|
|
|
- throw ex;
|
|
|
- }
|
|
|
-
|
|
|
- if (ex instanceof _core_utils.XRefEntryException && !recoveryMode) {
|
|
|
- throw ex;
|
|
|
- }
|
|
|
-
|
|
|
- addPageError(ex);
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
if (visitedNodes.has(kidObj)) {
|
|
|
addPageError(new _util.FormatError("Pages tree contains circular reference."));
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
visitedNodes.put(kidObj);
|
|
|
+
|
|
|
+ try {
|
|
|
+ obj = await xref.fetchAsync(kidObj);
|
|
|
+ } catch (ex) {
|
|
|
+ addPageError(ex);
|
|
|
+ break;
|
|
|
+ }
|
|
|
} else {
|
|
|
obj = kidObj;
|
|
|
}
|
|
@@ -1386,7 +1362,18 @@ class Catalog {
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- if ((0, _primitives.isDict)(obj, "Page") || !obj.has("Kids")) {
|
|
|
+ let type = obj.getRaw("Type");
|
|
|
+
|
|
|
+ if (type instanceof _primitives.Ref) {
|
|
|
+ try {
|
|
|
+ type = await xref.fetchAsync(type);
|
|
|
+ } catch (ex) {
|
|
|
+ addPageError(ex);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((0, _primitives.isName)(type, "Page") || !obj.has("Kids")) {
|
|
|
addPageDict(obj, kidObj instanceof _primitives.Ref ? kidObj : null);
|
|
|
} else {
|
|
|
queue.push({
|
|
@@ -1414,7 +1401,7 @@ class Catalog {
|
|
|
let total = 0,
|
|
|
parentRef;
|
|
|
return xref.fetchAsync(kidRef).then(function (node) {
|
|
|
- if ((0, _primitives.isRefsEqual)(kidRef, pageRef) && !(0, _primitives.isDict)(node, "Page") && !((0, _primitives.isDict)(node) && !node.has("Type") && node.has("Contents"))) {
|
|
|
+ if ((0, _primitives.isRefsEqual)(kidRef, pageRef) && !(0, _primitives.isDict)(node, "Page") && !(node instanceof _primitives.Dict && !node.has("Type") && node.has("Contents"))) {
|
|
|
throw new _util.FormatError("The reference does not point to a /Page dictionary.");
|
|
|
}
|
|
|
|
|
@@ -1422,7 +1409,7 @@ class Catalog {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- if (!(0, _primitives.isDict)(node)) {
|
|
|
+ if (!(node instanceof _primitives.Dict)) {
|
|
|
throw new _util.FormatError("Node must be a dictionary.");
|
|
|
}
|
|
|
|
|
@@ -1433,7 +1420,7 @@ class Catalog {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- if (!(0, _primitives.isDict)(parent)) {
|
|
|
+ if (!(parent instanceof _primitives.Dict)) {
|
|
|
throw new _util.FormatError("Parent must be a dictionary.");
|
|
|
}
|
|
|
|
|
@@ -1449,7 +1436,7 @@ class Catalog {
|
|
|
for (let i = 0, ii = kids.length; i < ii; i++) {
|
|
|
const kid = kids[i];
|
|
|
|
|
|
- if (!(0, _primitives.isRef)(kid)) {
|
|
|
+ if (!(kid instanceof _primitives.Ref)) {
|
|
|
throw new _util.FormatError("Kid must be a reference.");
|
|
|
}
|
|
|
|
|
@@ -1459,7 +1446,7 @@ class Catalog {
|
|
|
}
|
|
|
|
|
|
kidPromises.push(xref.fetchAsync(kid).then(function (obj) {
|
|
|
- if (!(0, _primitives.isDict)(obj)) {
|
|
|
+ if (!(obj instanceof _primitives.Dict)) {
|
|
|
throw new _util.FormatError("Kid node must be a dictionary.");
|
|
|
}
|
|
|
|
|
@@ -1500,7 +1487,7 @@ class Catalog {
|
|
|
static parseDestDictionary(params) {
|
|
|
const destDict = params.destDict;
|
|
|
|
|
|
- if (!(0, _primitives.isDict)(destDict)) {
|
|
|
+ if (!(destDict instanceof _primitives.Dict)) {
|
|
|
(0, _util.warn)("parseDestDictionary: `destDict` must be a dictionary.");
|
|
|
return;
|
|
|
}
|
|
@@ -1517,13 +1504,13 @@ class Catalog {
|
|
|
url,
|
|
|
dest;
|
|
|
|
|
|
- if (!(0, _primitives.isDict)(action)) {
|
|
|
+ if (!(action instanceof _primitives.Dict)) {
|
|
|
if (destDict.has("Dest")) {
|
|
|
action = destDict.get("Dest");
|
|
|
} else {
|
|
|
action = destDict.get("AA");
|
|
|
|
|
|
- if ((0, _primitives.isDict)(action)) {
|
|
|
+ if (action instanceof _primitives.Dict) {
|
|
|
if (action.has("D")) {
|
|
|
action = action.get("D");
|
|
|
} else if (action.has("U")) {
|
|
@@ -1533,10 +1520,10 @@ class Catalog {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if ((0, _primitives.isDict)(action)) {
|
|
|
+ if (action instanceof _primitives.Dict) {
|
|
|
const actionType = action.get("S");
|
|
|
|
|
|
- if (!(0, _primitives.isName)(actionType)) {
|
|
|
+ if (!(actionType instanceof _primitives.Name)) {
|
|
|
(0, _util.warn)("parseDestDictionary: Invalid type in Action dictionary.");
|
|
|
return;
|
|
|
}
|
|
@@ -1546,14 +1533,14 @@ class Catalog {
|
|
|
switch (actionName) {
|
|
|
case "ResetForm":
|
|
|
const flags = action.get("Flags");
|
|
|
- const include = (((0, _util.isNum)(flags) ? flags : 0) & 1) === 0;
|
|
|
+ const include = ((typeof flags === "number" ? flags : 0) & 1) === 0;
|
|
|
const fields = [];
|
|
|
const refs = [];
|
|
|
|
|
|
for (const obj of action.get("Fields") || []) {
|
|
|
- if ((0, _primitives.isRef)(obj)) {
|
|
|
+ if (obj instanceof _primitives.Ref) {
|
|
|
refs.push(obj.toString());
|
|
|
- } else if ((0, _util.isString)(obj)) {
|
|
|
+ } else if (typeof obj === "string") {
|
|
|
fields.push((0, _util.stringToPDFString)(obj));
|
|
|
}
|
|
|
}
|
|
@@ -1582,23 +1569,23 @@ class Catalog {
|
|
|
case "GoToR":
|
|
|
const urlDict = action.get("F");
|
|
|
|
|
|
- if ((0, _primitives.isDict)(urlDict)) {
|
|
|
+ if (urlDict instanceof _primitives.Dict) {
|
|
|
url = urlDict.get("F") || null;
|
|
|
- } else if ((0, _util.isString)(urlDict)) {
|
|
|
+ } else if (typeof urlDict === "string") {
|
|
|
url = urlDict;
|
|
|
}
|
|
|
|
|
|
let remoteDest = action.get("D");
|
|
|
|
|
|
if (remoteDest) {
|
|
|
- if ((0, _primitives.isName)(remoteDest)) {
|
|
|
+ if (remoteDest instanceof _primitives.Name) {
|
|
|
remoteDest = remoteDest.name;
|
|
|
}
|
|
|
|
|
|
- if ((0, _util.isString)(url)) {
|
|
|
+ if (typeof url === "string") {
|
|
|
const baseUrl = url.split("#")[0];
|
|
|
|
|
|
- if ((0, _util.isString)(remoteDest)) {
|
|
|
+ if (typeof remoteDest === "string") {
|
|
|
url = baseUrl + "#" + remoteDest;
|
|
|
} else if (Array.isArray(remoteDest)) {
|
|
|
url = baseUrl + "#" + JSON.stringify(remoteDest);
|
|
@@ -1608,7 +1595,7 @@ class Catalog {
|
|
|
|
|
|
const newWindow = action.get("NewWindow");
|
|
|
|
|
|
- if ((0, _util.isBool)(newWindow)) {
|
|
|
+ if (typeof newWindow === "boolean") {
|
|
|
resultObj.newWindow = newWindow;
|
|
|
}
|
|
|
|
|
@@ -1617,7 +1604,7 @@ class Catalog {
|
|
|
case "Named":
|
|
|
const namedAction = action.get("N");
|
|
|
|
|
|
- if ((0, _primitives.isName)(namedAction)) {
|
|
|
+ if (namedAction instanceof _primitives.Name) {
|
|
|
resultObj.action = namedAction.name;
|
|
|
}
|
|
|
|
|
@@ -1627,9 +1614,9 @@ class Catalog {
|
|
|
const jsAction = action.get("JS");
|
|
|
let js;
|
|
|
|
|
|
- if ((0, _primitives.isStream)(jsAction)) {
|
|
|
+ if (jsAction instanceof _base_stream.BaseStream) {
|
|
|
js = jsAction.getString();
|
|
|
- } else if ((0, _util.isString)(jsAction)) {
|
|
|
+ } else if (typeof jsAction === "string") {
|
|
|
js = jsAction;
|
|
|
}
|
|
|
|
|
@@ -1653,7 +1640,7 @@ class Catalog {
|
|
|
dest = destDict.get("Dest");
|
|
|
}
|
|
|
|
|
|
- if ((0, _util.isString)(url)) {
|
|
|
+ if (typeof url === "string") {
|
|
|
const absoluteUrl = (0, _util.createValidAbsoluteUrl)(url, docBaseUrl, {
|
|
|
addDefaultProtocol: true,
|
|
|
tryConvertEncoding: true
|
|
@@ -1667,11 +1654,11 @@ class Catalog {
|
|
|
}
|
|
|
|
|
|
if (dest) {
|
|
|
- if ((0, _primitives.isName)(dest)) {
|
|
|
+ if (dest instanceof _primitives.Name) {
|
|
|
dest = dest.name;
|
|
|
}
|
|
|
|
|
|
- if ((0, _util.isString)(dest) || Array.isArray(dest)) {
|
|
|
+ if (typeof dest === "string" || Array.isArray(dest)) {
|
|
|
resultObj.dest = dest;
|
|
|
}
|
|
|
}
|