Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
* 'master' of https://github.com/mozilla/pdf.js:
  Avoid the `getJavaScript` API-call in `PDFViewerApplication._initializeAutoPrint` when "enableScripting" is set
  Add a default DA for textfield to avoid issues when printing or saving  * it aims to fix issue mozilla#12750
  Stop running `gulp components` as part of the unit-tests
  Switch from Travis CI to GitHub Actions
  Run `AnnotationStorage.resetModified` when destroying the `PDFDocumentLoadingTask`/`PDFDocumentProxy`
  Delay initialization of the `AnnotationStorage` callbacks slightly in the default viewer
  Move the functionality of the `webViewerDownloadOrSave` function into a new `PDFViewerApplication` method instead
  Remove the arbitrary timeout in the "must check that first text field has focus" integration-test (PR 12702 follow-up)
  Don't dispatch a "doc/Open" event in the sandbox when creating it failed
  Remove the `ENABLE_SCRIPTING` build-target, since it's not necessary
  Update the events, used with scripting, to use lower-case names and avoid using DOM events internally in the viewer
  Tweak the `LinkAnnotationElement._bindJSAction` and `WidgetAnnotationElement.{_setEventListener, _setEventListeners}` methods
  Tweak the new `mouseState` parameter, and its usage, in the viewer components and the `AnnotationLayer`
  JS - Collect and execute actions at doc and pages level  * the goal is to execute actions like Open or OpenAction  * can be tested with issue6106.pdf (auto-print)  * once mozilla#12701 is merged, we can add page actions
  Dispatch an event on sandbox creation  * the goal is to be able to know when the sandbox is ready for mochitest in m-c
  Ignore, rather than throwing on, Coding style component (COC) markers in JPEG 2000 images (issue 12752)
  JS -- Actions must be evaluated in global scope  * All the public properties of doc are injected into globalThis, in order to make them available through `this`  * Put event in the global scope too.
  Add a new "pagesdestroy" event, dispatched *before* the `BaseViewer` removes an existing document
  Add new "pageopen"/"pageclose" events for usage with JavaScript actions
  In order to simplify m-c code, move some in pdf.js  * move set/clear|Timeout/Interval and crackURL code in pdf.js  * remove the "backdoor" in the proxy (used to dispatch event) and so return the dispatch function in the initializer  * remove listeners if an error occured during sandbox initialization  * add support for alert and prompt in the sandbox  * add a function to eval in the global scope
  • Loading branch information
joelkuiper committed Dec 21, 2020
2 parents b6355f1 + 9c99df7 commit f6bba9d
Show file tree
Hide file tree
Showing 39 changed files with 1,407 additions and 664 deletions.
14 changes: 14 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js 14 LTS
uses: actions/setup-node@v1
with:
node-version: 14.x
- run: npm install -g gulp-cli
- run: npm install
- run: npm test
10 changes: 0 additions & 10 deletions .travis.yml

This file was deleted.

50 changes: 24 additions & 26 deletions external/quickjs/quickjs-eval.js

Large diffs are not rendered by default.

