Merge pull request #11418 from Snuffleupagus/simplify-fakeWorkerLoader

[api-minor] Simplify the *fallback* fake worker loader code in `src/display/api.js`
This commit is contained in:
Tim van der Meij 2019-12-21 13:24:51 +01:00 committed by GitHub
commit 04df367ab6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 78 additions and 117 deletions

View File

@ -5,7 +5,7 @@
var pdfjsLib = require('pdfjs-dist'); var pdfjsLib = require('pdfjs-dist');
var pdfPath = '../helloworld/helloworld.pdf'; var pdfPath = '../learning/helloworld.pdf';
// Setting worker path to worker bundle. // Setting worker path to worker bundle.
pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsLib.GlobalWorkerOptions.workerSrc =

View File

@ -5,7 +5,7 @@
var pdfjsLib = require('pdfjs-dist'); var pdfjsLib = require('pdfjs-dist');
var pdfPath = '../helloworld/helloworld.pdf'; var pdfPath = '../learning/helloworld.pdf';
// Setting worker path to worker bundle. // Setting worker path to worker bundle.
pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsLib.GlobalWorkerOptions.workerSrc =

View File

@ -1320,7 +1320,6 @@ gulp.task('dist-pre', gulp.series('generic', 'components', 'image_decoders',
bugs: DIST_BUGS_URL, bugs: DIST_BUGS_URL,
license: DIST_LICENSE, license: DIST_LICENSE,
dependencies: { dependencies: {
'node-ensure': '^0.0.0', // shim for node for require.ensure
'worker-loader': '^2.0.0', // used in external/dist/webpack.json 'worker-loader': '^2.0.0', // used in external/dist/webpack.json
}, },
peerDependencies: { peerDependencies: {
@ -1330,7 +1329,6 @@ gulp.task('dist-pre', gulp.series('generic', 'components', 'image_decoders',
'fs': false, 'fs': false,
'http': false, 'http': false,
'https': false, 'https': false,
'node-ensure': false,
'url': false, 'url': false,
'zlib': false, 'zlib': false,
}, },

6
package-lock.json generated
View File

@ -6682,12 +6682,6 @@
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
"dev": true "dev": true
}, },
"node-ensure": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/node-ensure/-/node-ensure-0.0.0.tgz",
"integrity": "sha1-7K52QVDemYYexcgQ/V0Jaxg5Mqc=",
"dev": true
},
"node-libs-browser": { "node-libs-browser": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz",

View File

@ -35,7 +35,6 @@
"jstransformer-markdown-it": "^2.1.0", "jstransformer-markdown-it": "^2.1.0",
"merge-stream": "^1.0.1", "merge-stream": "^1.0.1",
"mkdirp": "^0.5.1", "mkdirp": "^0.5.1",
"node-ensure": "^0.0.0",
"prettier": "^1.19.1", "prettier": "^1.19.1",
"rimraf": "^2.7.1", "rimraf": "^2.7.1",
"streamqueue": "^1.1.2", "streamqueue": "^1.1.2",

View File

@ -12,7 +12,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/* globals requirejs, __non_webpack_require__ */
/* eslint no-var: error */ /* eslint no-var: error */
/** /**
@ -27,13 +26,14 @@ import {
unreachable, warn unreachable, warn
} from '../shared/util'; } from '../shared/util';
import { import {
DOMCanvasFactory, DOMCMapReaderFactory, loadScript, PageViewport, deprecated, DOMCanvasFactory, DOMCMapReaderFactory, loadScript, PageViewport,
releaseImageResources, RenderingCancelledException, StatTimer releaseImageResources, RenderingCancelledException, StatTimer
} from './display_utils'; } from './display_utils';
import { FontFaceObject, FontLoader } from './font_loader'; import { FontFaceObject, FontLoader } from './font_loader';
import { apiCompatibilityParams } from './api_compatibility'; import { apiCompatibilityParams } from './api_compatibility';
import { CanvasGraphics } from './canvas'; import { CanvasGraphics } from './canvas';
import { GlobalWorkerOptions } from './worker_options'; import { GlobalWorkerOptions } from './worker_options';
import { isNodeJS } from '../shared/is_node';
import { MessageHandler } from '../shared/message_handler'; import { MessageHandler } from '../shared/message_handler';
import { Metadata } from './metadata'; import { Metadata } from './metadata';
import { PDFDataTransportStream } from './transport_stream'; import { PDFDataTransportStream } from './transport_stream';
@ -42,68 +42,6 @@ import { WebGLContext } from './webgl';
const DEFAULT_RANGE_CHUNK_SIZE = 65536; // 2^16 = 65536 const DEFAULT_RANGE_CHUNK_SIZE = 65536; // 2^16 = 65536
const RENDERING_CANCELLED_TIMEOUT = 100; // ms const RENDERING_CANCELLED_TIMEOUT = 100; // ms
let isWorkerDisabled = false;
let fallbackWorkerSrc;
let fakeWorkerFilesLoader = null;
if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('GENERIC')) {
let useRequireEnsure = false;
// For GENERIC build we need to add support for different fake file loaders
// for different frameworks.
if (typeof window === 'undefined') {
// node.js - disable worker and set require.ensure.
isWorkerDisabled = true;
if (typeof __non_webpack_require__.ensure === 'undefined') {
__non_webpack_require__.ensure = __non_webpack_require__('node-ensure');
}
useRequireEnsure = true;
} else if (typeof __non_webpack_require__ !== 'undefined' &&
typeof __non_webpack_require__.ensure === 'function') {
useRequireEnsure = true;
}
if (typeof requirejs !== 'undefined' && requirejs.toUrl) {
fallbackWorkerSrc = requirejs.toUrl('pdfjs-dist/build/pdf.worker.js');
}
const dynamicLoaderSupported =
typeof requirejs !== 'undefined' && requirejs.load;
fakeWorkerFilesLoader = useRequireEnsure ? (function() {
return new Promise(function(resolve, reject) {
__non_webpack_require__.ensure([], function() {
try {
let worker;
if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('LIB')) {
worker = __non_webpack_require__('../pdf.worker.js');
} else {
worker = __non_webpack_require__('./pdf.worker.js');
}
resolve(worker.WorkerMessageHandler);
} catch (ex) {
reject(ex);
}
}, reject, 'pdfjsWorker');
});
}) : dynamicLoaderSupported ? (function() {
return new Promise(function(resolve, reject) {
requirejs(['pdfjs-dist/build/pdf.worker'], function(worker) {
try {
resolve(worker.WorkerMessageHandler);
} catch (ex) {
reject(ex);
}
}, reject);
});
}) : null;
if (!fallbackWorkerSrc && typeof document === 'object' &&
'currentScript' in document) {
const pdfjsFilePath = document.currentScript && document.currentScript.src;
if (pdfjsFilePath) {
fallbackWorkerSrc =
pdfjsFilePath.replace(/(\.(?:min\.)?js)(\?.*)?$/i, '.worker$1$2');
}
}
}
/** /**
* @typedef {function} IPDFStreamFactory * @typedef {function} IPDFStreamFactory
* @param {DocumentInitParameters} params The document initialization * @param {DocumentInitParameters} params The document initialization
@ -1526,14 +1464,40 @@ class LoopbackPort {
const PDFWorker = (function PDFWorkerClosure() { const PDFWorker = (function PDFWorkerClosure() {
const pdfWorkerPorts = new WeakMap(); const pdfWorkerPorts = new WeakMap();
let isWorkerDisabled = false;
let fallbackWorkerSrc;
let nextFakeWorkerId = 0; let nextFakeWorkerId = 0;
let fakeWorkerFilesLoadedCapability; let fakeWorkerCapability;
if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('GENERIC')) {
// eslint-disable-next-line no-undef
if (isNodeJS && typeof __non_webpack_require__ === 'function') {
// Workers aren't supported in Node.js, force-disabling them there.
isWorkerDisabled = true;
if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('LIB')) {
fallbackWorkerSrc = '../pdf.worker.js';
} else {
fallbackWorkerSrc = './pdf.worker.js';
}
} else if (typeof document === 'object' && 'currentScript' in document) {
const pdfjsFilePath = document.currentScript &&
document.currentScript.src;
if (pdfjsFilePath) {
fallbackWorkerSrc =
pdfjsFilePath.replace(/(\.(?:min\.)?js)(\?.*)?$/i, '.worker$1$2');
}
}
}
function getWorkerSrc() { function getWorkerSrc() {
if (GlobalWorkerOptions.workerSrc) { if (GlobalWorkerOptions.workerSrc) {
return GlobalWorkerOptions.workerSrc; return GlobalWorkerOptions.workerSrc;
} }
if (typeof fallbackWorkerSrc !== 'undefined') { if (typeof fallbackWorkerSrc !== 'undefined') {
if (!isNodeJS) {
deprecated('No "GlobalWorkerOptions.workerSrc" specified.');
}
return fallbackWorkerSrc; return fallbackWorkerSrc;
} }
throw new Error('No "GlobalWorkerOptions.workerSrc" specified.'); throw new Error('No "GlobalWorkerOptions.workerSrc" specified.');
@ -1550,39 +1514,50 @@ const PDFWorker = (function PDFWorkerClosure() {
// Loads worker code into main thread. // Loads worker code into main thread.
function setupFakeWorkerGlobal() { function setupFakeWorkerGlobal() {
if (fakeWorkerFilesLoadedCapability) { if (fakeWorkerCapability) {
return fakeWorkerFilesLoadedCapability.promise; return fakeWorkerCapability.promise;
} }
fakeWorkerFilesLoadedCapability = createPromiseCapability(); fakeWorkerCapability = createPromiseCapability();
const mainWorkerMessageHandler = getMainThreadWorkerMessageHandler(); const loader = async function() {
if (mainWorkerMessageHandler) { const mainWorkerMessageHandler = getMainThreadWorkerMessageHandler();
// The worker was already loaded using a `<script>` tag.
fakeWorkerFilesLoadedCapability.resolve(mainWorkerMessageHandler); if (mainWorkerMessageHandler) {
return fakeWorkerFilesLoadedCapability.promise; // The worker was already loaded using e.g. a `<script>` tag.
} return mainWorkerMessageHandler;
// In the developer build load worker_loader.js which in turn loads all the
// other files and resolves the promise. In production only the
// pdf.worker.js file is needed.
if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) {
if (typeof SystemJS === 'object') {
SystemJS.import('pdfjs/core/worker').then((worker) => {
fakeWorkerFilesLoadedCapability.resolve(worker.WorkerMessageHandler);
}).catch(fakeWorkerFilesLoadedCapability.reject);
} else {
fakeWorkerFilesLoadedCapability.reject(
new Error('SystemJS must be used to load fake worker.'));
} }
} else { if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) {
const loader = fakeWorkerFilesLoader || function() { if (typeof SystemJS !== 'object') {
return loadScript(getWorkerSrc()).then(function() { throw new Error('SystemJS must be used to load fake worker.');
return window.pdfjsWorker.WorkerMessageHandler; }
}); const worker = await SystemJS.import('pdfjs/core/worker');
}; return worker.WorkerMessageHandler;
loader().then(fakeWorkerFilesLoadedCapability.resolve, }
fakeWorkerFilesLoadedCapability.reject); if ((typeof PDFJSDev !== 'undefined' && PDFJSDev.test('GENERIC')) &&
} // eslint-disable-next-line no-undef
return fakeWorkerFilesLoadedCapability.promise; (isNodeJS && typeof __non_webpack_require__ === 'function')) {
// Since bundlers, such as Webpack, cannot be told to leave `require`
// statements alone we are thus forced to jump through hoops in order
// to prevent `Critical dependency: ...` warnings in third-party
// deployments of the built `pdf.js`/`pdf.worker.js` files; see
// https://github.com/webpack/webpack/issues/8826
//
// The following hack is based on the assumption that code running in
// Node.js won't ever be affected by e.g. Content Security Policies that
// prevent the use of `eval`. If that ever occurs, we should revert this
// to a normal `__non_webpack_require__` statement and simply document
// the Webpack warnings instead (telling users to ignore them).
//
// eslint-disable-next-line no-eval
const worker = eval('require')(getWorkerSrc());
return worker.WorkerMessageHandler;
}
await loadScript(getWorkerSrc());
return window.pdfjsWorker.WorkerMessageHandler;
};
loader().then(fakeWorkerCapability.resolve, fakeWorkerCapability.reject);
return fakeWorkerCapability.promise;
} }
function createCDNWrapper(url) { function createCDNWrapper(url) {

View File

@ -1523,21 +1523,16 @@ if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {
}; };
} }
function loadFakeWorker() { async function loadFakeWorker() {
if (!GlobalWorkerOptions.workerSrc) { if (!GlobalWorkerOptions.workerSrc) {
GlobalWorkerOptions.workerSrc = AppOptions.get('workerSrc'); GlobalWorkerOptions.workerSrc = AppOptions.get('workerSrc');
} }
if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) { if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) {
return new Promise(function(resolve, reject) { if (typeof SystemJS !== 'object') {
if (typeof SystemJS === 'object') { throw new Error('SystemJS must be used to load fake worker.');
SystemJS.import('pdfjs/core/worker').then((worker) => { }
window.pdfjsWorker = worker; window.pdfjsWorker = await SystemJS.import('pdfjs/core/worker');
resolve(); return undefined;
}).catch(reject);
} else {
reject(new Error('SystemJS must be used to load fake worker.'));
}
});
} }
return loadScript(PDFWorker.getWorkerSrc()); return loadScript(PDFWorker.getWorkerSrc());
} }