2017-01-09 00:51:30 +09:00
|
|
|
/* Copyright 2017 Mozilla Foundation
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2020-08-23 21:04:49 +09:00
|
|
|
import { createIdFactory, XRefMock } from "./test_utils.js";
|
|
|
|
import { Dict, Name, Ref } from "../../src/core/primitives.js";
|
|
|
|
import { PDFDocument } from "../../src/core/document.js";
|
|
|
|
import { StringStream } from "../../src/core/stream.js";
|
2017-01-09 00:51:30 +09:00
|
|
|
|
2020-04-14 19:28:14 +09:00
|
|
|
describe("document", function () {
|
|
|
|
describe("Page", function () {
|
Re-factor the `idFactory` functionality, used in the `core/`-code, and move the `fontID` generation into it
Note how the `getFontID`-method in `src/core/fonts.js` is *completely* global, rather than properly tied to the current document. This means that if you repeatedly open and parse/render, and then close, even the *same* PDF document the `fontID`s will still be incremented continuously.
For comparison the `createObjId` method, on `idFactory`, will always create a *consistent* id, assuming of course that the document and its pages are parsed/rendered in the same order.
In order to address this inconsistency, it thus seems reasonable to add a new `createFontId` method on the `idFactory` and use that when obtaining `fontID`s. (When the current `getFontID` method was added the `idFactory` didn't actually exist yet, which explains why the code looks the way it does.)
*Please note:* Since the document id is (still) part of the `loadedName`, it's thus not possible for different documents to have identical font names.
2020-07-07 23:00:05 +09:00
|
|
|
it("should create correct objId/fontId using the idFactory", function () {
|
2019-04-20 19:36:49 +09:00
|
|
|
const idFactory1 = createIdFactory(/* pageIndex = */ 0);
|
|
|
|
const idFactory2 = createIdFactory(/* pageIndex = */ 1);
|
2017-01-09 00:51:30 +09:00
|
|
|
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
expect(idFactory1.createObjId()).toEqual("p0_1");
|
|
|
|
expect(idFactory1.createObjId()).toEqual("p0_2");
|
Re-factor the `idFactory` functionality, used in the `core/`-code, and move the `fontID` generation into it
Note how the `getFontID`-method in `src/core/fonts.js` is *completely* global, rather than properly tied to the current document. This means that if you repeatedly open and parse/render, and then close, even the *same* PDF document the `fontID`s will still be incremented continuously.
For comparison the `createObjId` method, on `idFactory`, will always create a *consistent* id, assuming of course that the document and its pages are parsed/rendered in the same order.
In order to address this inconsistency, it thus seems reasonable to add a new `createFontId` method on the `idFactory` and use that when obtaining `fontID`s. (When the current `getFontID` method was added the `idFactory` didn't actually exist yet, which explains why the code looks the way it does.)
*Please note:* Since the document id is (still) part of the `loadedName`, it's thus not possible for different documents to have identical font names.
2020-07-07 23:00:05 +09:00
|
|
|
expect(idFactory1.createFontId()).toEqual("f1");
|
|
|
|
expect(idFactory1.createFontId()).toEqual("f2");
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
expect(idFactory1.getDocId()).toEqual("g_d0");
|
2017-01-09 00:51:30 +09:00
|
|
|
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
expect(idFactory2.createObjId()).toEqual("p1_1");
|
|
|
|
expect(idFactory2.createObjId()).toEqual("p1_2");
|
Re-factor the `idFactory` functionality, used in the `core/`-code, and move the `fontID` generation into it
Note how the `getFontID`-method in `src/core/fonts.js` is *completely* global, rather than properly tied to the current document. This means that if you repeatedly open and parse/render, and then close, even the *same* PDF document the `fontID`s will still be incremented continuously.
For comparison the `createObjId` method, on `idFactory`, will always create a *consistent* id, assuming of course that the document and its pages are parsed/rendered in the same order.
In order to address this inconsistency, it thus seems reasonable to add a new `createFontId` method on the `idFactory` and use that when obtaining `fontID`s. (When the current `getFontID` method was added the `idFactory` didn't actually exist yet, which explains why the code looks the way it does.)
*Please note:* Since the document id is (still) part of the `loadedName`, it's thus not possible for different documents to have identical font names.
2020-07-07 23:00:05 +09:00
|
|
|
expect(idFactory2.createFontId()).toEqual("f1");
|
|
|
|
expect(idFactory2.createFontId()).toEqual("f2");
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
expect(idFactory2.getDocId()).toEqual("g_d0");
|
2017-01-09 00:51:30 +09:00
|
|
|
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
expect(idFactory1.createObjId()).toEqual("p0_3");
|
|
|
|
expect(idFactory1.createObjId()).toEqual("p0_4");
|
Re-factor the `idFactory` functionality, used in the `core/`-code, and move the `fontID` generation into it
Note how the `getFontID`-method in `src/core/fonts.js` is *completely* global, rather than properly tied to the current document. This means that if you repeatedly open and parse/render, and then close, even the *same* PDF document the `fontID`s will still be incremented continuously.
For comparison the `createObjId` method, on `idFactory`, will always create a *consistent* id, assuming of course that the document and its pages are parsed/rendered in the same order.
In order to address this inconsistency, it thus seems reasonable to add a new `createFontId` method on the `idFactory` and use that when obtaining `fontID`s. (When the current `getFontID` method was added the `idFactory` didn't actually exist yet, which explains why the code looks the way it does.)
*Please note:* Since the document id is (still) part of the `loadedName`, it's thus not possible for different documents to have identical font names.
2020-07-07 23:00:05 +09:00
|
|
|
expect(idFactory1.createFontId()).toEqual("f3");
|
|
|
|
expect(idFactory1.createFontId()).toEqual("f4");
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
expect(idFactory1.getDocId()).toEqual("g_d0");
|
2017-01-09 00:51:30 +09:00
|
|
|
});
|
|
|
|
});
|
2020-08-23 21:04:49 +09:00
|
|
|
|
|
|
|
describe("PDFDocument", function () {
|
|
|
|
const stream = new StringStream("Dummy_PDF_data");
|
|
|
|
|
2020-10-15 20:20:27 +09:00
|
|
|
function getDocument(acroForm, xref = new XRefMock()) {
|
2020-10-17 22:15:17 +09:00
|
|
|
const catalog = { acroForm };
|
|
|
|
const pdfManager = {
|
|
|
|
get docId() {
|
|
|
|
return "d0";
|
|
|
|
},
|
A couple of small scripting/XFA-related tweaks in the worker-code
- Use `PDFManager.ensureDoc`, rather than `PDFManager.ensure`, in a couple of spots in the code. If there exists a short-hand format, we should obviously use it whenever possible.
- Fix a unit-test helper, to account for the previous changes. (Also, converts a function to be `async` instead.)
- Add one more exists-check in `PDFDocument.loadXfaFonts`, which I missed to suggest in PR 13146, to prevent any possible errors if the method is ever called in a situation where it shouldn't be.
Also, print a warning if the actual font-loading fails since that could help future debugging. (Finally, reduce overall indentation in the loop.)
- Slightly unrelated, but make a small tweak of a comment in `src/core/fonts.js` to reduce possible confusion.
2021-04-17 17:13:42 +09:00
|
|
|
ensureDoc(prop, args) {
|
|
|
|
return pdfManager.ensure(pdfDocument, prop, args);
|
|
|
|
},
|
2020-10-17 22:15:17 +09:00
|
|
|
ensureCatalog(prop, args) {
|
|
|
|
return pdfManager.ensure(catalog, prop, args);
|
|
|
|
},
|
A couple of small scripting/XFA-related tweaks in the worker-code
- Use `PDFManager.ensureDoc`, rather than `PDFManager.ensure`, in a couple of spots in the code. If there exists a short-hand format, we should obviously use it whenever possible.
- Fix a unit-test helper, to account for the previous changes. (Also, converts a function to be `async` instead.)
- Add one more exists-check in `PDFDocument.loadXfaFonts`, which I missed to suggest in PR 13146, to prevent any possible errors if the method is ever called in a situation where it shouldn't be.
Also, print a warning if the actual font-loading fails since that could help future debugging. (Finally, reduce overall indentation in the loop.)
- Slightly unrelated, but make a small tweak of a comment in `src/core/fonts.js` to reduce possible confusion.
2021-04-17 17:13:42 +09:00
|
|
|
async ensure(obj, prop, args) {
|
|
|
|
const value = obj[prop];
|
|
|
|
if (typeof value === "function") {
|
|
|
|
return value.apply(obj, args);
|
|
|
|
}
|
|
|
|
return value;
|
2020-10-17 22:15:17 +09:00
|
|
|
},
|
2022-10-19 00:07:47 +09:00
|
|
|
get evaluatorOptions() {
|
|
|
|
return { isOffscreenCanvasSupported: false };
|
|
|
|
},
|
2020-10-17 22:15:17 +09:00
|
|
|
};
|
2020-08-23 21:04:49 +09:00
|
|
|
const pdfDocument = new PDFDocument(pdfManager, stream);
|
2020-10-15 20:20:27 +09:00
|
|
|
pdfDocument.xref = xref;
|
2020-10-17 22:15:17 +09:00
|
|
|
pdfDocument.catalog = catalog;
|
2020-08-23 21:04:49 +09:00
|
|
|
return pdfDocument;
|
|
|
|
}
|
|
|
|
|
|
|
|
it("should get form info when no form data is present", function () {
|
|
|
|
const pdfDocument = getDocument(null);
|
|
|
|
expect(pdfDocument.formInfo).toEqual({
|
|
|
|
hasAcroForm: false,
|
2021-04-10 23:53:17 +09:00
|
|
|
hasSignatures: false,
|
2020-08-23 21:04:49 +09:00
|
|
|
hasXfa: false,
|
Don't store complex data in `PDFDocument.formInfo`, and replace the `fields` object with a `hasFields` boolean instead
*This patch is based on a couple of smaller things that I noticed when working on PR 12479.*
- Don't store the /Fields on the `formInfo` getter, since that feels like overloading it with unintended (and too complex) data, and utilize a `hasFields` boolean instead.
This functionality was originally added in PR 12271, to help determine what kind of form data a PDF document contains, and I think that we should ensure that the return value of `formInfo` only consists of "simple" data.
With these changes the `fieldObjects` getter instead has to look-up the /Fields manually, however that shouldn't be a problem since the access is guarded by a `formInfo.hasFields` check which ensures that the data both exists and is valid. Furthermore, most documents doesn't even have any /AcroForm data anyway.
- Determine the `hasFields` property *first*, to ensure that it's always correct even if there's errors when checking e.g. the /XFA or /SigFlags entires, since the `fieldObjects` getter depends on it.
- Simplify a loop in `fieldObjects`, since the object being accessed is a `Map` and those have built-in iteration support.
- Use a higher logging level for errors in the `formInfo` getter, and include the actual error message, since that'd have helped with fixing PR 12479 a lot quicker.
- Update the JSDoc comment in `src/display/api.js` to list the return values correctly, and also slightly extend/improve the description.
2020-10-16 19:20:44 +09:00
|
|
|
hasFields: false,
|
2020-08-23 21:04:49 +09:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should get form info when XFA is present", function () {
|
|
|
|
const acroForm = new Dict();
|
|
|
|
|
|
|
|
// The `XFA` entry can only be a non-empty array or stream.
|
|
|
|
acroForm.set("XFA", []);
|
|
|
|
let pdfDocument = getDocument(acroForm);
|
|
|
|
expect(pdfDocument.formInfo).toEqual({
|
|
|
|
hasAcroForm: false,
|
2021-04-10 23:53:17 +09:00
|
|
|
hasSignatures: false,
|
2020-08-23 21:04:49 +09:00
|
|
|
hasXfa: false,
|
Don't store complex data in `PDFDocument.formInfo`, and replace the `fields` object with a `hasFields` boolean instead
*This patch is based on a couple of smaller things that I noticed when working on PR 12479.*
- Don't store the /Fields on the `formInfo` getter, since that feels like overloading it with unintended (and too complex) data, and utilize a `hasFields` boolean instead.
This functionality was originally added in PR 12271, to help determine what kind of form data a PDF document contains, and I think that we should ensure that the return value of `formInfo` only consists of "simple" data.
With these changes the `fieldObjects` getter instead has to look-up the /Fields manually, however that shouldn't be a problem since the access is guarded by a `formInfo.hasFields` check which ensures that the data both exists and is valid. Furthermore, most documents doesn't even have any /AcroForm data anyway.
- Determine the `hasFields` property *first*, to ensure that it's always correct even if there's errors when checking e.g. the /XFA or /SigFlags entires, since the `fieldObjects` getter depends on it.
- Simplify a loop in `fieldObjects`, since the object being accessed is a `Map` and those have built-in iteration support.
- Use a higher logging level for errors in the `formInfo` getter, and include the actual error message, since that'd have helped with fixing PR 12479 a lot quicker.
- Update the JSDoc comment in `src/display/api.js` to list the return values correctly, and also slightly extend/improve the description.
2020-10-16 19:20:44 +09:00
|
|
|
hasFields: false,
|
2020-08-23 21:04:49 +09:00
|
|
|
});
|
|
|
|
|
|
|
|
acroForm.set("XFA", ["foo", "bar"]);
|
|
|
|
pdfDocument = getDocument(acroForm);
|
|
|
|
expect(pdfDocument.formInfo).toEqual({
|
|
|
|
hasAcroForm: false,
|
2021-04-10 23:53:17 +09:00
|
|
|
hasSignatures: false,
|
2020-08-23 21:04:49 +09:00
|
|
|
hasXfa: true,
|
Don't store complex data in `PDFDocument.formInfo`, and replace the `fields` object with a `hasFields` boolean instead
*This patch is based on a couple of smaller things that I noticed when working on PR 12479.*
- Don't store the /Fields on the `formInfo` getter, since that feels like overloading it with unintended (and too complex) data, and utilize a `hasFields` boolean instead.
This functionality was originally added in PR 12271, to help determine what kind of form data a PDF document contains, and I think that we should ensure that the return value of `formInfo` only consists of "simple" data.
With these changes the `fieldObjects` getter instead has to look-up the /Fields manually, however that shouldn't be a problem since the access is guarded by a `formInfo.hasFields` check which ensures that the data both exists and is valid. Furthermore, most documents doesn't even have any /AcroForm data anyway.
- Determine the `hasFields` property *first*, to ensure that it's always correct even if there's errors when checking e.g. the /XFA or /SigFlags entires, since the `fieldObjects` getter depends on it.
- Simplify a loop in `fieldObjects`, since the object being accessed is a `Map` and those have built-in iteration support.
- Use a higher logging level for errors in the `formInfo` getter, and include the actual error message, since that'd have helped with fixing PR 12479 a lot quicker.
- Update the JSDoc comment in `src/display/api.js` to list the return values correctly, and also slightly extend/improve the description.
2020-10-16 19:20:44 +09:00
|
|
|
hasFields: false,
|
2020-08-23 21:04:49 +09:00
|
|
|
});
|
|
|
|
|
|
|
|
acroForm.set("XFA", new StringStream(""));
|
|
|
|
pdfDocument = getDocument(acroForm);
|
|
|
|
expect(pdfDocument.formInfo).toEqual({
|
|
|
|
hasAcroForm: false,
|
2021-04-10 23:53:17 +09:00
|
|
|
hasSignatures: false,
|
2020-08-23 21:04:49 +09:00
|
|
|
hasXfa: false,
|
Don't store complex data in `PDFDocument.formInfo`, and replace the `fields` object with a `hasFields` boolean instead
*This patch is based on a couple of smaller things that I noticed when working on PR 12479.*
- Don't store the /Fields on the `formInfo` getter, since that feels like overloading it with unintended (and too complex) data, and utilize a `hasFields` boolean instead.
This functionality was originally added in PR 12271, to help determine what kind of form data a PDF document contains, and I think that we should ensure that the return value of `formInfo` only consists of "simple" data.
With these changes the `fieldObjects` getter instead has to look-up the /Fields manually, however that shouldn't be a problem since the access is guarded by a `formInfo.hasFields` check which ensures that the data both exists and is valid. Furthermore, most documents doesn't even have any /AcroForm data anyway.
- Determine the `hasFields` property *first*, to ensure that it's always correct even if there's errors when checking e.g. the /XFA or /SigFlags entires, since the `fieldObjects` getter depends on it.
- Simplify a loop in `fieldObjects`, since the object being accessed is a `Map` and those have built-in iteration support.
- Use a higher logging level for errors in the `formInfo` getter, and include the actual error message, since that'd have helped with fixing PR 12479 a lot quicker.
- Update the JSDoc comment in `src/display/api.js` to list the return values correctly, and also slightly extend/improve the description.
2020-10-16 19:20:44 +09:00
|
|
|
hasFields: false,
|
2020-08-23 21:04:49 +09:00
|
|
|
});
|
|
|
|
|
|
|
|
acroForm.set("XFA", new StringStream("non-empty"));
|
|
|
|
pdfDocument = getDocument(acroForm);
|
|
|
|
expect(pdfDocument.formInfo).toEqual({
|
|
|
|
hasAcroForm: false,
|
2021-04-10 23:53:17 +09:00
|
|
|
hasSignatures: false,
|
2020-08-23 21:04:49 +09:00
|
|
|
hasXfa: true,
|
Don't store complex data in `PDFDocument.formInfo`, and replace the `fields` object with a `hasFields` boolean instead
*This patch is based on a couple of smaller things that I noticed when working on PR 12479.*
- Don't store the /Fields on the `formInfo` getter, since that feels like overloading it with unintended (and too complex) data, and utilize a `hasFields` boolean instead.
This functionality was originally added in PR 12271, to help determine what kind of form data a PDF document contains, and I think that we should ensure that the return value of `formInfo` only consists of "simple" data.
With these changes the `fieldObjects` getter instead has to look-up the /Fields manually, however that shouldn't be a problem since the access is guarded by a `formInfo.hasFields` check which ensures that the data both exists and is valid. Furthermore, most documents doesn't even have any /AcroForm data anyway.
- Determine the `hasFields` property *first*, to ensure that it's always correct even if there's errors when checking e.g. the /XFA or /SigFlags entires, since the `fieldObjects` getter depends on it.
- Simplify a loop in `fieldObjects`, since the object being accessed is a `Map` and those have built-in iteration support.
- Use a higher logging level for errors in the `formInfo` getter, and include the actual error message, since that'd have helped with fixing PR 12479 a lot quicker.
- Update the JSDoc comment in `src/display/api.js` to list the return values correctly, and also slightly extend/improve the description.
2020-10-16 19:20:44 +09:00
|
|
|
hasFields: false,
|
2020-08-23 21:04:49 +09:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should get form info when AcroForm is present", function () {
|
|
|
|
const acroForm = new Dict();
|
|
|
|
|
|
|
|
// The `Fields` entry can only be a non-empty array.
|
|
|
|
acroForm.set("Fields", []);
|
|
|
|
let pdfDocument = getDocument(acroForm);
|
|
|
|
expect(pdfDocument.formInfo).toEqual({
|
|
|
|
hasAcroForm: false,
|
2021-04-10 23:53:17 +09:00
|
|
|
hasSignatures: false,
|
2020-08-23 21:04:49 +09:00
|
|
|
hasXfa: false,
|
Don't store complex data in `PDFDocument.formInfo`, and replace the `fields` object with a `hasFields` boolean instead
*This patch is based on a couple of smaller things that I noticed when working on PR 12479.*
- Don't store the /Fields on the `formInfo` getter, since that feels like overloading it with unintended (and too complex) data, and utilize a `hasFields` boolean instead.
This functionality was originally added in PR 12271, to help determine what kind of form data a PDF document contains, and I think that we should ensure that the return value of `formInfo` only consists of "simple" data.
With these changes the `fieldObjects` getter instead has to look-up the /Fields manually, however that shouldn't be a problem since the access is guarded by a `formInfo.hasFields` check which ensures that the data both exists and is valid. Furthermore, most documents doesn't even have any /AcroForm data anyway.
- Determine the `hasFields` property *first*, to ensure that it's always correct even if there's errors when checking e.g. the /XFA or /SigFlags entires, since the `fieldObjects` getter depends on it.
- Simplify a loop in `fieldObjects`, since the object being accessed is a `Map` and those have built-in iteration support.
- Use a higher logging level for errors in the `formInfo` getter, and include the actual error message, since that'd have helped with fixing PR 12479 a lot quicker.
- Update the JSDoc comment in `src/display/api.js` to list the return values correctly, and also slightly extend/improve the description.
2020-10-16 19:20:44 +09:00
|
|
|
hasFields: false,
|
2020-08-23 21:04:49 +09:00
|
|
|
});
|
|
|
|
|
|
|
|
acroForm.set("Fields", ["foo", "bar"]);
|
|
|
|
pdfDocument = getDocument(acroForm);
|
|
|
|
expect(pdfDocument.formInfo).toEqual({
|
|
|
|
hasAcroForm: true,
|
2021-04-10 23:53:17 +09:00
|
|
|
hasSignatures: false,
|
2020-08-23 21:04:49 +09:00
|
|
|
hasXfa: false,
|
Don't store complex data in `PDFDocument.formInfo`, and replace the `fields` object with a `hasFields` boolean instead
*This patch is based on a couple of smaller things that I noticed when working on PR 12479.*
- Don't store the /Fields on the `formInfo` getter, since that feels like overloading it with unintended (and too complex) data, and utilize a `hasFields` boolean instead.
This functionality was originally added in PR 12271, to help determine what kind of form data a PDF document contains, and I think that we should ensure that the return value of `formInfo` only consists of "simple" data.
With these changes the `fieldObjects` getter instead has to look-up the /Fields manually, however that shouldn't be a problem since the access is guarded by a `formInfo.hasFields` check which ensures that the data both exists and is valid. Furthermore, most documents doesn't even have any /AcroForm data anyway.
- Determine the `hasFields` property *first*, to ensure that it's always correct even if there's errors when checking e.g. the /XFA or /SigFlags entires, since the `fieldObjects` getter depends on it.
- Simplify a loop in `fieldObjects`, since the object being accessed is a `Map` and those have built-in iteration support.
- Use a higher logging level for errors in the `formInfo` getter, and include the actual error message, since that'd have helped with fixing PR 12479 a lot quicker.
- Update the JSDoc comment in `src/display/api.js` to list the return values correctly, and also slightly extend/improve the description.
2020-10-16 19:20:44 +09:00
|
|
|
hasFields: true,
|
2020-08-23 21:04:49 +09:00
|
|
|
});
|
|
|
|
|
|
|
|
// If the first bit of the `SigFlags` entry is set and the `Fields` array
|
|
|
|
// only contains document signatures, then there is no AcroForm data.
|
|
|
|
acroForm.set("Fields", ["foo", "bar"]);
|
|
|
|
acroForm.set("SigFlags", 2);
|
|
|
|
pdfDocument = getDocument(acroForm);
|
|
|
|
expect(pdfDocument.formInfo).toEqual({
|
|
|
|
hasAcroForm: true,
|
2021-04-10 23:53:17 +09:00
|
|
|
hasSignatures: false,
|
2020-08-23 21:04:49 +09:00
|
|
|
hasXfa: false,
|
Don't store complex data in `PDFDocument.formInfo`, and replace the `fields` object with a `hasFields` boolean instead
*This patch is based on a couple of smaller things that I noticed when working on PR 12479.*
- Don't store the /Fields on the `formInfo` getter, since that feels like overloading it with unintended (and too complex) data, and utilize a `hasFields` boolean instead.
This functionality was originally added in PR 12271, to help determine what kind of form data a PDF document contains, and I think that we should ensure that the return value of `formInfo` only consists of "simple" data.
With these changes the `fieldObjects` getter instead has to look-up the /Fields manually, however that shouldn't be a problem since the access is guarded by a `formInfo.hasFields` check which ensures that the data both exists and is valid. Furthermore, most documents doesn't even have any /AcroForm data anyway.
- Determine the `hasFields` property *first*, to ensure that it's always correct even if there's errors when checking e.g. the /XFA or /SigFlags entires, since the `fieldObjects` getter depends on it.
- Simplify a loop in `fieldObjects`, since the object being accessed is a `Map` and those have built-in iteration support.
- Use a higher logging level for errors in the `formInfo` getter, and include the actual error message, since that'd have helped with fixing PR 12479 a lot quicker.
- Update the JSDoc comment in `src/display/api.js` to list the return values correctly, and also slightly extend/improve the description.
2020-10-16 19:20:44 +09:00
|
|
|
hasFields: true,
|
2020-08-23 21:04:49 +09:00
|
|
|
});
|
|
|
|
|
|
|
|
const annotationDict = new Dict();
|
|
|
|
annotationDict.set("FT", Name.get("Sig"));
|
|
|
|
annotationDict.set("Rect", [0, 0, 0, 0]);
|
|
|
|
const annotationRef = Ref.get(11, 0);
|
|
|
|
|
|
|
|
const kidsDict = new Dict();
|
|
|
|
kidsDict.set("Kids", [annotationRef]);
|
|
|
|
const kidsRef = Ref.get(10, 0);
|
|
|
|
|
2020-10-15 20:20:27 +09:00
|
|
|
const xref = new XRefMock([
|
2020-08-23 21:04:49 +09:00
|
|
|
{ ref: annotationRef, data: annotationDict },
|
|
|
|
{ ref: kidsRef, data: kidsDict },
|
|
|
|
]);
|
|
|
|
|
|
|
|
acroForm.set("Fields", [kidsRef]);
|
|
|
|
acroForm.set("SigFlags", 3);
|
2020-10-15 20:20:27 +09:00
|
|
|
pdfDocument = getDocument(acroForm, xref);
|
2020-08-23 21:04:49 +09:00
|
|
|
expect(pdfDocument.formInfo).toEqual({
|
|
|
|
hasAcroForm: false,
|
2021-04-10 23:53:17 +09:00
|
|
|
hasSignatures: true,
|
2020-08-23 21:04:49 +09:00
|
|
|
hasXfa: false,
|
Don't store complex data in `PDFDocument.formInfo`, and replace the `fields` object with a `hasFields` boolean instead
*This patch is based on a couple of smaller things that I noticed when working on PR 12479.*
- Don't store the /Fields on the `formInfo` getter, since that feels like overloading it with unintended (and too complex) data, and utilize a `hasFields` boolean instead.
This functionality was originally added in PR 12271, to help determine what kind of form data a PDF document contains, and I think that we should ensure that the return value of `formInfo` only consists of "simple" data.
With these changes the `fieldObjects` getter instead has to look-up the /Fields manually, however that shouldn't be a problem since the access is guarded by a `formInfo.hasFields` check which ensures that the data both exists and is valid. Furthermore, most documents doesn't even have any /AcroForm data anyway.
- Determine the `hasFields` property *first*, to ensure that it's always correct even if there's errors when checking e.g. the /XFA or /SigFlags entires, since the `fieldObjects` getter depends on it.
- Simplify a loop in `fieldObjects`, since the object being accessed is a `Map` and those have built-in iteration support.
- Use a higher logging level for errors in the `formInfo` getter, and include the actual error message, since that'd have helped with fixing PR 12479 a lot quicker.
- Update the JSDoc comment in `src/display/api.js` to list the return values correctly, and also slightly extend/improve the description.
2020-10-16 19:20:44 +09:00
|
|
|
hasFields: true,
|
2020-08-23 21:04:49 +09:00
|
|
|
});
|
|
|
|
});
|
2020-10-17 00:15:58 +09:00
|
|
|
|
|
|
|
it("should get calculation order array or null", function () {
|
|
|
|
const acroForm = new Dict();
|
|
|
|
|
|
|
|
let pdfDocument = getDocument(acroForm);
|
|
|
|
expect(pdfDocument.calculationOrderIds).toEqual(null);
|
|
|
|
|
|
|
|
acroForm.set("CO", [Ref.get(1, 0), Ref.get(2, 0), Ref.get(3, 0)]);
|
|
|
|
pdfDocument = getDocument(acroForm);
|
|
|
|
expect(pdfDocument.calculationOrderIds).toEqual(["1R", "2R", "3R"]);
|
|
|
|
|
|
|
|
acroForm.set("CO", []);
|
|
|
|
pdfDocument = getDocument(acroForm);
|
|
|
|
expect(pdfDocument.calculationOrderIds).toEqual(null);
|
2020-12-11 00:02:11 +09:00
|
|
|
|
|
|
|
acroForm.set("CO", ["1", "2"]);
|
|
|
|
pdfDocument = getDocument(acroForm);
|
|
|
|
expect(pdfDocument.calculationOrderIds).toEqual(null);
|
|
|
|
|
|
|
|
acroForm.set("CO", ["1", Ref.get(1, 0), "2"]);
|
|
|
|
pdfDocument = getDocument(acroForm);
|
|
|
|
expect(pdfDocument.calculationOrderIds).toEqual(["1R"]);
|
2020-10-17 00:15:58 +09:00
|
|
|
});
|
2020-10-17 22:15:17 +09:00
|
|
|
|
|
|
|
it("should get field objects array or null", async function () {
|
|
|
|
const acroForm = new Dict();
|
|
|
|
|
|
|
|
let pdfDocument = getDocument(acroForm);
|
|
|
|
let fields = await pdfDocument.fieldObjects;
|
|
|
|
expect(fields).toEqual(null);
|
|
|
|
|
|
|
|
acroForm.set("Fields", []);
|
|
|
|
pdfDocument = getDocument(acroForm);
|
|
|
|
fields = await pdfDocument.fieldObjects;
|
|
|
|
expect(fields).toEqual(null);
|
|
|
|
|
|
|
|
const kid1Ref = Ref.get(314, 0);
|
|
|
|
const kid11Ref = Ref.get(159, 0);
|
|
|
|
const kid2Ref = Ref.get(265, 0);
|
2020-12-17 00:00:12 +09:00
|
|
|
const kid2BisRef = Ref.get(266, 0);
|
2020-10-17 22:15:17 +09:00
|
|
|
const parentRef = Ref.get(358, 0);
|
|
|
|
|
|
|
|
const allFields = Object.create(null);
|
|
|
|
for (const name of ["parent", "kid1", "kid2", "kid11"]) {
|
|
|
|
const buttonWidgetDict = new Dict();
|
|
|
|
buttonWidgetDict.set("Type", Name.get("Annot"));
|
|
|
|
buttonWidgetDict.set("Subtype", Name.get("Widget"));
|
|
|
|
buttonWidgetDict.set("FT", Name.get("Btn"));
|
|
|
|
buttonWidgetDict.set("T", name);
|
|
|
|
allFields[name] = buttonWidgetDict;
|
|
|
|
}
|
|
|
|
|
|
|
|
allFields.kid1.set("Kids", [kid11Ref]);
|
2020-12-17 00:00:12 +09:00
|
|
|
allFields.parent.set("Kids", [kid1Ref, kid2Ref, kid2BisRef]);
|
2020-10-17 22:15:17 +09:00
|
|
|
|
|
|
|
const xref = new XRefMock([
|
|
|
|
{ ref: parentRef, data: allFields.parent },
|
|
|
|
{ ref: kid1Ref, data: allFields.kid1 },
|
|
|
|
{ ref: kid11Ref, data: allFields.kid11 },
|
|
|
|
{ ref: kid2Ref, data: allFields.kid2 },
|
2020-12-17 00:00:12 +09:00
|
|
|
{ ref: kid2BisRef, data: allFields.kid2 },
|
2020-10-17 22:15:17 +09:00
|
|
|
]);
|
|
|
|
|
|
|
|
acroForm.set("Fields", [parentRef]);
|
|
|
|
pdfDocument = getDocument(acroForm, xref);
|
|
|
|
fields = await pdfDocument.fieldObjects;
|
|
|
|
|
|
|
|
for (const [name, objs] of Object.entries(fields)) {
|
|
|
|
fields[name] = objs.map(obj => obj.id);
|
|
|
|
}
|
|
|
|
|
|
|
|
expect(fields["parent.kid1"]).toEqual(["314R"]);
|
|
|
|
expect(fields["parent.kid1.kid11"]).toEqual(["159R"]);
|
2020-12-17 00:00:12 +09:00
|
|
|
expect(fields["parent.kid2"]).toEqual(["265R", "266R"]);
|
2020-10-17 22:15:17 +09:00
|
|
|
expect(fields.parent).toEqual(["358R"]);
|
|
|
|
});
|
2020-10-29 03:16:56 +09:00
|
|
|
|
|
|
|
it("should check if fields have any actions", async function () {
|
|
|
|
const acroForm = new Dict();
|
|
|
|
|
|
|
|
let pdfDocument = getDocument(acroForm);
|
|
|
|
let hasJSActions = await pdfDocument.hasJSActions;
|
|
|
|
expect(hasJSActions).toEqual(false);
|
|
|
|
|
|
|
|
acroForm.set("Fields", []);
|
|
|
|
pdfDocument = getDocument(acroForm);
|
|
|
|
hasJSActions = await pdfDocument.hasJSActions;
|
|
|
|
expect(hasJSActions).toEqual(false);
|
|
|
|
|
|
|
|
const kid1Ref = Ref.get(314, 0);
|
|
|
|
const kid11Ref = Ref.get(159, 0);
|
|
|
|
const kid2Ref = Ref.get(265, 0);
|
|
|
|
const parentRef = Ref.get(358, 0);
|
|
|
|
|
|
|
|
const allFields = Object.create(null);
|
|
|
|
for (const name of ["parent", "kid1", "kid2", "kid11"]) {
|
|
|
|
const buttonWidgetDict = new Dict();
|
|
|
|
buttonWidgetDict.set("Type", Name.get("Annot"));
|
|
|
|
buttonWidgetDict.set("Subtype", Name.get("Widget"));
|
|
|
|
buttonWidgetDict.set("FT", Name.get("Btn"));
|
|
|
|
buttonWidgetDict.set("T", name);
|
|
|
|
allFields[name] = buttonWidgetDict;
|
|
|
|
}
|
|
|
|
|
|
|
|
allFields.kid1.set("Kids", [kid11Ref]);
|
|
|
|
allFields.parent.set("Kids", [kid1Ref, kid2Ref]);
|
|
|
|
|
|
|
|
const xref = new XRefMock([
|
|
|
|
{ ref: parentRef, data: allFields.parent },
|
|
|
|
{ ref: kid1Ref, data: allFields.kid1 },
|
|
|
|
{ ref: kid11Ref, data: allFields.kid11 },
|
|
|
|
{ ref: kid2Ref, data: allFields.kid2 },
|
|
|
|
]);
|
|
|
|
|
|
|
|
acroForm.set("Fields", [parentRef]);
|
|
|
|
pdfDocument = getDocument(acroForm, xref);
|
|
|
|
hasJSActions = await pdfDocument.hasJSActions;
|
|
|
|
expect(hasJSActions).toEqual(false);
|
|
|
|
|
|
|
|
const JS = Name.get("JavaScript");
|
|
|
|
const additionalActionsDict = new Dict();
|
|
|
|
const eDict = new Dict();
|
|
|
|
eDict.set("JS", "hello()");
|
|
|
|
eDict.set("S", JS);
|
|
|
|
additionalActionsDict.set("E", eDict);
|
|
|
|
allFields.kid2.set("AA", additionalActionsDict);
|
|
|
|
|
|
|
|
pdfDocument = getDocument(acroForm, xref);
|
|
|
|
hasJSActions = await pdfDocument.hasJSActions;
|
|
|
|
expect(hasJSActions).toEqual(true);
|
|
|
|
});
|
2020-08-23 21:04:49 +09:00
|
|
|
});
|
2017-01-09 00:51:30 +09:00
|
|
|
});
|