Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[api-minor] Simplify the *fallback* fake worker loader code in src/display/api.js #11418

Merged
merged 5 commits into from
Dec 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/browserify/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

var pdfjsLib = require('pdfjs-dist');

var pdfPath = '../helloworld/helloworld.pdf';
timvandermeij marked this conversation as resolved.
Show resolved Hide resolved
var pdfPath = '../learning/helloworld.pdf';

// Setting worker path to worker bundle.
pdfjsLib.GlobalWorkerOptions.workerSrc =
Expand Down
2 changes: 1 addition & 1 deletion examples/webpack/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

var pdfjsLib = require('pdfjs-dist');

var pdfPath = '../helloworld/helloworld.pdf';
var pdfPath = '../learning/helloworld.pdf';

// Setting worker path to worker bundle.
pdfjsLib.GlobalWorkerOptions.workerSrc =
Expand Down
2 changes: 0 additions & 2 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -1320,7 +1320,6 @@ gulp.task('dist-pre', gulp.series('generic', 'components', 'image_decoders',
bugs: DIST_BUGS_URL,
license: DIST_LICENSE,
dependencies: {
'node-ensure': '^0.0.0', // shim for node for require.ensure
'worker-loader': '^2.0.0', // used in external/dist/webpack.json
},
peerDependencies: {
Expand All @@ -1330,7 +1329,6 @@ gulp.task('dist-pre', gulp.series('generic', 'components', 'image_decoders',
'fs': false,
'http': false,
'https': false,
'node-ensure': false,
'url': false,
'zlib': false,
},
Expand Down
6 changes: 0 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
"jstransformer-markdown-it": "^2.1.0",
"merge-stream": "^1.0.1",
"mkdirp": "^0.5.1",
"node-ensure": "^0.0.0",
"prettier": "^1.19.1",
"rimraf": "^2.7.1",
"streamqueue": "^1.1.2",
Expand Down
169 changes: 72 additions & 97 deletions src/display/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* globals requirejs, __non_webpack_require__ */
/* eslint no-var: error */

/**
Expand All @@ -27,13 +26,14 @@ import {
unreachable, warn
} from '../shared/util';
import {
DOMCanvasFactory, DOMCMapReaderFactory, loadScript, PageViewport,
deprecated, DOMCanvasFactory, DOMCMapReaderFactory, loadScript, PageViewport,
releaseImageResources, RenderingCancelledException, StatTimer
} from './display_utils';
import { FontFaceObject, FontLoader } from './font_loader';
import { apiCompatibilityParams } from './api_compatibility';
import { CanvasGraphics } from './canvas';
import { GlobalWorkerOptions } from './worker_options';
import { isNodeJS } from '../shared/is_node';
import { MessageHandler } from '../shared/message_handler';
import { Metadata } from './metadata';
import { PDFDataTransportStream } from './transport_stream';
Expand All @@ -42,68 +42,6 @@ import { WebGLContext } from './webgl';
const DEFAULT_RANGE_CHUNK_SIZE = 65536; // 2^16 = 65536
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
* @param {DocumentInitParameters} params The document initialization
Expand Down Expand Up @@ -1526,14 +1464,40 @@ class LoopbackPort {

const PDFWorker = (function PDFWorkerClosure() {
const pdfWorkerPorts = new WeakMap();
let isWorkerDisabled = false;
let fallbackWorkerSrc;
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() {
if (GlobalWorkerOptions.workerSrc) {
return GlobalWorkerOptions.workerSrc;
}
if (typeof fallbackWorkerSrc !== 'undefined') {
if (!isNodeJS) {
deprecated('No "GlobalWorkerOptions.workerSrc" specified.');
}
return fallbackWorkerSrc;
}
throw new Error('No "GlobalWorkerOptions.workerSrc" specified.');
Expand All @@ -1550,39 +1514,50 @@ const PDFWorker = (function PDFWorkerClosure() {

// Loads worker code into main thread.
function setupFakeWorkerGlobal() {
if (fakeWorkerFilesLoadedCapability) {
return fakeWorkerFilesLoadedCapability.promise;
}
fakeWorkerFilesLoadedCapability = createPromiseCapability();

const mainWorkerMessageHandler = getMainThreadWorkerMessageHandler();
if (mainWorkerMessageHandler) {
// The worker was already loaded using a `<script>` tag.
fakeWorkerFilesLoadedCapability.resolve(mainWorkerMessageHandler);
return fakeWorkerFilesLoadedCapability.promise;
}
// 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 {
const loader = fakeWorkerFilesLoader || function() {
return loadScript(getWorkerSrc()).then(function() {
return window.pdfjsWorker.WorkerMessageHandler;
});
};
loader().then(fakeWorkerFilesLoadedCapability.resolve,
fakeWorkerFilesLoadedCapability.reject);
if (fakeWorkerCapability) {
return fakeWorkerCapability.promise;
}
return fakeWorkerFilesLoadedCapability.promise;
fakeWorkerCapability = createPromiseCapability();

const loader = async function() {
const mainWorkerMessageHandler = getMainThreadWorkerMessageHandler();

if (mainWorkerMessageHandler) {
// The worker was already loaded using e.g. a `<script>` tag.
return mainWorkerMessageHandler;
}
if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) {
if (typeof SystemJS !== 'object') {
throw new Error('SystemJS must be used to load fake worker.');
}
const worker = await SystemJS.import('pdfjs/core/worker');
return worker.WorkerMessageHandler;
}
if ((typeof PDFJSDev !== 'undefined' && PDFJSDev.test('GENERIC')) &&
// eslint-disable-next-line no-undef
(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) {
Expand Down
17 changes: 6 additions & 11 deletions web/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -1523,21 +1523,16 @@ if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {
};
}

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