Skip to content

Commit 62009ff

Browse files
committed
Simplify how the ObjectLoader is used
The `ObjectLoader.prototype.load` method has a fast-path, which avoids any lookup/parsing if the entire PDF document is already loaded. However, we still need to create an `ObjectLoader`-instance which seems unnecessary in that case. Hence we introduce a *static* `ObjectLoader.load` method, which will help avoid creating `ObjectLoader`-instances needlessly and also (slightly) shortens the call-sites. To ensure that the new method will be used, we extend the `no-restricted-syntax` ESLint rule to "forbid" direct usage of `new ObjectLoader()`.
1 parent ef1ad67 commit 62009ff

File tree

4 files changed

+25
-22
lines changed

4 files changed

+25
-22
lines changed

eslint.config.mjs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,11 @@ export default [
303303
selector: "NewExpression[callee.name='Name']",
304304
message: "Use `Name.get()` rather than `new Name()`.",
305305
},
306+
{
307+
selector: "NewExpression[callee.name='ObjectLoader']",
308+
message:
309+
"Use `ObjectLoader.load()` rather than `new ObjectLoader()`.",
310+
},
306311
{
307312
selector: "NewExpression[callee.name='Ref']",
308313
message: "Use `Ref.get()` rather than `new Ref()`.",

src/core/annotation.js

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,15 +1158,12 @@ class Annotation {
11581158
}
11591159
}
11601160

1161-
loadResources(keys, appearance) {
1162-
return appearance.dict.getAsync("Resources").then(resources => {
1163-
if (!resources) {
1164-
return undefined;
1165-
}
1166-
1167-
const objectLoader = new ObjectLoader(resources, keys, resources.xref);
1168-
return objectLoader.load().then(() => resources);
1169-
});
1161+
async loadResources(keys, appearance) {
1162+
const resources = await appearance.dict.getAsync("Resources");
1163+
if (resources) {
1164+
await ObjectLoader.load(resources, keys, resources.xref);
1165+
}
1166+
return resources;
11701167
}
11711168

11721169
async getOperatorList(evaluator, task, intent, annotationStorage) {

src/core/document.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -417,8 +417,7 @@ class Page {
417417
// TODO: add async `_getInheritableProperty` and remove this.
418418
await (this.resourcesPromise ??= this.pdfManager.ensure(this, "resources"));
419419

420-
const objectLoader = new ObjectLoader(this.resources, keys, this.xref);
421-
await objectLoader.load();
420+
await ObjectLoader.load(this.resources, keys, this.xref);
422421
}
423422

424423
async #getMergedResources(streamDict, keys) {
@@ -430,8 +429,7 @@ class Page {
430429
if (!(localResources instanceof Dict && localResources.size)) {
431430
return this.resources;
432431
}
433-
const objectLoader = new ObjectLoader(localResources, keys, this.xref);
434-
await objectLoader.load();
432+
await ObjectLoader.load(localResources, keys, this.xref);
435433

436434
return Dict.merge({
437435
xref: this.xref,
@@ -1254,8 +1252,7 @@ class PDFDocument {
12541252
if (!(resources instanceof Dict)) {
12551253
return;
12561254
}
1257-
const objectLoader = new ObjectLoader(resources, ["Font"], this.xref);
1258-
await objectLoader.load();
1255+
await ObjectLoader.load(resources, ["Font"], this.xref);
12591256

12601257
const fontRes = resources.get("Font");
12611258
if (!(fontRes instanceof Dict)) {

src/core/object_loader.js

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ function addChildren(node, nodesToVisit) {
5454
* entire PDF document object graph to be traversed.
5555
*/
5656
class ObjectLoader {
57-
refSet = null;
57+
refSet = new RefSet();
5858

5959
constructor(dict, keys, xref) {
6060
this.dict = dict;
@@ -63,13 +63,7 @@ class ObjectLoader {
6363
}
6464

6565
async load() {
66-
// Don't walk the graph if all the data is already loaded.
67-
if (this.xref.stream.isDataLoaded) {
68-
return;
69-
}
70-
7166
const { keys, dict } = this;
72-
this.refSet = new RefSet();
7367
// Setup the initial nodes to visit.
7468
const nodesToVisit = [];
7569
for (const key of keys) {
@@ -144,6 +138,16 @@ class ObjectLoader {
144138
await this.#walk(nodesToRevisit);
145139
}
146140
}
141+
142+
static async load(obj, keys, xref) {
143+
// Don't walk the graph if all the data is already loaded.
144+
if (xref.stream.isDataLoaded) {
145+
return;
146+
}
147+
// eslint-disable-next-line no-restricted-syntax
148+
const objLoader = new ObjectLoader(obj, keys, xref);
149+
await objLoader.load();
150+
}
147151
}
148152

149153
export { ObjectLoader };

0 commit comments

Comments
 (0)