From e24050fa137b6696dc8b5b38ef820fdca7dcad05 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Mon, 14 Oct 2019 13:19:41 +0200 Subject: [PATCH] [api-minor] Move the `ReadableStream` polyfill to the global scope Note that most (reasonably) modern browsers have supported this for a while now, see https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream#Browser_compatibility By moving the polyfill into `src/shared/compatibility.js` we can thus get rid of the need to manually export/import `ReadableStream` and simply use it directly instead. The only change here which *could* possibly lead to a difference in behavior is in the `isFetchSupported` function. Previously we attempted to check for the existence of a global `ReadableStream` implementation, which could now pass (assuming obviously that the preceding checks also succeeded). However I'm not sure if that's a problem, since the previous check only confirmed the existence of a native `ReadableStream` implementation and not that it actually worked correctly. Finally it *could* just as well have been a globally registered polyfill from an application embedding the PDF.js library. --- .eslintrc | 6 ---- src/display/display_utils.js | 1 - src/pdf.js | 1 - src/shared/compatibility.js | 30 +++++++++++++++++++ src/shared/message_handler.js | 2 +- src/shared/streams_polyfill.js | 55 ---------------------------------- src/shared/util.js | 2 -- test/unit/util_spec.js | 3 +- 8 files changed, 32 insertions(+), 68 deletions(-) delete mode 100644 src/shared/streams_polyfill.js diff --git a/.eslintrc b/.eslintrc index 0f50c6e55..2bbb0d3ce 100644 --- a/.eslintrc +++ b/.eslintrc @@ -117,12 +117,6 @@ "no-catch-shadow": "error", "no-delete-var": "error", "no-label-var": "error", - "no-restricted-globals": ["error", - { - "name": "ReadableStream", - "message": "Import it from `src/shared/util.js` or `pdfjsLib` instead; outside of the `/src` and `/web` folders, the rule may be disabled as needed. ", - }, - ], "no-shadow-restricted-names": "error", "no-shadow": "off", "no-undef-init": "error", diff --git a/src/display/display_utils.js b/src/display/display_utils.js index ba259e4d2..8e3afea9a 100644 --- a/src/display/display_utils.js +++ b/src/display/display_utils.js @@ -435,7 +435,6 @@ class StatTimer { function isFetchSupported() { return (typeof fetch !== 'undefined' && typeof Response !== 'undefined' && 'body' in Response.prototype && - // eslint-disable-next-line no-restricted-globals typeof ReadableStream !== 'undefined'); } diff --git a/src/pdf.js b/src/pdf.js index 508f2056d..de0d0d62d 100644 --- a/src/pdf.js +++ b/src/pdf.js @@ -106,7 +106,6 @@ exports.createObjectURL = pdfjsSharedUtil.createObjectURL; exports.removeNullCharacters = pdfjsSharedUtil.removeNullCharacters; exports.shadow = pdfjsSharedUtil.shadow; exports.Util = pdfjsSharedUtil.Util; -exports.ReadableStream = pdfjsSharedUtil.ReadableStream; exports.RenderingCancelledException = pdfjsDisplayDisplayUtils.RenderingCancelledException; exports.getFilenameFromUrl = pdfjsDisplayDisplayUtils.getFilenameFromUrl; diff --git a/src/shared/compatibility.js b/src/shared/compatibility.js index 41849c617..7dbafd29f 100644 --- a/src/shared/compatibility.js +++ b/src/shared/compatibility.js @@ -249,6 +249,36 @@ const isIE = /Trident/.test(userAgent); globalThis.URL = require('core-js/web/url'); })(); +// Support: IE, Node.js +(function checkReadableStream() { + if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('IMAGE_DECODERS')) { + // The current image decoders are synchronous, hence `ReadableStream` + // shouldn't need to be polyfilled for the IMAGE_DECODERS build target. + return; + } + let isReadableStreamSupported = false; + + if (typeof ReadableStream !== 'undefined') { + // MS Edge may say it has ReadableStream but they are not up to spec yet. + try { + // eslint-disable-next-line no-new + new ReadableStream({ + start(controller) { + controller.close(); + }, + }); + isReadableStreamSupported = true; + } catch (e) { + // The ReadableStream constructor cannot be used. + } + } + if (isReadableStreamSupported) { + return; + } + globalThis.ReadableStream = + require('web-streams-polyfill/dist/ponyfill').ReadableStream; +})(); + // Support: IE<11, Safari<8, Chrome<36 (function checkWeakMap() { if (globalThis.WeakMap) { diff --git a/src/shared/message_handler.js b/src/shared/message_handler.js index a8d44073d..36cec48ea 100644 --- a/src/shared/message_handler.js +++ b/src/shared/message_handler.js @@ -16,7 +16,7 @@ import { AbortException, assert, createPromiseCapability, MissingPDFException, - ReadableStream, UnexpectedResponseException, UnknownErrorException + UnexpectedResponseException, UnknownErrorException } from './util'; const CallbackKind = { diff --git a/src/shared/streams_polyfill.js b/src/shared/streams_polyfill.js deleted file mode 100644 index 711d27c5d..000000000 --- a/src/shared/streams_polyfill.js +++ /dev/null @@ -1,55 +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. - */ -/* eslint-disable no-restricted-globals */ - -if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('MOZCENTRAL')) { - if (typeof ReadableStream === 'undefined') { - throw new Error('Please enable ReadableStream support by resetting the ' + - '"javascript.options.streams" preference to "true" in about:config.'); - } - exports.ReadableStream = ReadableStream; -} else { - let isReadableStreamSupported = false; - if (typeof ReadableStream !== 'undefined') { - // MS Edge may say it has ReadableStream but they are not up to spec yet. - try { - // eslint-disable-next-line no-new - new ReadableStream({ - start(controller) { - controller.close(); - }, - }); - isReadableStreamSupported = true; - } catch (e) { - // The ReadableStream constructor cannot be used. - } - } - if (isReadableStreamSupported) { - exports.ReadableStream = ReadableStream; - } else if (typeof PDFJSDev !== 'undefined' && - PDFJSDev.test('IMAGE_DECODERS')) { - class DummyReadableStream { - constructor() { - throw new Error('The current image decoders are synchronous, ' + - 'hence `ReadableStream` shouldn\'t need to be ' + - 'polyfilled for the IMAGE_DECODERS build target.'); - } - } - exports.ReadableStream = DummyReadableStream; - } else { - exports.ReadableStream = - require('web-streams-polyfill/dist/ponyfill').ReadableStream; - } -} diff --git a/src/shared/util.js b/src/shared/util.js index 62c53a577..a6a40ee14 100644 --- a/src/shared/util.js +++ b/src/shared/util.js @@ -15,7 +15,6 @@ /* eslint no-var: error */ import './compatibility'; -import { ReadableStream } from './streams_polyfill'; const IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0]; const FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0]; @@ -930,7 +929,6 @@ export { readUint16, readUint32, removeNullCharacters, - ReadableStream, setVerbosityLevel, shadow, string32, diff --git a/test/unit/util_spec.js b/test/unit/util_spec.js index ce1f0c21e..e224fe79f 100644 --- a/test/unit/util_spec.js +++ b/test/unit/util_spec.js @@ -16,8 +16,7 @@ import { bytesToString, createPromiseCapability, createValidAbsoluteUrl, isArrayBuffer, isBool, isEmptyObj, isNum, isSameOrigin, isSpace, isString, log2, - ReadableStream, removeNullCharacters, string32, stringToBytes, - stringToPDFString + removeNullCharacters, string32, stringToBytes, stringToPDFString } from '../../src/shared/util'; describe('util', function() {