Merge pull request #12695 from Snuffleupagus/sandbox-build
Various clean-up and improvements related to `pdf.sandbox.js` building, and the related default-viewer functionality
This commit is contained in:
commit
3df72c3fac
396
gulpfile.js
396
gulpfile.js
@ -33,7 +33,6 @@ var stream = require("stream");
|
|||||||
var exec = require("child_process").exec;
|
var exec = require("child_process").exec;
|
||||||
var spawn = require("child_process").spawn;
|
var spawn = require("child_process").spawn;
|
||||||
var spawnSync = require("child_process").spawnSync;
|
var spawnSync = require("child_process").spawnSync;
|
||||||
var stripComments = require("gulp-strip-comments");
|
|
||||||
var streamqueue = require("streamqueue");
|
var streamqueue = require("streamqueue");
|
||||||
var merge = require("merge-stream");
|
var merge = require("merge-stream");
|
||||||
var zip = require("gulp-zip");
|
var zip = require("gulp-zip");
|
||||||
@ -65,6 +64,7 @@ var SRC_DIR = "src/";
|
|||||||
var LIB_DIR = BUILD_DIR + "lib/";
|
var LIB_DIR = BUILD_DIR + "lib/";
|
||||||
var DIST_DIR = BUILD_DIR + "dist/";
|
var DIST_DIR = BUILD_DIR + "dist/";
|
||||||
var TYPES_DIR = BUILD_DIR + "types/";
|
var TYPES_DIR = BUILD_DIR + "types/";
|
||||||
|
const TMP_DIR = BUILD_DIR + "tmp/";
|
||||||
var TYPESTEST_DIR = BUILD_DIR + "typestest/";
|
var TYPESTEST_DIR = BUILD_DIR + "typestest/";
|
||||||
var COMMON_WEB_FILES = ["web/images/*.{png,svg,gif,cur}", "web/debugger.js"];
|
var COMMON_WEB_FILES = ["web/images/*.{png,svg,gif,cur}", "web/debugger.js"];
|
||||||
var MOZCENTRAL_DIFF_FILE = "mozcentral.diff";
|
var MOZCENTRAL_DIFF_FILE = "mozcentral.diff";
|
||||||
@ -106,7 +106,6 @@ const DEFINES = Object.freeze({
|
|||||||
COMPONENTS: false,
|
COMPONENTS: false,
|
||||||
LIB: false,
|
LIB: false,
|
||||||
IMAGE_DECODERS: false,
|
IMAGE_DECODERS: false,
|
||||||
NO_SOURCE_MAP: false,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function transform(charEncoding, transformFunction) {
|
function transform(charEncoding, transformFunction) {
|
||||||
@ -171,8 +170,18 @@ function createStringSource(filename, content) {
|
|||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createWebpackConfig(defines, output) {
|
function createWebpackConfig(
|
||||||
var versionInfo = getVersionJSON();
|
defines,
|
||||||
|
output,
|
||||||
|
{
|
||||||
|
disableVersionInfo = false,
|
||||||
|
disableSourceMaps = false,
|
||||||
|
disableLicenseHeader = false,
|
||||||
|
} = {}
|
||||||
|
) {
|
||||||
|
const versionInfo = !disableVersionInfo
|
||||||
|
? getVersionJSON()
|
||||||
|
: { version: 0, commit: 0 };
|
||||||
var bundleDefines = builder.merge(defines, {
|
var bundleDefines = builder.merge(defines, {
|
||||||
BUNDLE_VERSION: versionInfo.version,
|
BUNDLE_VERSION: versionInfo.version,
|
||||||
BUNDLE_BUILD: versionInfo.commit,
|
BUNDLE_BUILD: versionInfo.commit,
|
||||||
@ -184,8 +193,9 @@ function createWebpackConfig(defines, output) {
|
|||||||
var enableSourceMaps =
|
var enableSourceMaps =
|
||||||
!bundleDefines.MOZCENTRAL &&
|
!bundleDefines.MOZCENTRAL &&
|
||||||
!bundleDefines.CHROME &&
|
!bundleDefines.CHROME &&
|
||||||
|
!bundleDefines.LIB &&
|
||||||
!bundleDefines.TESTING &&
|
!bundleDefines.TESTING &&
|
||||||
!bundleDefines.NO_SOURCE_MAP;
|
!disableSourceMaps;
|
||||||
var skipBabel = bundleDefines.SKIP_BABEL;
|
var skipBabel = bundleDefines.SKIP_BABEL;
|
||||||
|
|
||||||
// `core-js` (see https://github.com/zloirock/core-js/issues/514),
|
// `core-js` (see https://github.com/zloirock/core-js/issues/514),
|
||||||
@ -201,6 +211,13 @@ function createWebpackConfig(defines, output) {
|
|||||||
}
|
}
|
||||||
const babelExcludeRegExp = new RegExp(`(${babelExcludes.join("|")})`);
|
const babelExcludeRegExp = new RegExp(`(${babelExcludes.join("|")})`);
|
||||||
|
|
||||||
|
const plugins = [];
|
||||||
|
if (!disableLicenseHeader) {
|
||||||
|
plugins.push(
|
||||||
|
new webpack2.BannerPlugin({ banner: licenseHeaderLibre, raw: true })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Required to expose e.g., the `window` object.
|
// Required to expose e.g., the `window` object.
|
||||||
output.globalObject = "this";
|
output.globalObject = "this";
|
||||||
|
|
||||||
@ -210,9 +227,7 @@ function createWebpackConfig(defines, output) {
|
|||||||
performance: {
|
performance: {
|
||||||
hints: false, // Disable messages about larger file sizes.
|
hints: false, // Disable messages about larger file sizes.
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins,
|
||||||
new webpack2.BannerPlugin({ banner: licenseHeaderLibre, raw: true }),
|
|
||||||
],
|
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
pdfjs: path.join(__dirname, "src"),
|
pdfjs: path.join(__dirname, "src"),
|
||||||
@ -329,16 +344,20 @@ function createMainBundle(defines) {
|
|||||||
.pipe(replaceJSRootName(mainAMDName, "pdfjsLib"));
|
.pipe(replaceJSRootName(mainAMDName, "pdfjsLib"));
|
||||||
}
|
}
|
||||||
|
|
||||||
function createScriptingBundle(defines) {
|
function createScriptingBundle(defines, extraOptions = undefined) {
|
||||||
var scriptingAMDName = "pdfjs-dist/build/pdf.scripting";
|
var scriptingAMDName = "pdfjs-dist/build/pdf.scripting";
|
||||||
var scriptingOutputName = "pdf.scripting.js";
|
var scriptingOutputName = "pdf.scripting.js";
|
||||||
|
|
||||||
var scriptingFileConfig = createWebpackConfig(defines, {
|
var scriptingFileConfig = createWebpackConfig(
|
||||||
filename: scriptingOutputName,
|
defines,
|
||||||
library: scriptingAMDName,
|
{
|
||||||
libraryTarget: "umd",
|
filename: scriptingOutputName,
|
||||||
umdNamedDefine: true,
|
library: scriptingAMDName,
|
||||||
});
|
libraryTarget: "umd",
|
||||||
|
umdNamedDefine: true,
|
||||||
|
},
|
||||||
|
extraOptions
|
||||||
|
);
|
||||||
return gulp
|
return gulp
|
||||||
.src("./src/pdf.scripting.js")
|
.src("./src/pdf.scripting.js")
|
||||||
.pipe(webpack2Stream(scriptingFileConfig))
|
.pipe(webpack2Stream(scriptingFileConfig))
|
||||||
@ -346,51 +365,41 @@ function createScriptingBundle(defines) {
|
|||||||
.pipe(replaceJSRootName(scriptingAMDName, "pdfjsScripting"));
|
.pipe(replaceJSRootName(scriptingAMDName, "pdfjsScripting"));
|
||||||
}
|
}
|
||||||
|
|
||||||
function createSandboxBundle(defines, code) {
|
function createTemporaryScriptingBundle(defines, extraOptions = undefined) {
|
||||||
var sandboxAMDName = "pdfjs-dist/build/pdf.sandbox";
|
return createScriptingBundle(defines, {
|
||||||
var sandboxOutputName = "pdf.sandbox.js";
|
disableVersionInfo: !!(extraOptions && extraOptions.disableVersionInfo),
|
||||||
var sandboxFileConfig = createWebpackConfig(defines, {
|
disableSourceMaps: true,
|
||||||
filename: sandboxOutputName,
|
disableLicenseHeader: true,
|
||||||
library: sandboxAMDName,
|
}).pipe(gulp.dest(TMP_DIR));
|
||||||
libraryTarget: "umd",
|
|
||||||
umdNamedDefine: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
// The code is the one from the bundle pdf.scripting.js
|
|
||||||
// so in order to have it in a string (which will be eval-ed
|
|
||||||
// in the sandbox) we must escape some chars.
|
|
||||||
// This way we've all the code (initialization+sandbox) in
|
|
||||||
// the same bundle.
|
|
||||||
code = code.replace(/["\\\n\t]/g, match => {
|
|
||||||
if (match === "\n") {
|
|
||||||
return "\\n";
|
|
||||||
}
|
|
||||||
if (match === "\t") {
|
|
||||||
return "\\t";
|
|
||||||
}
|
|
||||||
return `\\${match}`;
|
|
||||||
});
|
|
||||||
return (
|
|
||||||
gulp
|
|
||||||
.src("./src/scripting_api/quickjs-sandbox.js")
|
|
||||||
.pipe(webpack2Stream(sandboxFileConfig))
|
|
||||||
.pipe(replaceWebpackRequire())
|
|
||||||
.pipe(replaceJSRootName(sandboxAMDName, "pdfjsSandbox"))
|
|
||||||
// put the code in a string to be eval-ed in the sandbox
|
|
||||||
.pipe(replace("/* INITIALIZATION_CODE */", `${code}`))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildSandbox(defines, dir) {
|
function createSandboxBundle(defines, extraOptions = undefined) {
|
||||||
const scriptingDefines = builder.merge(defines, { NO_SOURCE_MAP: true });
|
var sandboxAMDName = "pdfjs-dist/build/pdf.sandbox";
|
||||||
return createScriptingBundle(scriptingDefines)
|
var sandboxOutputName = "pdf.sandbox.js";
|
||||||
.pipe(stripComments())
|
|
||||||
.pipe(gulp.dest(dir + "build"))
|
const scriptingPath = TMP_DIR + "pdf.scripting.js";
|
||||||
.on("data", file => {
|
// Insert the source as a string to be `eval`-ed in the sandbox.
|
||||||
const content = file.contents.toString();
|
const sandboxDefines = builder.merge(defines, {
|
||||||
createSandboxBundle(defines, content).pipe(gulp.dest(dir + "build"));
|
PDF_SCRIPTING_JS_SOURCE: fs.readFileSync(scriptingPath).toString(),
|
||||||
fs.unlinkSync(dir + "build/pdf.scripting.js");
|
});
|
||||||
});
|
fs.unlinkSync(scriptingPath);
|
||||||
|
|
||||||
|
var sandboxFileConfig = createWebpackConfig(
|
||||||
|
sandboxDefines,
|
||||||
|
{
|
||||||
|
filename: sandboxOutputName,
|
||||||
|
library: sandboxAMDName,
|
||||||
|
libraryTarget: "umd",
|
||||||
|
umdNamedDefine: true,
|
||||||
|
},
|
||||||
|
extraOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
return gulp
|
||||||
|
.src("./src/pdf.sandbox.js")
|
||||||
|
.pipe(webpack2Stream(sandboxFileConfig))
|
||||||
|
.pipe(replaceWebpackRequire())
|
||||||
|
.pipe(replaceJSRootName(sandboxAMDName, "pdfjsSandbox"));
|
||||||
}
|
}
|
||||||
|
|
||||||
function createWorkerBundle(defines) {
|
function createWorkerBundle(defines) {
|
||||||
@ -544,25 +553,6 @@ function makeRef(done, bot) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
gulp.task("sandbox", function (done) {
|
|
||||||
const defines = builder.merge(DEFINES, { GENERIC: true });
|
|
||||||
buildSandbox(defines, GENERIC_DIR);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task("watch-sandbox", function (done) {
|
|
||||||
const defines = builder.merge(DEFINES, { GENERIC: true });
|
|
||||||
buildSandbox(defines, GENERIC_DIR);
|
|
||||||
const watcher = gulp.watch([
|
|
||||||
"src/scripting_api/*.js",
|
|
||||||
"external/quickjs/*.js",
|
|
||||||
]);
|
|
||||||
watcher.on("change", function () {
|
|
||||||
buildSandbox(defines, GENERIC_DIR);
|
|
||||||
});
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task("default", function (done) {
|
gulp.task("default", function (done) {
|
||||||
console.log("Available tasks:");
|
console.log("Available tasks:");
|
||||||
var tasks = Object.keys(gulp.registry().tasks());
|
var tasks = Object.keys(gulp.registry().tasks());
|
||||||
@ -798,6 +788,7 @@ function buildGeneric(defines, dir) {
|
|||||||
return merge([
|
return merge([
|
||||||
createMainBundle(defines).pipe(gulp.dest(dir + "build")),
|
createMainBundle(defines).pipe(gulp.dest(dir + "build")),
|
||||||
createWorkerBundle(defines).pipe(gulp.dest(dir + "build")),
|
createWorkerBundle(defines).pipe(gulp.dest(dir + "build")),
|
||||||
|
createSandboxBundle(defines).pipe(gulp.dest(dir + "build")),
|
||||||
createWebBundle(defines).pipe(gulp.dest(dir + "web")),
|
createWebBundle(defines).pipe(gulp.dest(dir + "web")),
|
||||||
gulp.src(COMMON_WEB_FILES, { base: "web/" }).pipe(gulp.dest(dir + "web")),
|
gulp.src(COMMON_WEB_FILES, { base: "web/" }).pipe(gulp.dest(dir + "web")),
|
||||||
gulp.src("LICENSE").pipe(gulp.dest(dir)),
|
gulp.src("LICENSE").pipe(gulp.dest(dir)),
|
||||||
@ -836,14 +827,17 @@ gulp.task(
|
|||||||
"buildnumber",
|
"buildnumber",
|
||||||
"default_preferences",
|
"default_preferences",
|
||||||
"locale",
|
"locale",
|
||||||
|
function scripting() {
|
||||||
|
var defines = builder.merge(DEFINES, { GENERIC: true });
|
||||||
|
return createTemporaryScriptingBundle(defines);
|
||||||
|
},
|
||||||
function () {
|
function () {
|
||||||
console.log();
|
console.log();
|
||||||
console.log("### Creating generic viewer");
|
console.log("### Creating generic viewer");
|
||||||
var defines = builder.merge(DEFINES, { GENERIC: true });
|
var defines = builder.merge(DEFINES, { GENERIC: true });
|
||||||
|
|
||||||
return buildGeneric(defines, GENERIC_DIR);
|
return buildGeneric(defines, GENERIC_DIR);
|
||||||
},
|
}
|
||||||
"sandbox"
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -855,6 +849,13 @@ gulp.task(
|
|||||||
"buildnumber",
|
"buildnumber",
|
||||||
"default_preferences",
|
"default_preferences",
|
||||||
"locale",
|
"locale",
|
||||||
|
function scripting() {
|
||||||
|
var defines = builder.merge(DEFINES, {
|
||||||
|
GENERIC: true,
|
||||||
|
SKIP_BABEL: false,
|
||||||
|
});
|
||||||
|
return createTemporaryScriptingBundle(defines);
|
||||||
|
},
|
||||||
function () {
|
function () {
|
||||||
console.log();
|
console.log();
|
||||||
console.log("### Creating generic (ES5) viewer");
|
console.log("### Creating generic (ES5) viewer");
|
||||||
@ -864,13 +865,6 @@ gulp.task(
|
|||||||
});
|
});
|
||||||
|
|
||||||
return buildGeneric(defines, GENERIC_ES5_DIR);
|
return buildGeneric(defines, GENERIC_ES5_DIR);
|
||||||
},
|
|
||||||
function () {
|
|
||||||
const defines = builder.merge(DEFINES, {
|
|
||||||
GENERIC: true,
|
|
||||||
SKIP_BABEL: false,
|
|
||||||
});
|
|
||||||
return buildSandbox(defines, GENERIC_ES5_DIR);
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -964,6 +958,7 @@ function buildMinified(defines, dir) {
|
|||||||
return merge([
|
return merge([
|
||||||
createMainBundle(defines).pipe(gulp.dest(dir + "build")),
|
createMainBundle(defines).pipe(gulp.dest(dir + "build")),
|
||||||
createWorkerBundle(defines).pipe(gulp.dest(dir + "build")),
|
createWorkerBundle(defines).pipe(gulp.dest(dir + "build")),
|
||||||
|
createSandboxBundle(defines).pipe(gulp.dest(dir + "build")),
|
||||||
createWebBundle(defines).pipe(gulp.dest(dir + "web")),
|
createWebBundle(defines).pipe(gulp.dest(dir + "web")),
|
||||||
createImageDecodersBundle(
|
createImageDecodersBundle(
|
||||||
builder.merge(defines, { IMAGE_DECODERS: true })
|
builder.merge(defines, { IMAGE_DECODERS: true })
|
||||||
@ -1003,16 +998,15 @@ gulp.task(
|
|||||||
"buildnumber",
|
"buildnumber",
|
||||||
"default_preferences",
|
"default_preferences",
|
||||||
"locale",
|
"locale",
|
||||||
|
function scripting() {
|
||||||
|
var defines = builder.merge(DEFINES, { MINIFIED: true, GENERIC: true });
|
||||||
|
return createTemporaryScriptingBundle(defines);
|
||||||
|
},
|
||||||
function () {
|
function () {
|
||||||
console.log();
|
console.log();
|
||||||
console.log("### Creating minified viewer");
|
console.log("### Creating minified viewer");
|
||||||
var defines = builder.merge(DEFINES, { MINIFIED: true, GENERIC: true });
|
var defines = builder.merge(DEFINES, { MINIFIED: true, GENERIC: true });
|
||||||
|
|
||||||
return buildSandbox(defines, MINIFIED_DIR);
|
|
||||||
},
|
|
||||||
function () {
|
|
||||||
var defines = builder.merge(DEFINES, { MINIFIED: true, GENERIC: true });
|
|
||||||
|
|
||||||
return buildMinified(defines, MINIFIED_DIR);
|
return buildMinified(defines, MINIFIED_DIR);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -1024,19 +1018,17 @@ gulp.task(
|
|||||||
"buildnumber",
|
"buildnumber",
|
||||||
"default_preferences",
|
"default_preferences",
|
||||||
"locale",
|
"locale",
|
||||||
function () {
|
function scripting() {
|
||||||
console.log();
|
|
||||||
console.log("### Creating minified (ES5) viewer");
|
|
||||||
var defines = builder.merge(DEFINES, {
|
var defines = builder.merge(DEFINES, {
|
||||||
MINIFIED: true,
|
MINIFIED: true,
|
||||||
GENERIC: true,
|
GENERIC: true,
|
||||||
SKIP_BABEL: false,
|
SKIP_BABEL: false,
|
||||||
});
|
});
|
||||||
|
return createTemporaryScriptingBundle(defines);
|
||||||
return buildSandbox(defines, MINIFIED_ES5_DIR);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
function () {
|
function () {
|
||||||
|
console.log();
|
||||||
|
console.log("### Creating minified (ES5) viewer");
|
||||||
var defines = builder.merge(DEFINES, {
|
var defines = builder.merge(DEFINES, {
|
||||||
MINIFIED: true,
|
MINIFIED: true,
|
||||||
GENERIC: true,
|
GENERIC: true,
|
||||||
@ -1238,80 +1230,85 @@ gulp.task("mozcentral", gulp.series("mozcentral-pre"));
|
|||||||
|
|
||||||
gulp.task(
|
gulp.task(
|
||||||
"chromium-pre",
|
"chromium-pre",
|
||||||
gulp.series("buildnumber", "default_preferences", "locale", function () {
|
gulp.series(
|
||||||
console.log();
|
"buildnumber",
|
||||||
console.log("### Building Chromium extension");
|
"default_preferences",
|
||||||
var defines = builder.merge(DEFINES, { CHROME: true, SKIP_BABEL: false });
|
"locale",
|
||||||
|
function scripting() {
|
||||||
|
var defines = builder.merge(DEFINES, { CHROME: true, SKIP_BABEL: false });
|
||||||
|
return createTemporaryScriptingBundle(defines);
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
console.log();
|
||||||
|
console.log("### Building Chromium extension");
|
||||||
|
var defines = builder.merge(DEFINES, { CHROME: true, SKIP_BABEL: false });
|
||||||
|
|
||||||
var CHROME_BUILD_DIR = BUILD_DIR + "/chromium/",
|
var CHROME_BUILD_DIR = BUILD_DIR + "/chromium/",
|
||||||
CHROME_BUILD_CONTENT_DIR = CHROME_BUILD_DIR + "/content/";
|
CHROME_BUILD_CONTENT_DIR = CHROME_BUILD_DIR + "/content/";
|
||||||
|
|
||||||
// Clear out everything in the chrome extension build directory
|
// Clear out everything in the chrome extension build directory
|
||||||
rimraf.sync(CHROME_BUILD_DIR);
|
rimraf.sync(CHROME_BUILD_DIR);
|
||||||
|
|
||||||
var version = getVersionJSON().version;
|
var version = getVersionJSON().version;
|
||||||
|
|
||||||
return merge([
|
return merge([
|
||||||
createMainBundle(defines).pipe(
|
createMainBundle(defines).pipe(
|
||||||
gulp.dest(CHROME_BUILD_CONTENT_DIR + "build")
|
gulp.dest(CHROME_BUILD_CONTENT_DIR + "build")
|
||||||
),
|
),
|
||||||
createWorkerBundle(defines).pipe(
|
createWorkerBundle(defines).pipe(
|
||||||
gulp.dest(CHROME_BUILD_CONTENT_DIR + "build")
|
gulp.dest(CHROME_BUILD_CONTENT_DIR + "build")
|
||||||
),
|
),
|
||||||
createWebBundle(defines).pipe(
|
createSandboxBundle(defines).pipe(
|
||||||
gulp.dest(CHROME_BUILD_CONTENT_DIR + "web")
|
gulp.dest(CHROME_BUILD_CONTENT_DIR + "build")
|
||||||
),
|
),
|
||||||
gulp
|
createWebBundle(defines).pipe(
|
||||||
.src(COMMON_WEB_FILES, { base: "web/" })
|
gulp.dest(CHROME_BUILD_CONTENT_DIR + "web")
|
||||||
.pipe(gulp.dest(CHROME_BUILD_CONTENT_DIR + "web")),
|
),
|
||||||
|
gulp
|
||||||
|
.src(COMMON_WEB_FILES, { base: "web/" })
|
||||||
|
.pipe(gulp.dest(CHROME_BUILD_CONTENT_DIR + "web")),
|
||||||
|
|
||||||
gulp
|
gulp
|
||||||
.src(
|
.src(
|
||||||
["web/locale/*/viewer.properties", "web/locale/locale.properties"],
|
["web/locale/*/viewer.properties", "web/locale/locale.properties"],
|
||||||
{ base: "web/" }
|
{ base: "web/" }
|
||||||
)
|
)
|
||||||
.pipe(gulp.dest(CHROME_BUILD_CONTENT_DIR + "web")),
|
.pipe(gulp.dest(CHROME_BUILD_CONTENT_DIR + "web")),
|
||||||
gulp
|
gulp
|
||||||
.src(["external/bcmaps/*.bcmap", "external/bcmaps/LICENSE"], {
|
.src(["external/bcmaps/*.bcmap", "external/bcmaps/LICENSE"], {
|
||||||
base: "external/bcmaps",
|
base: "external/bcmaps",
|
||||||
})
|
})
|
||||||
.pipe(gulp.dest(CHROME_BUILD_CONTENT_DIR + "web/cmaps")),
|
.pipe(gulp.dest(CHROME_BUILD_CONTENT_DIR + "web/cmaps")),
|
||||||
|
|
||||||
preprocessHTML("web/viewer.html", defines).pipe(
|
preprocessHTML("web/viewer.html", defines).pipe(
|
||||||
gulp.dest(CHROME_BUILD_CONTENT_DIR + "web")
|
gulp.dest(CHROME_BUILD_CONTENT_DIR + "web")
|
||||||
),
|
),
|
||||||
preprocessCSS("web/viewer.css", "chrome", defines, true)
|
preprocessCSS("web/viewer.css", "chrome", defines, true)
|
||||||
.pipe(
|
.pipe(
|
||||||
postcss([autoprefixer({ overrideBrowserslist: ["chrome >= 49"] })])
|
postcss([autoprefixer({ overrideBrowserslist: ["chrome >= 49"] })])
|
||||||
)
|
)
|
||||||
.pipe(gulp.dest(CHROME_BUILD_CONTENT_DIR + "web")),
|
.pipe(gulp.dest(CHROME_BUILD_CONTENT_DIR + "web")),
|
||||||
|
|
||||||
gulp.src("LICENSE").pipe(gulp.dest(CHROME_BUILD_DIR)),
|
gulp.src("LICENSE").pipe(gulp.dest(CHROME_BUILD_DIR)),
|
||||||
gulp
|
gulp
|
||||||
.src("extensions/chromium/manifest.json")
|
.src("extensions/chromium/manifest.json")
|
||||||
.pipe(replace(/\bPDFJSSCRIPT_VERSION\b/g, version))
|
.pipe(replace(/\bPDFJSSCRIPT_VERSION\b/g, version))
|
||||||
.pipe(gulp.dest(CHROME_BUILD_DIR)),
|
.pipe(gulp.dest(CHROME_BUILD_DIR)),
|
||||||
gulp
|
gulp
|
||||||
.src(
|
.src(
|
||||||
[
|
[
|
||||||
"extensions/chromium/**/*.{html,js,css,png}",
|
"extensions/chromium/**/*.{html,js,css,png}",
|
||||||
"extensions/chromium/preferences_schema.json",
|
"extensions/chromium/preferences_schema.json",
|
||||||
],
|
],
|
||||||
{ base: "extensions/chromium/" }
|
{ base: "extensions/chromium/" }
|
||||||
)
|
)
|
||||||
.pipe(gulp.dest(CHROME_BUILD_DIR)),
|
.pipe(gulp.dest(CHROME_BUILD_DIR)),
|
||||||
]);
|
]);
|
||||||
})
|
}
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
gulp.task(
|
gulp.task("chromium", gulp.series("chromium-pre"));
|
||||||
"chromium",
|
|
||||||
gulp.series("chromium-pre", function () {
|
|
||||||
var defines = builder.merge(DEFINES, { CHROME: true, SKIP_BABEL: false });
|
|
||||||
var CHROME_BUILD_CONTENT_DIR = BUILD_DIR + "/chromium/content/";
|
|
||||||
return buildSandbox(defines, CHROME_BUILD_CONTENT_DIR);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
gulp.task("jsdoc", function (done) {
|
gulp.task("jsdoc", function (done) {
|
||||||
console.log();
|
console.log();
|
||||||
@ -1432,15 +1429,17 @@ gulp.task(
|
|||||||
gulp.series(
|
gulp.series(
|
||||||
"buildnumber",
|
"buildnumber",
|
||||||
"default_preferences",
|
"default_preferences",
|
||||||
function () {
|
function scripting() {
|
||||||
var defines = builder.merge(DEFINES, { GENERIC: true, LIB: true });
|
var defines = builder.merge(DEFINES, { GENERIC: true, LIB: true });
|
||||||
|
return createTemporaryScriptingBundle(defines);
|
||||||
return buildLib(defines, "build/lib/");
|
|
||||||
},
|
},
|
||||||
function () {
|
function () {
|
||||||
var defines = builder.merge(DEFINES, { GENERIC: true, LIB: true });
|
var defines = builder.merge(DEFINES, { GENERIC: true, LIB: true });
|
||||||
|
|
||||||
return buildSandbox(defines, "build/lib/");
|
return merge([
|
||||||
|
buildLib(defines, "build/lib/"),
|
||||||
|
createSandboxBundle(defines).pipe(gulp.dest("build/lib/")),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -1450,14 +1449,13 @@ gulp.task(
|
|||||||
gulp.series(
|
gulp.series(
|
||||||
"buildnumber",
|
"buildnumber",
|
||||||
"default_preferences",
|
"default_preferences",
|
||||||
function () {
|
function scripting() {
|
||||||
var defines = builder.merge(DEFINES, {
|
var defines = builder.merge(DEFINES, {
|
||||||
GENERIC: true,
|
GENERIC: true,
|
||||||
LIB: true,
|
LIB: true,
|
||||||
SKIP_BABEL: false,
|
SKIP_BABEL: false,
|
||||||
});
|
});
|
||||||
|
return createTemporaryScriptingBundle(defines);
|
||||||
return buildLib(defines, "build/lib-es5/");
|
|
||||||
},
|
},
|
||||||
function () {
|
function () {
|
||||||
var defines = builder.merge(DEFINES, {
|
var defines = builder.merge(DEFINES, {
|
||||||
@ -1466,7 +1464,10 @@ gulp.task(
|
|||||||
SKIP_BABEL: false,
|
SKIP_BABEL: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
return buildSandbox(defines, "build/lib-es5/");
|
return merge([
|
||||||
|
buildLib(defines, "build/lib-es5/"),
|
||||||
|
createSandboxBundle(defines).pipe(gulp.dest("build/lib-es5/")),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -1717,16 +1718,57 @@ gulp.task(
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
gulp.task("server", function () {
|
gulp.task(
|
||||||
console.log();
|
"dev-sandbox",
|
||||||
console.log("### Starting local server");
|
gulp.series(
|
||||||
|
function scripting() {
|
||||||
|
const defines = builder.merge(DEFINES, { GENERIC: true, TESTING: true });
|
||||||
|
return createTemporaryScriptingBundle(defines, {
|
||||||
|
disableVersionInfo: true,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
console.log();
|
||||||
|
console.log("### Building development sandbox");
|
||||||
|
|
||||||
var WebServer = require("./test/webserver.js").WebServer;
|
const defines = builder.merge(DEFINES, { GENERIC: true, TESTING: true });
|
||||||
var server = new WebServer();
|
const sandboxDir = BUILD_DIR + "dev-sandbox/";
|
||||||
server.port = 8888;
|
|
||||||
server.start();
|
rimraf.sync(sandboxDir);
|
||||||
|
|
||||||
|
return createSandboxBundle(defines, {
|
||||||
|
disableVersionInfo: true,
|
||||||
|
}).pipe(gulp.dest(sandboxDir));
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
gulp.task("watch-dev-sandbox", function () {
|
||||||
|
gulp.watch(
|
||||||
|
[
|
||||||
|
"src/pdf.{sandbox,scripting}.js",
|
||||||
|
"src/scripting_api/*.js",
|
||||||
|
"src/shared/scripting_utils.js",
|
||||||
|
"external/quickjs/*.js",
|
||||||
|
],
|
||||||
|
{ ignoreInitial: false },
|
||||||
|
gulp.series("dev-sandbox")
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
gulp.task(
|
||||||
|
"server",
|
||||||
|
gulp.parallel("watch-dev-sandbox", function () {
|
||||||
|
console.log();
|
||||||
|
console.log("### Starting local server");
|
||||||
|
|
||||||
|
var WebServer = require("./test/webserver.js").WebServer;
|
||||||
|
var server = new WebServer();
|
||||||
|
server.port = 8888;
|
||||||
|
server.start();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
gulp.task("clean", function (done) {
|
gulp.task("clean", function (done) {
|
||||||
console.log();
|
console.log();
|
||||||
console.log("### Cleaning up project builds");
|
console.log("### Cleaning up project builds");
|
||||||
|
100
package-lock.json
generated
100
package-lock.json
generated
@ -2178,15 +2178,6 @@
|
|||||||
"ansi-wrap": "^0.1.0"
|
"ansi-wrap": "^0.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ansi-cyan": {
|
|
||||||
"version": "0.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz",
|
|
||||||
"integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"ansi-wrap": "0.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ansi-gray": {
|
"ansi-gray": {
|
||||||
"version": "0.1.1",
|
"version": "0.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz",
|
||||||
@ -2196,15 +2187,6 @@
|
|||||||
"ansi-wrap": "0.1.0"
|
"ansi-wrap": "0.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ansi-red": {
|
|
||||||
"version": "0.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz",
|
|
||||||
"integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"ansi-wrap": "0.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ansi-regex": {
|
"ansi-regex": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||||
@ -4028,15 +4010,6 @@
|
|||||||
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
|
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"decomment": {
|
|
||||||
"version": "0.9.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/decomment/-/decomment-0.9.3.tgz",
|
|
||||||
"integrity": "sha512-5skH5BfUL3n09RDmMVaHS1QGCiZRnl2nArUwmsE9JRY93Ueh3tihYl5wIrDdAuXnoFhxVis/DmRWREO2c6DG3w==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"esprima": "4.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"decompress-response": {
|
"decompress-response": {
|
||||||
"version": "4.2.1",
|
"version": "4.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
|
||||||
@ -7073,79 +7046,6 @@
|
|||||||
"replacestream": "^4.0.0"
|
"replacestream": "^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"gulp-strip-comments": {
|
|
||||||
"version": "2.5.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/gulp-strip-comments/-/gulp-strip-comments-2.5.2.tgz",
|
|
||||||
"integrity": "sha512-lb1bW7rsPWDD8f4ZPSguDvmCdjKmjr5HR4yZb9ros3sLl5AfW7oUj8KzY9/VRisT7dG8dL7hVHzNpQEVxfwZGQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"decomment": "^0.9.0",
|
|
||||||
"plugin-error": "^0.1.2",
|
|
||||||
"through2": "^2.0.3"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"arr-diff": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz",
|
|
||||||
"integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"arr-flatten": "^1.0.1",
|
|
||||||
"array-slice": "^0.2.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"arr-union": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz",
|
|
||||||
"integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"array-slice": {
|
|
||||||
"version": "0.2.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz",
|
|
||||||
"integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"extend-shallow": {
|
|
||||||
"version": "1.1.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz",
|
|
||||||
"integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"kind-of": "^1.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"kind-of": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz",
|
|
||||||
"integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"plugin-error": {
|
|
||||||
"version": "0.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz",
|
|
||||||
"integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"ansi-cyan": "^0.1.1",
|
|
||||||
"ansi-red": "^0.1.1",
|
|
||||||
"arr-diff": "^1.0.1",
|
|
||||||
"arr-union": "^2.0.1",
|
|
||||||
"extend-shallow": "^1.1.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"through2": {
|
|
||||||
"version": "2.0.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
|
|
||||||
"integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"readable-stream": "~2.3.6",
|
|
||||||
"xtend": "~4.0.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"gulp-zip": {
|
"gulp-zip": {
|
||||||
"version": "5.0.2",
|
"version": "5.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/gulp-zip/-/gulp-zip-5.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/gulp-zip/-/gulp-zip-5.0.2.tgz",
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
"gulp-postcss": "^9.0.0",
|
"gulp-postcss": "^9.0.0",
|
||||||
"gulp-rename": "^2.0.0",
|
"gulp-rename": "^2.0.0",
|
||||||
"gulp-replace": "^1.0.0",
|
"gulp-replace": "^1.0.0",
|
||||||
"gulp-strip-comments": "^2.5.2",
|
|
||||||
"gulp-zip": "^5.0.2",
|
"gulp-zip": "^5.0.2",
|
||||||
"jasmine": "^3.6.3",
|
"jasmine": "^3.6.3",
|
||||||
"jsdoc": "^3.6.6",
|
"jsdoc": "^3.6.6",
|
||||||
|
@ -13,17 +13,24 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ModuleLoader from "../../external/quickjs/quickjs-eval.js";
|
import ModuleLoader from "../external/quickjs/quickjs-eval.js";
|
||||||
|
|
||||||
|
/* eslint-disable-next-line no-unused-vars */
|
||||||
|
const pdfjsVersion = PDFJSDev.eval("BUNDLE_VERSION");
|
||||||
|
/* eslint-disable-next-line no-unused-vars */
|
||||||
|
const pdfjsBuild = PDFJSDev.eval("BUNDLE_BUILD");
|
||||||
|
|
||||||
|
const TESTING =
|
||||||
|
typeof PDFJSDev === "undefined" || PDFJSDev.test("!PRODUCTION || TESTING");
|
||||||
|
|
||||||
class Sandbox {
|
class Sandbox {
|
||||||
constructor(module, testMode) {
|
constructor(module) {
|
||||||
this._evalInSandbox = module.cwrap("evalInSandbox", null, [
|
this._evalInSandbox = module.cwrap("evalInSandbox", null, [
|
||||||
"string",
|
"string",
|
||||||
"int",
|
"int",
|
||||||
]);
|
]);
|
||||||
this._dispatchEventName = null;
|
this._dispatchEventName = null;
|
||||||
this._module = module;
|
this._module = module;
|
||||||
this._testMode = testMode;
|
|
||||||
this._alertOnError = 1;
|
this._alertOnError = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,14 +50,14 @@ class Sandbox {
|
|||||||
"module = Object.create(null);",
|
"module = Object.create(null);",
|
||||||
// Next line is replaced by code from initialization.js
|
// Next line is replaced by code from initialization.js
|
||||||
// when we create the bundle for the sandbox.
|
// when we create the bundle for the sandbox.
|
||||||
"/* INITIALIZATION_CODE */",
|
PDFJSDev.eval("PDF_SCRIPTING_JS_SOURCE"),
|
||||||
`data = ${sandboxData};`,
|
`data = ${sandboxData};`,
|
||||||
`module.exports.initSandbox({ data, extra: {${extraStr}}, out: this});`,
|
`module.exports.initSandbox({ data, extra: {${extraStr}}, out: this});`,
|
||||||
"delete exports;",
|
"delete exports;",
|
||||||
"delete module;",
|
"delete module;",
|
||||||
"delete data;",
|
"delete data;",
|
||||||
];
|
];
|
||||||
if (!this._testMode) {
|
if (!TESTING) {
|
||||||
code = code.concat(extra.map(name => `delete ${name};`));
|
code = code.concat(extra.map(name => `delete ${name};`));
|
||||||
code.push("delete debugMe;");
|
code.push("delete debugMe;");
|
||||||
}
|
}
|
||||||
@ -81,7 +88,7 @@ class Sandbox {
|
|||||||
}
|
}
|
||||||
|
|
||||||
evalForTesting(code, key) {
|
evalForTesting(code, key) {
|
||||||
if (this._testMode) {
|
if (TESTING) {
|
||||||
this._evalInSandbox(
|
this._evalInSandbox(
|
||||||
`try {
|
`try {
|
||||||
send({ id: "${key}", result: ${code} });
|
send({ id: "${key}", result: ${code} });
|
||||||
@ -94,13 +101,9 @@ class Sandbox {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function QuickJSSandbox(testMode = false) {
|
function QuickJSSandbox() {
|
||||||
testMode =
|
|
||||||
testMode &&
|
|
||||||
(typeof PDFJSDev === "undefined" ||
|
|
||||||
PDFJSDev.test("!PRODUCTION || TESTING"));
|
|
||||||
return ModuleLoader().then(module => {
|
return ModuleLoader().then(module => {
|
||||||
return new Sandbox(module, testMode);
|
return new Sandbox(module);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
import { loadScript } from "../../src/display/display_utils.js";
|
import { loadScript } from "../../src/display/display_utils.js";
|
||||||
|
|
||||||
|
const sandboxBundleSrc = "../../build/generic/build/pdf.sandbox.js";
|
||||||
|
|
||||||
describe("Scripting", function () {
|
describe("Scripting", function () {
|
||||||
let sandbox, send_queue, test_id, ref;
|
let sandbox, send_queue, test_id, ref;
|
||||||
|
|
||||||
@ -44,11 +46,9 @@ describe("Scripting", function () {
|
|||||||
send_queue.set(event.detail.id, event.detail);
|
send_queue.set(event.detail.id, event.detail);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const promise = loadScript("../../build/generic/build/pdf.sandbox.js").then(
|
const promise = loadScript(sandboxBundleSrc).then(() => {
|
||||||
() => {
|
return window.pdfjsSandbox.QuickJSSandbox();
|
||||||
return window.pdfjsSandbox.QuickJSSandbox(true);
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
sandbox = {
|
sandbox = {
|
||||||
createSandbox(data) {
|
createSandbox(data) {
|
||||||
promise.then(sbx => sbx.create(data));
|
promise.then(sbx => sbx.create(data));
|
||||||
|
146
web/app.js
146
web/app.js
@ -248,12 +248,16 @@ const PDFViewerApplication = {
|
|||||||
url: "",
|
url: "",
|
||||||
baseUrl: "",
|
baseUrl: "",
|
||||||
externalServices: DefaultExternalServices,
|
externalServices: DefaultExternalServices,
|
||||||
_boundEvents: {},
|
_boundEvents: Object.create(null),
|
||||||
contentDispositionFilename: null,
|
documentInfo: null,
|
||||||
|
metadata: null,
|
||||||
|
_contentDispositionFilename: null,
|
||||||
|
_contentLength: null,
|
||||||
triggerDelayedFallback: null,
|
triggerDelayedFallback: null,
|
||||||
_saveInProgress: false,
|
_saveInProgress: false,
|
||||||
_wheelUnusedTicks: 0,
|
_wheelUnusedTicks: 0,
|
||||||
_idleCallbacks: new Set(),
|
_idleCallbacks: new Set(),
|
||||||
|
_scriptingInstance: null,
|
||||||
|
|
||||||
// Called once when the document is loaded.
|
// Called once when the document is loaded.
|
||||||
async initialize(appConfig) {
|
async initialize(appConfig) {
|
||||||
@ -789,7 +793,10 @@ const PDFViewerApplication = {
|
|||||||
this.downloadComplete = false;
|
this.downloadComplete = false;
|
||||||
this.url = "";
|
this.url = "";
|
||||||
this.baseUrl = "";
|
this.baseUrl = "";
|
||||||
this.contentDispositionFilename = null;
|
this.documentInfo = null;
|
||||||
|
this.metadata = null;
|
||||||
|
this._contentDispositionFilename = null;
|
||||||
|
this._contentLength = null;
|
||||||
this.triggerDelayedFallback = null;
|
this.triggerDelayedFallback = null;
|
||||||
this._saveInProgress = false;
|
this._saveInProgress = false;
|
||||||
for (const callback of this._idleCallbacks) {
|
for (const callback of this._idleCallbacks) {
|
||||||
@ -797,6 +804,18 @@ const PDFViewerApplication = {
|
|||||||
}
|
}
|
||||||
this._idleCallbacks.clear();
|
this._idleCallbacks.clear();
|
||||||
|
|
||||||
|
if (this._scriptingInstance) {
|
||||||
|
const { scripting, events } = this._scriptingInstance;
|
||||||
|
try {
|
||||||
|
scripting.destroySandbox();
|
||||||
|
} catch (ex) {}
|
||||||
|
|
||||||
|
for (const [name, listener] of events) {
|
||||||
|
window.removeEventListener(name, listener);
|
||||||
|
}
|
||||||
|
this._scriptingInstance = null;
|
||||||
|
}
|
||||||
|
|
||||||
this.pdfSidebar.reset();
|
this.pdfSidebar.reset();
|
||||||
this.pdfOutlineViewer.reset();
|
this.pdfOutlineViewer.reset();
|
||||||
this.pdfAttachmentViewer.reset();
|
this.pdfAttachmentViewer.reset();
|
||||||
@ -942,7 +961,7 @@ const PDFViewerApplication = {
|
|||||||
// Use this.url instead of this.baseUrl to perform filename detection based
|
// Use this.url instead of this.baseUrl to perform filename detection based
|
||||||
// on the reference fragment as ultimate fallback if needed.
|
// on the reference fragment as ultimate fallback if needed.
|
||||||
const filename =
|
const filename =
|
||||||
this.contentDispositionFilename || getPDFFileNameFromURL(this.url);
|
this._contentDispositionFilename || getPDFFileNameFromURL(this.url);
|
||||||
const downloadManager = this.downloadManager;
|
const downloadManager = this.downloadManager;
|
||||||
downloadManager.onerror = err => {
|
downloadManager.onerror = err => {
|
||||||
// This error won't really be helpful because it's likely the
|
// This error won't really be helpful because it's likely the
|
||||||
@ -975,7 +994,7 @@ const PDFViewerApplication = {
|
|||||||
// Use this.url instead of this.baseUrl to perform filename detection based
|
// Use this.url instead of this.baseUrl to perform filename detection based
|
||||||
// on the reference fragment as ultimate fallback if needed.
|
// on the reference fragment as ultimate fallback if needed.
|
||||||
const filename =
|
const filename =
|
||||||
this.contentDispositionFilename || getPDFFileNameFromURL(this.url);
|
this._contentDispositionFilename || getPDFFileNameFromURL(this.url);
|
||||||
const downloadManager = this.downloadManager;
|
const downloadManager = this.downloadManager;
|
||||||
downloadManager.onerror = err => {
|
downloadManager.onerror = err => {
|
||||||
// This error won't really be helpful because it's likely the
|
// This error won't really be helpful because it's likely the
|
||||||
@ -1403,54 +1422,71 @@ const PDFViewerApplication = {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
async _initializeJavaScript(pdfDocument) {
|
async _initializeJavaScript(pdfDocument) {
|
||||||
const objects = await pdfDocument.getFieldObjects();
|
if (!AppOptions.get("enableScripting")) {
|
||||||
|
|
||||||
if (pdfDocument !== this.pdfDocument) {
|
|
||||||
return; // The document was closed while the JavaScript data resolved.
|
|
||||||
}
|
|
||||||
if (!objects || !AppOptions.get("enableScripting")) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const calculationOrder = await pdfDocument.getCalculationOrderIds();
|
const [objects, calculationOrder] = await Promise.all([
|
||||||
const scripting = this.externalServices.scripting;
|
pdfDocument.getFieldObjects(),
|
||||||
const {
|
pdfDocument.getCalculationOrderIds(),
|
||||||
info,
|
]);
|
||||||
metadata,
|
|
||||||
contentDispositionFilename,
|
|
||||||
} = await pdfDocument.getMetadata();
|
|
||||||
|
|
||||||
window.addEventListener("updateFromSandbox", event => {
|
if (!objects || pdfDocument !== this.pdfDocument) {
|
||||||
const detail = event.detail;
|
// No FieldObjects were found in the document,
|
||||||
const id = detail.id;
|
// or the document was closed while the data resolved.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { scripting } = this.externalServices;
|
||||||
|
// Store a reference to the current scripting-instance, to allow destruction
|
||||||
|
// of the sandbox and removal of the event listeners at document closing.
|
||||||
|
this._scriptingInstance = { scripting, events: new Map() };
|
||||||
|
|
||||||
|
if (!this.documentInfo) {
|
||||||
|
// It should be *extremely* rare for metadata to not have been resolved
|
||||||
|
// when this code runs, but ensure that we handle that case here.
|
||||||
|
await new Promise(resolve => {
|
||||||
|
const metadataLoaded = () => {
|
||||||
|
this.eventBus._off("metadataloaded", metadataLoaded);
|
||||||
|
resolve();
|
||||||
|
};
|
||||||
|
this.eventBus._on("metadataloaded", metadataLoaded);
|
||||||
|
});
|
||||||
|
if (pdfDocument !== this.pdfDocument) {
|
||||||
|
return; // The document was closed while the metadata resolved.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateFromSandbox = event => {
|
||||||
|
const { detail } = event;
|
||||||
|
const { id, command, value } = detail;
|
||||||
if (!id) {
|
if (!id) {
|
||||||
switch (detail.command) {
|
switch (command) {
|
||||||
case "alert":
|
case "alert":
|
||||||
// eslint-disable-next-line no-alert
|
// eslint-disable-next-line no-alert
|
||||||
window.alert(detail.value);
|
window.alert(value);
|
||||||
break;
|
break;
|
||||||
case "clear":
|
case "clear":
|
||||||
console.clear();
|
console.clear();
|
||||||
break;
|
break;
|
||||||
case "error":
|
case "error":
|
||||||
console.error(detail.value);
|
console.error(value);
|
||||||
break;
|
break;
|
||||||
case "layout":
|
case "layout":
|
||||||
this.pdfViewer.spreadMode = apiPageLayoutToSpreadMode(detail.value);
|
this.pdfViewer.spreadMode = apiPageLayoutToSpreadMode(value);
|
||||||
return;
|
return;
|
||||||
case "page-num":
|
case "page-num":
|
||||||
this.pdfViewer.currentPageNumber = detail.value + 1;
|
this.pdfViewer.currentPageNumber = value + 1;
|
||||||
return;
|
return;
|
||||||
case "print":
|
case "print":
|
||||||
this.triggerPrinting();
|
this.triggerPrinting();
|
||||||
return;
|
return;
|
||||||
case "println":
|
case "println":
|
||||||
console.log(detail.value);
|
console.log(value);
|
||||||
break;
|
break;
|
||||||
case "zoom":
|
case "zoom":
|
||||||
if (typeof detail.value === "string") {
|
if (typeof value === "string") {
|
||||||
this.pdfViewer.currentScaleValue = detail.value;
|
this.pdfViewer.currentScaleValue = value;
|
||||||
} else {
|
} else {
|
||||||
this.pdfViewer.currentScale = detail.value;
|
this.pdfViewer.currentScale = value;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1461,22 +1497,44 @@ const PDFViewerApplication = {
|
|||||||
if (element) {
|
if (element) {
|
||||||
element.dispatchEvent(new CustomEvent("updateFromSandbox", { detail }));
|
element.dispatchEvent(new CustomEvent("updateFromSandbox", { detail }));
|
||||||
} else {
|
} else {
|
||||||
const value = detail.value;
|
|
||||||
if (value !== undefined && value !== null) {
|
if (value !== undefined && value !== null) {
|
||||||
// the element hasn't been rendered yet so use annotation storage
|
// The element hasn't been rendered yet, use the AnnotationStorage.
|
||||||
pdfDocument.annotationStorage.setValue(id, detail.value);
|
pdfDocument.annotationStorage.setValue(id, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
window.addEventListener("updateFromSandbox", updateFromSandbox);
|
||||||
|
// Ensure that the event listener can be removed at document closing.
|
||||||
|
this._scriptingInstance.events.set("updateFromSandbox", updateFromSandbox);
|
||||||
|
|
||||||
window.addEventListener("dispatchEventInSandbox", function (event) {
|
const dispatchEventInSandbox = event => {
|
||||||
scripting.dispatchEventInSandbox(event.detail);
|
scripting.dispatchEventInSandbox(event.detail);
|
||||||
});
|
};
|
||||||
|
window.addEventListener("dispatchEventInSandbox", dispatchEventInSandbox);
|
||||||
|
// Ensure that the event listener can be removed at document closing.
|
||||||
|
this._scriptingInstance.events.set(
|
||||||
|
"dispatchEventInSandbox",
|
||||||
|
dispatchEventInSandbox
|
||||||
|
);
|
||||||
|
|
||||||
const dispatchEventName = generateRandomStringForSandbox(objects);
|
const dispatchEventName = generateRandomStringForSandbox(objects);
|
||||||
const { length } = await pdfDocument.getDownloadInfo();
|
|
||||||
|
if (!this._contentLength) {
|
||||||
|
// Always waiting for the entire PDF document to be loaded will, most
|
||||||
|
// likely, delay sandbox-creation too much in the general case for all
|
||||||
|
// PDF documents which are not provided as binary data to the API.
|
||||||
|
// Hence we'll simply have to trust that the `contentLength` (as provided
|
||||||
|
// by the server), when it exists, is accurate enough here.
|
||||||
|
const { length } = await pdfDocument.getDownloadInfo();
|
||||||
|
|
||||||
|
if (pdfDocument !== this.pdfDocument) {
|
||||||
|
return; // The document was closed while the download info resolved.
|
||||||
|
}
|
||||||
|
this._contentLength = length;
|
||||||
|
}
|
||||||
const filename =
|
const filename =
|
||||||
contentDispositionFilename || getPDFFileNameFromURL(this.url);
|
this._contentDispositionFilename || getPDFFileNameFromURL(this.url);
|
||||||
|
|
||||||
scripting.createSandbox({
|
scripting.createSandbox({
|
||||||
objects,
|
objects,
|
||||||
dispatchEventName,
|
dispatchEventName,
|
||||||
@ -1486,11 +1544,11 @@ const PDFViewerApplication = {
|
|||||||
language: navigator.language,
|
language: navigator.language,
|
||||||
},
|
},
|
||||||
docInfo: {
|
docInfo: {
|
||||||
...info,
|
...this.documentInfo,
|
||||||
baseURL: this.baseUrl,
|
baseURL: this.baseUrl,
|
||||||
filesize: length,
|
filesize: this._contentLength,
|
||||||
filename,
|
filename,
|
||||||
metadata,
|
metadata: this.metadata,
|
||||||
numPages: pdfDocument.numPages,
|
numPages: pdfDocument.numPages,
|
||||||
URL: this.url,
|
URL: this.url,
|
||||||
},
|
},
|
||||||
@ -1568,6 +1626,7 @@ const PDFViewerApplication = {
|
|||||||
info,
|
info,
|
||||||
metadata,
|
metadata,
|
||||||
contentDispositionFilename,
|
contentDispositionFilename,
|
||||||
|
contentLength,
|
||||||
} = await pdfDocument.getMetadata();
|
} = await pdfDocument.getMetadata();
|
||||||
|
|
||||||
if (pdfDocument !== this.pdfDocument) {
|
if (pdfDocument !== this.pdfDocument) {
|
||||||
@ -1575,7 +1634,8 @@ const PDFViewerApplication = {
|
|||||||
}
|
}
|
||||||
this.documentInfo = info;
|
this.documentInfo = info;
|
||||||
this.metadata = metadata;
|
this.metadata = metadata;
|
||||||
this.contentDispositionFilename = contentDispositionFilename;
|
this._contentDispositionFilename = contentDispositionFilename;
|
||||||
|
this._contentLength = contentLength;
|
||||||
|
|
||||||
// Provides some basic debug information
|
// Provides some basic debug information
|
||||||
console.log(
|
console.log(
|
||||||
@ -1652,6 +1712,8 @@ const PDFViewerApplication = {
|
|||||||
generator: generatorId,
|
generator: generatorId,
|
||||||
formType,
|
formType,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.eventBus.dispatch("metadataloaded", { source: this });
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -223,14 +223,6 @@ const defaultOptions = {
|
|||||||
value: false,
|
value: false,
|
||||||
kind: OptionKind.API,
|
kind: OptionKind.API,
|
||||||
},
|
},
|
||||||
scriptingSrc: {
|
|
||||||
/** @type {string} */
|
|
||||||
value:
|
|
||||||
typeof PDFJSDev === "undefined" || !PDFJSDev.test("PRODUCTION")
|
|
||||||
? "../build/generic/build/pdf.sandbox.js"
|
|
||||||
: "../build/pdf.sandbox.js",
|
|
||||||
kind: OptionKind.VIEWER,
|
|
||||||
},
|
|
||||||
verbosity: {
|
verbosity: {
|
||||||
/** @type {number} */
|
/** @type {number} */
|
||||||
value: 1,
|
value: 1,
|
||||||
@ -265,6 +257,14 @@ if (
|
|||||||
value: typeof navigator !== "undefined" ? navigator.language : "en-US",
|
value: typeof navigator !== "undefined" ? navigator.language : "en-US",
|
||||||
kind: OptionKind.VIEWER,
|
kind: OptionKind.VIEWER,
|
||||||
};
|
};
|
||||||
|
defaultOptions.sandboxBundleSrc = {
|
||||||
|
/** @type {string} */
|
||||||
|
value:
|
||||||
|
typeof PDFJSDev === "undefined" || !PDFJSDev.test("PRODUCTION")
|
||||||
|
? "../build/dev-sandbox/pdf.sandbox.js"
|
||||||
|
: "../build/pdf.sandbox.js",
|
||||||
|
kind: OptionKind.VIEWER,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const userOptions = Object.create(null);
|
const userOptions = Object.create(null);
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
/* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { DefaultExternalServices, PDFViewerApplication } from "./app.js";
|
|
||||||
import { loadScript, shadow } from "pdfjs-lib";
|
|
||||||
|
|
||||||
const DevCom = {};
|
|
||||||
|
|
||||||
class DevExternalServices extends DefaultExternalServices {
|
|
||||||
static get scripting() {
|
|
||||||
const promise = loadScript("../build/pdf.sandbox.js").then(() => {
|
|
||||||
return window.pdfjsSandbox.QuickJSSandbox();
|
|
||||||
});
|
|
||||||
const sandbox = {
|
|
||||||
createSandbox(data) {
|
|
||||||
promise.then(sbx => sbx.create(data));
|
|
||||||
},
|
|
||||||
dispatchEventInSandbox(event) {
|
|
||||||
promise.then(sbx => sbx.dispatchEvent(event));
|
|
||||||
},
|
|
||||||
destroySandbox() {
|
|
||||||
promise.then(sbx => sbx.nukeSandbox());
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return shadow(this, "scripting", sandbox);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PDFViewerApplication.externalServices = DevExternalServices;
|
|
||||||
|
|
||||||
export { DevCom };
|
|
@ -14,11 +14,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { DefaultExternalServices, PDFViewerApplication } from "./app.js";
|
import { DefaultExternalServices, PDFViewerApplication } from "./app.js";
|
||||||
import { loadScript, shadow } from "pdfjs-lib";
|
|
||||||
import { AppOptions } from "./app_options.js";
|
import { AppOptions } from "./app_options.js";
|
||||||
import { BasePreferences } from "./preferences.js";
|
import { BasePreferences } from "./preferences.js";
|
||||||
import { DownloadManager } from "./download_manager.js";
|
import { DownloadManager } from "./download_manager.js";
|
||||||
import { GenericL10n } from "./genericl10n.js";
|
import { GenericL10n } from "./genericl10n.js";
|
||||||
|
import { loadScript } from "pdfjs-lib";
|
||||||
|
|
||||||
if (typeof PDFJSDev !== "undefined" && !PDFJSDev.test("GENERIC")) {
|
if (typeof PDFJSDev !== "undefined" && !PDFJSDev.test("GENERIC")) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@ -39,6 +39,29 @@ class GenericPreferences extends BasePreferences {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GenericScripting {
|
||||||
|
constructor() {
|
||||||
|
this._ready = loadScript(AppOptions.get("sandboxBundleSrc")).then(() => {
|
||||||
|
return window.pdfjsSandbox.QuickJSSandbox();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async createSandbox(data) {
|
||||||
|
const sandbox = await this._ready;
|
||||||
|
sandbox.create(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
async dispatchEventInSandbox(event) {
|
||||||
|
const sandbox = await this._ready;
|
||||||
|
sandbox.dispatchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
async destroySandbox() {
|
||||||
|
const sandbox = await this._ready;
|
||||||
|
sandbox.nukeSandbox();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class GenericExternalServices extends DefaultExternalServices {
|
class GenericExternalServices extends DefaultExternalServices {
|
||||||
static createDownloadManager(options) {
|
static createDownloadManager(options) {
|
||||||
return new DownloadManager();
|
return new DownloadManager();
|
||||||
@ -53,22 +76,7 @@ class GenericExternalServices extends DefaultExternalServices {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static get scripting() {
|
static get scripting() {
|
||||||
const promise = loadScript(AppOptions.get("scriptingSrc")).then(() => {
|
return new GenericScripting();
|
||||||
return window.pdfjsSandbox.QuickJSSandbox();
|
|
||||||
});
|
|
||||||
const sandbox = {
|
|
||||||
createSandbox(data) {
|
|
||||||
promise.then(sbx => sbx.create(data));
|
|
||||||
},
|
|
||||||
dispatchEventInSandbox(event) {
|
|
||||||
promise.then(sbx => sbx.dispatchEvent(event));
|
|
||||||
},
|
|
||||||
destroySandbox() {
|
|
||||||
promise.then(sbx => sbx.nukeSandbox());
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return shadow(this, "scripting", sandbox);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PDFViewerApplication.externalServices = GenericExternalServices;
|
PDFViewerApplication.externalServices = GenericExternalServices;
|
||||||
|
@ -56,9 +56,6 @@ if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("GENERIC")) {
|
|||||||
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("CHROME")) {
|
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("CHROME")) {
|
||||||
require("./chromecom.js");
|
require("./chromecom.js");
|
||||||
}
|
}
|
||||||
if (typeof PDFJSDev === "undefined") {
|
|
||||||
import("./devcom.js");
|
|
||||||
}
|
|
||||||
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("CHROME || GENERIC")) {
|
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("CHROME || GENERIC")) {
|
||||||
require("./pdf_print_service.js");
|
require("./pdf_print_service.js");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user