diff --git a/README.md b/README.md index ee976fcc9af131..5ca22854febea4 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,9 @@ Feel free to stop by #pdfjs on irc.mozilla.org for questions or guidance. ### Online demo -+ https://mozilla.github.io/pdf.js/web/viewer.html ++ Modern browsers: https://mozilla.github.io/pdf.js/web/viewer.html + ++ Older browsers: https://mozilla.github.io/pdf.js/es5/web/viewer.html ### Browser Extensions diff --git a/examples/node/getinfo.js b/examples/node/getinfo.js index 3df0b2bac1260d..b8dcee37d2ea3d 100644 --- a/examples/node/getinfo.js +++ b/examples/node/getinfo.js @@ -8,7 +8,7 @@ // // Run `gulp dist-install` to generate 'pdfjs-dist' npm package files. -var pdfjsLib = require('pdfjs-dist'); +var pdfjsLib = require('pdfjs-dist/es5/build/pdf.js'); // Loading file from file system into typed array var pdfPath = process.argv[2] || '../../web/compressed.tracemonkey-pldi-09.pdf'; diff --git a/examples/node/pdf2png/pdf2png.js b/examples/node/pdf2png/pdf2png.js index 34e7b14a1bc9ec..151940f8c112c6 100644 --- a/examples/node/pdf2png/pdf2png.js +++ b/examples/node/pdf2png/pdf2png.js @@ -48,7 +48,7 @@ NodeCanvasFactory.prototype = { }, }; -var pdfjsLib = require('pdfjs-dist'); +var pdfjsLib = require('pdfjs-dist/es5/build/pdf.js'); // Relative path of the PDF file. var pdfURL = '../../../web/compressed.tracemonkey-pldi-09.pdf'; diff --git a/examples/node/pdf2svg.js b/examples/node/pdf2svg.js index 50860d869f8240..cddb9b9df3537b 100644 --- a/examples/node/pdf2svg.js +++ b/examples/node/pdf2svg.js @@ -14,7 +14,7 @@ var stream = require('stream'); require('./domstubs.js').setStubs(global); // Run `gulp dist-install` to generate 'pdfjs-dist' npm package files. -var pdfjsLib = require('pdfjs-dist'); +var pdfjsLib = require('pdfjs-dist/es5/build/pdf.js'); // Loading file from file system into typed array var pdfPath = process.argv[2] || '../../web/compressed.tracemonkey-pldi-09.pdf'; diff --git a/external/dist/README.md b/external/dist/README.md index daef282c17fab5..e124167b2e1e08 100644 --- a/external/dist/README.md +++ b/external/dist/README.md @@ -7,4 +7,7 @@ parsing and rendering PDFs. This is a pre-built version of the PDF.js source code. It is automatically generated by the build scripts. +For usage with older browsers/environments, without support for modern features +such as e.g. `ReadableStream`, please refer to the `es5` folder. + See https://github.com/mozilla/pdf.js for learning and contributing. diff --git a/gulpfile.js b/gulpfile.js index 7651f6cb0a0663..475a75b65ac92a 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -49,7 +49,9 @@ var EXTENSION_SRC_DIR = 'extensions/'; var BASELINE_DIR = BUILD_DIR + 'baseline/'; var MOZCENTRAL_BASELINE_DIR = BUILD_DIR + 'mozcentral.baseline/'; var GENERIC_DIR = BUILD_DIR + 'generic/'; +var GENERIC_ES5_DIR = BUILD_DIR + 'generic-es5/'; var COMPONENTS_DIR = BUILD_DIR + 'components/'; +var COMPONENTS_ES5_DIR = BUILD_DIR + 'components-es5/'; var IMAGE_DECODERS_DIR = BUILD_DIR + 'image_decoders'; var DEFAULT_PREFERENCES_DIR = BUILD_DIR + 'default_preferences/'; var MINIFIED_DIR = BUILD_DIR + 'minified/'; @@ -88,6 +90,7 @@ var AUTOPREFIXER_CONFIG = { var DEFINES = { PRODUCTION: true, + SKIP_BABEL: true, TESTING: false, // The main build targets: GENERIC: false, @@ -97,7 +100,6 @@ var DEFINES = { MINIFIED: false, COMPONENTS: false, LIB: false, - SKIP_BABEL: false, IMAGE_DECODERS: false, }; @@ -168,8 +170,7 @@ function createWebpackConfig(defines, output) { fs.readFileSync('./src/license_header_libre.js').toString(); var enableSourceMaps = !bundleDefines.FIREFOX && !bundleDefines.MOZCENTRAL && !bundleDefines.CHROME && !bundleDefines.TESTING; - var skipBabel = bundleDefines.SKIP_BABEL || - process.env['SKIP_BABEL'] === 'true'; + var skipBabel = bundleDefines.SKIP_BABEL; // Required to expose e.g., the `window` object. output.globalObject = 'this'; @@ -679,8 +680,8 @@ function preprocessHTML(source, defines) { return createStringSource(source.substr(i + 1), out); } -// Builds the generic production viewer that should be compatible with most -// modern HTML5 browsers. +// Builds the generic production viewer that is only compatible with up-to-date +// HTML5 browsers, which implements modern ECMAScript features. gulp.task('generic', gulp.series('buildnumber', 'default_preferences', 'locale', function() { console.log(); @@ -715,6 +716,40 @@ gulp.task('generic', gulp.series('buildnumber', 'default_preferences', 'locale', ]); })); +// Builds the generic production viewer that should be compatible with most +// older HTML5 browsers. +gulp.task('generic-es5', gulp.series('buildnumber', 'default_preferences', + 'locale', function() { + console.log(); + console.log('### Creating generic (ES5) viewer'); + var defines = builder.merge(DEFINES, { GENERIC: true, SKIP_BABEL: false, }); + + rimraf.sync(GENERIC_ES5_DIR); + + return merge([ + createBundle(defines).pipe(gulp.dest(GENERIC_ES5_DIR + 'build')), + createWebBundle(defines).pipe(gulp.dest(GENERIC_ES5_DIR + 'web')), + gulp.src(COMMON_WEB_FILES, { base: 'web/', }) + .pipe(gulp.dest(GENERIC_ES5_DIR + 'web')), + gulp.src('LICENSE').pipe(gulp.dest(GENERIC_ES5_DIR)), + gulp.src([ + 'web/locale/*/viewer.properties', + 'web/locale/locale.properties' + ], { base: 'web/', }).pipe(gulp.dest(GENERIC_ES5_DIR + 'web')), + gulp.src(['external/bcmaps/*.bcmap', 'external/bcmaps/LICENSE'], + { base: 'external/bcmaps', }) + .pipe(gulp.dest(GENERIC_ES5_DIR + 'web/cmaps')), + preprocessHTML('web/viewer.html', defines) + .pipe(gulp.dest(GENERIC_ES5_DIR + 'web')), + preprocessCSS('web/viewer.css', 'generic', defines, true) + .pipe(postcss([autoprefixer(AUTOPREFIXER_CONFIG)])) + .pipe(gulp.dest(GENERIC_ES5_DIR + 'web')), + + gulp.src('web/compressed.tracemonkey-pldi-09.pdf') + .pipe(gulp.dest(GENERIC_ES5_DIR + 'web')), + ]); +})); + gulp.task('components', gulp.series('buildnumber', function () { console.log(); console.log('### Creating generic components'); @@ -740,6 +775,30 @@ gulp.task('components', gulp.series('buildnumber', function () { ]); })); +gulp.task('components-es5', gulp.series('buildnumber', function () { + console.log(); + console.log('### Creating generic (ES5) components'); + var defines = builder.merge(DEFINES, { COMPONENTS: true, GENERIC: true, + SKIP_BABEL: false, }); + + rimraf.sync(COMPONENTS_ES5_DIR); + + var COMPONENTS_IMAGES = [ + 'web/images/annotation-*.svg', + 'web/images/loading-icon.gif', + 'web/images/shadow.png', + 'web/images/texture.png', + ]; + + return merge([ + createComponentsBundle(defines).pipe(gulp.dest(COMPONENTS_ES5_DIR)), + gulp.src(COMPONENTS_IMAGES).pipe(gulp.dest(COMPONENTS_ES5_DIR + 'images')), + preprocessCSS('web/pdf_viewer.css', 'components', defines, true) + .pipe(postcss([autoprefixer(AUTOPREFIXER_CONFIG)])) + .pipe(gulp.dest(COMPONENTS_ES5_DIR)), + ]); +})); + gulp.task('image_decoders', gulp.series('buildnumber', function() { console.log(); console.log('### Creating image decoders'); @@ -851,7 +910,7 @@ gulp.task('mozcentral-pre', gulp.series('buildnumber', 'default_preferences', function() { console.log(); console.log('### Building mozilla-central extension'); - var defines = builder.merge(DEFINES, { MOZCENTRAL: true, SKIP_BABEL: true, }); + var defines = builder.merge(DEFINES, { MOZCENTRAL: true, }); var MOZCENTRAL_DIR = BUILD_DIR + 'mozcentral/', MOZCENTRAL_EXTENSION_DIR = MOZCENTRAL_DIR + 'browser/extensions/pdfjs/', @@ -902,7 +961,7 @@ gulp.task('chromium-pre', gulp.series('buildnumber', 'default_preferences', 'locale', function() { console.log(); console.log('### Building Chromium extension'); - var defines = builder.merge(DEFINES, { CHROME: true, }); + var defines = builder.merge(DEFINES, { CHROME: true, SKIP_BABEL: false, }); var CHROME_BUILD_DIR = BUILD_DIR + '/chromium/', CHROME_BUILD_CONTENT_DIR = CHROME_BUILD_DIR + '/content/'; @@ -984,7 +1043,7 @@ gulp.task('lib', gulp.series('buildnumber', 'default_preferences', function() { }; } function preprocess(content) { - var skipBabel = process.env['SKIP_BABEL'] === 'true' || + var skipBabel = bundleDefines.SKIP_BABEL || /\/\*\s*no-babel-preset\s*\*\//.test(content); content = preprocessor2.preprocessPDFJSCode(ctx, content); content = babel.transform(content, { @@ -1008,16 +1067,17 @@ gulp.task('lib', gulp.series('buildnumber', 'default_preferences', function() { } var babel = require('@babel/core'); var versionInfo = getVersionJSON(); + var bundleDefines = builder.merge(DEFINES, { + GENERIC: true, + LIB: true, + BUNDLE_VERSION: versionInfo.version, + BUNDLE_BUILD: versionInfo.commit, + TESTING: process.env['TESTING'] === 'true', + }); var ctx = { rootPath: __dirname, saveComments: false, - defines: builder.merge(DEFINES, { - GENERIC: true, - LIB: true, - BUNDLE_VERSION: versionInfo.version, - BUNDLE_BUILD: versionInfo.commit, - TESTING: process.env['TESTING'] === 'true', - }), + defines: bundleDefines, map: { 'pdfjs-lib': '../pdf', }, @@ -1041,25 +1101,34 @@ gulp.task('lib', gulp.series('buildnumber', 'default_preferences', function() { .pipe(gulp.dest('build/lib/')); })); -gulp.task('publish', gulp.series('generic', function (done) { +gulp.task('publish', gulp.series('generic', 'generic-es5', function(done) { var version = JSON.parse( fs.readFileSync(BUILD_DIR + 'version.json').toString()).version; config.stableVersion = config.betaVersion; config.betaVersion = version; - createStringSource(CONFIG_FILE, JSON.stringify(config, null, 2)) - .pipe(gulp.dest('.')) - .on('end', function () { - var targetName = 'pdfjs-' + version + '-dist.zip'; - gulp.src(BUILD_DIR + 'generic/**') + var targetName = 'pdfjs-' + version + '-dist.zip'; + var targetNameES5 = 'pdfjs-' + version + '-es5-dist.zip'; + + return merge([ + createStringSource(CONFIG_FILE, JSON.stringify(config, null, 2)) + .pipe(gulp.dest('.')), + + gulp.src(GENERIC_DIR + '**') .pipe(zip(targetName)) .pipe(gulp.dest(BUILD_DIR)) - .on('end', function () { + .on('end', function() { console.log('Built distribution file: ' + targetName); - done(); - }); - }); + }), + + gulp.src(GENERIC_ES5_DIR + '**') + .pipe(zip(targetNameES5)) + .pipe(gulp.dest(BUILD_DIR)) + .on('end', function() { + console.log('Built distribution file: ' + targetNameES5); + }), + ]); })); gulp.task('testing-pre', function(done) { @@ -1233,6 +1302,9 @@ gulp.task('gh-pages-prepare', function () { return merge([ vfs.src(GENERIC_DIR + '**/*', { base: GENERIC_DIR, stripBOM: false, }) .pipe(gulp.dest(GH_PAGES_DIR)), + vfs.src(GENERIC_ES5_DIR + '**/*', { base: GENERIC_ES5_DIR, + stripBOM: false, }) + .pipe(gulp.dest(GH_PAGES_DIR + 'es5/')), gulp.src('test/features/**/*', { base: 'test/', }) .pipe(gulp.dest(GH_PAGES_DIR)), gulp.src(JSDOC_BUILD_DIR + '**/*', { base: JSDOC_BUILD_DIR, }) @@ -1285,10 +1357,12 @@ gulp.task('gh-pages-git', function (done) { done(); }); -gulp.task('web', gulp.series('generic', 'jsdoc', 'gh-pages-prepare', - 'wintersmith', 'gh-pages-git')); +gulp.task('web', gulp.series('generic', 'generic-es5', 'jsdoc', + 'gh-pages-prepare', 'wintersmith', + 'gh-pages-git')); -gulp.task('dist-pre', gulp.series('generic', 'components', 'image_decoders', +gulp.task('dist-pre', gulp.series('generic', 'generic-es5', 'components', + 'components-es5', 'image_decoders', 'lib', 'minified', function() { var VERSION = getVersionJSON().version; @@ -1373,6 +1447,13 @@ gulp.task('dist-pre', gulp.series('generic', 'components', 'image_decoders', GENERIC_DIR + 'build/pdf.worker.js.map', SRC_DIR + 'pdf.worker.entry.js', ]).pipe(gulp.dest(DIST_DIR + 'build/')), + gulp.src([ + GENERIC_ES5_DIR + 'build/pdf.js', + GENERIC_ES5_DIR + 'build/pdf.js.map', + GENERIC_ES5_DIR + 'build/pdf.worker.js', + GENERIC_ES5_DIR + 'build/pdf.worker.js.map', + SRC_DIR + 'pdf.worker.entry.js', + ]).pipe(gulp.dest(DIST_DIR + 'es5/build/')), gulp.src(MINIFIED_DIR + 'build/pdf.js') .pipe(rename('pdf.min.js')) .pipe(gulp.dest(DIST_DIR + 'build/')), @@ -1384,6 +1465,8 @@ gulp.task('dist-pre', gulp.series('generic', 'components', 'image_decoders', .pipe(gulp.dest(DIST_DIR + 'image_decoders/')), gulp.src(COMPONENTS_DIR + '**/*', { base: COMPONENTS_DIR, }) .pipe(gulp.dest(DIST_DIR + 'web/')), + gulp.src(COMPONENTS_ES5_DIR + '**/*', { base: COMPONENTS_ES5_DIR, }) + .pipe(gulp.dest(DIST_DIR + 'es5/web/')), gulp.src(IMAGE_DECODERS_DIR + '**/*', { base: IMAGE_DECODERS_DIR, }) .pipe(gulp.dest(DIST_DIR + 'image_decoders')), gulp.src(LIB_DIR + '**/*', { base: LIB_DIR, }) diff --git a/package.json b/package.json index c46b89fa9966e2..a48cfcff6198f1 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "yargs": "^11.1.1" }, "scripts": { - "test": "env SKIP_BABEL=true gulp lint unittestcli externaltest" + "test": "gulp lint unittestcli externaltest" }, "repository": { "type": "git", diff --git a/test/unit/clitests_helper.js b/test/unit/clitests_helper.js index 2d77b069c5b523..71b814ce9224b6 100644 --- a/test/unit/clitests_helper.js +++ b/test/unit/clitests_helper.js @@ -32,3 +32,9 @@ setVerbosityLevel(VerbosityLevel.ERRORS); setPDFNetworkStreamFactory(function(params) { return new PDFNodeStream(params); }); + +// Ensure that `ReadableStream` is always available. +if (typeof ReadableStream === 'undefined') { + globalThis.ReadableStream = + require('web-streams-polyfill/dist/ponyfill').ReadableStream; +}