85 changes: 45 additions & 40 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ const DEFINES = Object.freeze({
PRODUCTION: true,
SKIP_BABEL: true,
TESTING: false,
ENABLE_SCRIPTING: false,
// The main build targets:
GENERIC: false,
MOZCENTRAL: false,
Expand Down Expand Up @@ -374,7 +373,28 @@ function createScriptingBundle(defines, extraOptions = undefined) {
.src("./src/pdf.scripting.js")
.pipe(webpack2Stream(scriptingFileConfig))
.pipe(replaceWebpackRequire())
.pipe(replaceJSRootName(scriptingAMDName, "pdfjsScripting"));
.pipe(
replace(
'root["' + scriptingAMDName + '"] = factory()',
"root.pdfjsScripting = factory()"
)
);
}

function createSandboxExternal(defines) {
const preprocessor2 = require("./external/builder/preprocessor2.js");
const licenseHeader = fs.readFileSync("./src/license_header.js").toString();

const ctx = {
saveComments: false,
defines,
};
return gulp.src("./src/pdf.sandbox.external.js").pipe(
transform("utf8", content => {
content = preprocessor2.preprocessPDFJSCode(ctx, content);
return `${licenseHeader}\n${content}`;
})
);
}

function createTemporaryScriptingBundle(defines, extraOptions = undefined) {
Expand Down Expand Up @@ -661,7 +681,6 @@ gulp.task("default_preferences-pre", function () {
LIB: true,
BUNDLE_VERSION: 0, // Dummy version
BUNDLE_BUILD: 0, // Dummy build
ENABLE_SCRIPTING: process.env.ENABLE_SCRIPTING === "true",
}),
map: {
"pdfjs-lib": "../pdf",
Expand Down Expand Up @@ -1203,6 +1222,9 @@ gulp.task(
createScriptingBundle(defines).pipe(
gulp.dest(MOZCENTRAL_CONTENT_DIR + "build")
),
createSandboxExternal(defines).pipe(
gulp.dest(MOZCENTRAL_CONTENT_DIR + "build")
),
createWorkerBundle(defines).pipe(
gulp.dest(MOZCENTRAL_CONTENT_DIR + "build")
),
Expand Down Expand Up @@ -1527,46 +1549,29 @@ gulp.task("testing-pre", function (done) {
done();
});

gulp.task("enable-scripting", function (done) {
process.env.ENABLE_SCRIPTING = "true";
done();
});

gulp.task(
"test",
gulp.series(
"enable-scripting",
"testing-pre",
"generic",
"components",
function () {
return streamqueue(
{ objectMode: true },
createTestSource("unit"),
createTestSource("browser"),
createTestSource("integration")
);
}
)
gulp.series("testing-pre", "generic", "components", function () {
return streamqueue(
{ objectMode: true },
createTestSource("unit"),
createTestSource("browser"),
createTestSource("integration")
);
})
);

gulp.task(
"bottest",
gulp.series(
"enable-scripting",
"testing-pre",
"generic",
"components",
function () {
return streamqueue(
{ objectMode: true },
createTestSource("unit", true),
createTestSource("font", true),
createTestSource("browser (no reftest)", true),
createTestSource("integration")
);
}
)
gulp.series("testing-pre", "generic", "components", function () {
return streamqueue(
{ objectMode: true },
createTestSource("unit", true),
createTestSource("font", true),
createTestSource("browser (no reftest)", true),
createTestSource("integration")
);
})
);

gulp.task(
Expand All @@ -1578,14 +1583,14 @@ gulp.task(

gulp.task(
"unittest",
gulp.series("testing-pre", "generic", "components", function () {
gulp.series("testing-pre", "generic", function () {
return createTestSource("unit");
})
);

gulp.task(
"integrationtest",
gulp.series("enable-scripting", "testing-pre", "generic", function () {
gulp.series("testing-pre", "generic", function () {
return createTestSource("integration");
})
);
Expand Down Expand Up @@ -1791,7 +1796,7 @@ gulp.task(
gulp.task("watch-dev-sandbox", function () {
gulp.watch(
[
"src/pdf.{sandbox,scripting}.js",
"src/pdf.{sandbox,sandbox.external,scripting}.js",
"src/scripting_api/*.js",
"src/shared/scripting_utils.js",
"external/quickjs/*.js",
Expand Down
102 changes: 16 additions & 86 deletions src/core/annotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,9 @@ import {
AnnotationReplyType,
AnnotationType,
assert,
bytesToString,
escapeString,
getModificationDate,
isString,
objectSize,
OPS,
shadow,
stringToPDFString,
Expand All @@ -34,17 +32,9 @@ import {
warn,
} from "../shared/util.js";
import { Catalog, FileSpec, ObjectLoader } from "./obj.js";
import {
Dict,
isDict,
isName,
isRef,
isStream,
Name,
RefSet,
} from "./primitives.js";
import { collectActions, getInheritableProperty } from "./core_utils.js";
import { Dict, isDict, isName, isRef, isStream, Name } from "./primitives.js";
import { ColorSpace } from "./colorspace.js";
import { getInheritableProperty } from "./core_utils.js";
import { OperatorList } from "./operator_list.js";
import { StringStream } from "./stream.js";
import { writeDict } from "./writer.js";
Expand Down Expand Up @@ -977,7 +967,7 @@ class WidgetAnnotation extends Annotation {

data.annotationType = AnnotationType.WIDGET;
data.fieldName = this._constructFieldName(dict);
data.actions = this._collectActions(params.xref, dict);
data.actions = collectActions(params.xref, dict, AnnotationActionEventType);

const fieldValue = getInheritableProperty({
dict,
Expand All @@ -994,10 +984,13 @@ class WidgetAnnotation extends Annotation {
data.defaultFieldValue = this._decodeFormValue(defaultFieldValue);

data.alternativeText = stringToPDFString(dict.get("TU") || "");
data.defaultAppearance =
const defaultAppearance =
getInheritableProperty({ dict, key: "DA" }) ||
params.acroForm.get("DA") ||
"";
data.defaultAppearance = isString(defaultAppearance)
? defaultAppearance
: "";
const fieldType = getInheritableProperty({ dict, key: "FT" });
data.fieldType = isName(fieldType) ? fieldType.name : null;

Expand Down Expand Up @@ -1282,6 +1275,15 @@ class WidgetAnnotation extends Annotation {
const totalHeight = this.data.rect[3] - this.data.rect[1];
const totalWidth = this.data.rect[2] - this.data.rect[0];

if (!this.data.defaultAppearance) {
// The DA is required and must be a string.
// If there is no font named Helvetica in the resource dictionary,
// the evaluator will fall back to a default font.
// Doing so prevents exceptions and allows saving/printing
// the file as expected.
this.data.defaultAppearance = "/Helvetica 0 Tf 0 g";
}

const fontInfo = await this._getFontData(evaluator, task);
const [font, fontName] = fontInfo;
const fontSize = this._computeFontSize(...fontInfo, totalHeight);
Expand Down Expand Up @@ -1459,78 +1461,6 @@ class WidgetAnnotation extends Annotation {
return localResources || Dict.empty;
}

_collectJS(entry, xref, list, parents) {
if (!entry) {
return;
}

let parent = null;
if (isRef(entry)) {
if (parents.has(entry)) {
// If we've already found entry then we've a cycle.
return;
}
parent = entry;
parents.put(parent);
entry = xref.fetch(entry);
}
if (Array.isArray(entry)) {
for (const element of entry) {
this._collectJS(element, xref, list, parents);
}
} else if (entry instanceof Dict) {
if (isName(entry.get("S"), "JavaScript") && entry.has("JS")) {
const js = entry.get("JS");
let code;
if (isStream(js)) {
code = bytesToString(js.getBytes());
} else {
code = js;
}
code = stringToPDFString(code);
if (code) {
list.push(code);
}
}
this._collectJS(entry.getRaw("Next"), xref, list, parents);
}

if (parent) {
parents.remove(parent);
}
}

_collectActions(xref, dict) {
const actions = Object.create(null);
if (dict.has("AA")) {
const additionalActions = dict.get("AA");
for (const key of additionalActions.getKeys()) {
const action = AnnotationActionEventType[key];
if (!action) {
continue;
}
const actionDict = additionalActions.getRaw(key);
const parents = new RefSet();
const list = [];
this._collectJS(actionDict, xref, list, parents);
if (list.length > 0) {
actions[action] = list;
}
}
}
// Collect the Action if any (we may have one on pushbutton).
if (dict.has("A")) {
const actionDict = dict.get("A");
const parents = new RefSet();
const list = [];
this._collectJS(actionDict, xref, list, parents);
if (list.length > 0) {
actions.Action = list;
}
}
return objectSize(actions) > 0 ? actions : null;
}

getFieldObject() {
if (this.data.fieldType === "Sig") {
return {
Expand Down
Loading

0 comments on commit f6bba9d

Please sign in to comment.