From b8606abbc1448ffd26ad553b253e2fb72d7f2cb7 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sat, 17 Feb 2018 23:51:24 +0100 Subject: [PATCH] [api-major] Completely remove the global `PDFJS` object --- examples/acroforms/acroforms.js | 8 +- examples/browserify/main.js | 6 +- examples/components/pageviewer.js | 12 +- examples/components/simpleviewer.js | 14 +- examples/components/singlepageviewer.js | 14 +- examples/learning/helloworld.html | 4 +- examples/learning/helloworld64.html | 4 +- examples/learning/prevnext.html | 6 +- examples/mobile-viewer/viewer.js | 37 +- examples/text-only/pdf2svg.js | 10 +- gulpfile.js | 1 - src/display/global.js | 82 ----- src/doc_helper.js | 9 - src/pdf.js | 3 +- src/shared/compatibility.js | 16 +- test/driver.js | 12 +- test/unit/api_spec.js | 471 ++++++++++++------------ web/pdf_viewer.component.js | 40 +- 18 files changed, 323 insertions(+), 426 deletions(-) delete mode 100644 src/display/global.js diff --git a/examples/acroforms/acroforms.js b/examples/acroforms/acroforms.js index 44932e796..a54494534 100644 --- a/examples/acroforms/acroforms.js +++ b/examples/acroforms/acroforms.js @@ -15,7 +15,7 @@ 'use strict'; -PDFJS.GlobalWorkerOptions.workerSrc = +pdfjsDistBuildPdf.GlobalWorkerOptions.workerSrc = '../../node_modules/pdfjs-dist/build/pdf.worker.js'; var DEFAULT_URL = '../../test/pdfs/f1040.pdf'; @@ -24,7 +24,7 @@ var DEFAULT_SCALE = 1.0; var container = document.getElementById('pageContainer'); // Fetch the PDF document from the URL using promises. -PDFJS.getDocument(DEFAULT_URL).then(function (doc) { +pdfjsDistBuildPdf.getDocument(DEFAULT_URL).then(function (doc) { // Use a promise to fetch and render the next page. var promise = Promise.resolve(); @@ -32,12 +32,12 @@ PDFJS.getDocument(DEFAULT_URL).then(function (doc) { promise = promise.then(function (pageNum) { return doc.getPage(pageNum).then(function (pdfPage) { // Create the page view. - var pdfPageView = new PDFJS.PDFPageView({ + var pdfPageView = new pdfjsDistWebPdfViewer.PDFPageView({ container: container, id: pageNum, scale: DEFAULT_SCALE, defaultViewport: pdfPage.getViewport(DEFAULT_SCALE), - annotationLayerFactory: new PDFJS.DefaultAnnotationLayerFactory(), + annotationLayerFactory: new pdfjsDistWebPdfViewer.DefaultAnnotationLayerFactory(), renderInteractiveForms: true, }); diff --git a/examples/browserify/main.js b/examples/browserify/main.js index 5d20aa05b..218a8c0e5 100644 --- a/examples/browserify/main.js +++ b/examples/browserify/main.js @@ -3,16 +3,16 @@ // Hello world example for browserify. -require('pdfjs-dist'); +var pdfjsLib = require('pdfjs-dist'); var pdfPath = '../helloworld/helloworld.pdf'; // Setting worker path to worker bundle. -PDFJS.GlobalWorkerOptions.workerSrc = +pdfjsLib.GlobalWorkerOptions.workerSrc = '../../build/browserify/pdf.worker.bundle.js'; // Loading a document. -var loadingTask = PDFJS.getDocument(pdfPath); +var loadingTask = pdfjsLib.getDocument(pdfPath); loadingTask.promise.then(function (pdfDocument) { // Request a first page return pdfDocument.getPage(1).then(function (pdfPage) { diff --git a/examples/components/pageviewer.js b/examples/components/pageviewer.js index de33355e0..63d317560 100644 --- a/examples/components/pageviewer.js +++ b/examples/components/pageviewer.js @@ -15,14 +15,14 @@ 'use strict'; -if (!PDFJS.PDFPageView || !PDFJS.getDocument) { +if (!pdfjsDistBuildPdf.getDocument || !pdfjsDistWebPdfViewer.PDFPageView) { alert('Please build the pdfjs-dist library using\n' + ' `gulp dist-install`'); } // The workerSrc property shall be specified. // -PDFJS.GlobalWorkerOptions.workerSrc = +pdfjsDistBuildPdf.GlobalWorkerOptions.workerSrc = '../../node_modules/pdfjs-dist/build/pdf.worker.js'; // Some PDFs need external cmaps. @@ -37,7 +37,7 @@ var SCALE = 1.0; var container = document.getElementById('pageContainer'); // Loading document. -PDFJS.getDocument({ +pdfjsDistBuildPdf.getDocument({ url: DEFAULT_URL, cMapUrl: CMAP_URL, cMapPacked: CMAP_PACKED, @@ -45,14 +45,14 @@ PDFJS.getDocument({ // Document loaded, retrieving the page. return pdfDocument.getPage(PAGE_TO_VIEW).then(function (pdfPage) { // Creating the page view with default parameters. - var pdfPageView = new PDFJS.PDFPageView({ + var pdfPageView = new pdfjsDistWebPdfViewer.PDFPageView({ container: container, id: PAGE_TO_VIEW, scale: SCALE, defaultViewport: pdfPage.getViewport(SCALE), // We can enable text/annotations layers, if needed - textLayerFactory: new PDFJS.DefaultTextLayerFactory(), - annotationLayerFactory: new PDFJS.DefaultAnnotationLayerFactory() + textLayerFactory: new pdfjsDistWebPdfViewer.DefaultTextLayerFactory(), + annotationLayerFactory: new pdfjsDistWebPdfViewer.DefaultAnnotationLayerFactory(), }); // Associates the actual page with the view, and drawing it pdfPageView.setPdfPage(pdfPage); diff --git a/examples/components/simpleviewer.js b/examples/components/simpleviewer.js index 8d2e09fd2..c987fd8c9 100644 --- a/examples/components/simpleviewer.js +++ b/examples/components/simpleviewer.js @@ -15,14 +15,14 @@ 'use strict'; -if (!PDFJS.PDFViewer || !PDFJS.getDocument) { +if (!pdfjsDistBuildPdf.getDocument || !pdfjsDistWebPdfViewer.PDFViewer) { alert('Please build the pdfjs-dist library using\n' + ' `gulp dist-install`'); } // The workerSrc property shall be specified. // -PDFJS.GlobalWorkerOptions.workerSrc = +pdfjsDistBuildPdf.GlobalWorkerOptions.workerSrc = '../../node_modules/pdfjs-dist/build/pdf.worker.js'; // Some PDFs need external cmaps. @@ -36,17 +36,17 @@ var SEARCH_FOR = ''; // try 'Mozilla'; var container = document.getElementById('viewerContainer'); // (Optionally) enable hyperlinks within PDF files. -var pdfLinkService = new PDFJS.PDFLinkService(); +var pdfLinkService = new pdfjsDistWebPdfViewer.PDFLinkService(); -var pdfViewer = new PDFJS.PDFViewer({ +var pdfViewer = new pdfjsDistWebPdfViewer.PDFViewer({ container: container, linkService: pdfLinkService, }); pdfLinkService.setViewer(pdfViewer); // (Optionally) enable find controller. -var pdfFindController = new PDFJS.PDFFindController({ - pdfViewer: pdfViewer +var pdfFindController = new pdfjsDistWebPdfViewer.PDFFindController({ + pdfViewer: pdfViewer, }); pdfViewer.setFindController(pdfFindController); @@ -60,7 +60,7 @@ container.addEventListener('pagesinit', function () { }); // Loading document. -PDFJS.getDocument({ +pdfjsDistBuildPdf.getDocument({ url: DEFAULT_URL, cMapUrl: CMAP_URL, cMapPacked: CMAP_PACKED, diff --git a/examples/components/singlepageviewer.js b/examples/components/singlepageviewer.js index b2b9d34be..e1d554e59 100644 --- a/examples/components/singlepageviewer.js +++ b/examples/components/singlepageviewer.js @@ -15,14 +15,14 @@ 'use strict'; -if (!PDFJS.PDFSinglePageViewer || !PDFJS.getDocument) { +if (!pdfjsDistBuildPdf.getDocument || !pdfjsDistWebPdfViewer.PDFSinglePageViewer) { alert('Please build the pdfjs-dist library using\n' + ' `gulp dist-install`'); } // The workerSrc property shall be specified. // -PDFJS.GlobalWorkerOptions.workerSrc = +pdfjsDistBuildPdf.GlobalWorkerOptions.workerSrc = '../../node_modules/pdfjs-dist/build/pdf.worker.js'; // Some PDFs need external cmaps. @@ -36,17 +36,17 @@ var SEARCH_FOR = ''; // try 'Mozilla'; var container = document.getElementById('viewerContainer'); // (Optionally) enable hyperlinks within PDF files. -var pdfLinkService = new PDFJS.PDFLinkService(); +var pdfLinkService = new pdfjsDistWebPdfViewer.PDFLinkService(); -var pdfSinglePageViewer = new PDFJS.PDFSinglePageViewer({ +var pdfSinglePageViewer = new pdfjsDistWebPdfViewer.PDFSinglePageViewer({ container: container, linkService: pdfLinkService, }); pdfLinkService.setViewer(pdfSinglePageViewer); // (Optionally) enable find controller. -var pdfFindController = new PDFJS.PDFFindController({ - pdfViewer: pdfSinglePageViewer +var pdfFindController = new pdfjsDistWebPdfViewer.PDFFindController({ + pdfViewer: pdfSinglePageViewer, }); pdfSinglePageViewer.setFindController(pdfFindController); @@ -60,7 +60,7 @@ container.addEventListener('pagesinit', function () { }); // Loading document. -PDFJS.getDocument({ +pdfjsDistBuildPdf.getDocument({ url: DEFAULT_URL, cMapUrl: CMAP_URL, cMapPacked: CMAP_PACKED, diff --git a/examples/learning/helloworld.html b/examples/learning/helloworld.html index 5657b73e0..aab3f84b0 100644 --- a/examples/learning/helloworld.html +++ b/examples/learning/helloworld.html @@ -22,13 +22,13 @@ // // The workerSrc property shall be specified. // - PDFJS.GlobalWorkerOptions.workerSrc = + pdfjsDistBuildPdf.GlobalWorkerOptions.workerSrc = '../../node_modules/pdfjs-dist/build/pdf.worker.js'; // // Asynchronous download PDF // - PDFJS.getDocument(url).then(function getPdfHelloWorld(pdf) { + pdfjsDistBuildPdf.getDocument(url).then(function getPdfHelloWorld(pdf) { // // Fetch the first page // diff --git a/examples/learning/helloworld64.html b/examples/learning/helloworld64.html index 263ba905a..e24de3a2e 100644 --- a/examples/learning/helloworld64.html +++ b/examples/learning/helloworld64.html @@ -34,12 +34,12 @@ // // The workerSrc property shall be specified. // - PDFJS.GlobalWorkerOptions.workerSrc = + pdfjsDistBuildPdf.GlobalWorkerOptions.workerSrc = '../../node_modules/pdfjs-dist/build/pdf.worker.js'; // Opening PDF by passing its binary data as a string. It is still preferable // to use Uint8Array, but string or array-like structure will work too. - PDFJS.getDocument({data: pdfData}).then(function getPdfHelloWorld(pdf) { + pdfjsDistBuildPdf.getDocument({data: pdfData}).then(function getPdfHelloWorld(pdf) { // Fetch the first page. pdf.getPage(1).then(function getPageHelloWorld(page) { var scale = 1.5; diff --git a/examples/learning/prevnext.html b/examples/learning/prevnext.html index a315a2118..f02c40dbd 100644 --- a/examples/learning/prevnext.html +++ b/examples/learning/prevnext.html @@ -33,8 +33,8 @@ // pdf.js's one, or the pdf.js is executed via eval(), the workerSrc property // shall be specified. // - // PDFJS.GlobalWorkerOptions.workerSrc = - // '../../node_modules/pdfjs-dist/build/pdf.worker.js'; + pdfjsDistBuildPdf.GlobalWorkerOptions.workerSrc = + '../../node_modules/pdfjs-dist/build/pdf.worker.js'; var pdfDoc = null, pageNum = 1, @@ -117,7 +117,7 @@ /** * Asynchronously downloads PDF. */ - PDFJS.getDocument(url).then(function (pdfDoc_) { + pdfjsDistBuildPdf.getDocument(url).then(function (pdfDoc_) { pdfDoc = pdfDoc_; document.getElementById('page_count').textContent = pdfDoc.numPages; diff --git a/examples/mobile-viewer/viewer.js b/examples/mobile-viewer/viewer.js index 52e152986..7b03cbcb5 100644 --- a/examples/mobile-viewer/viewer.js +++ b/examples/mobile-viewer/viewer.js @@ -12,13 +12,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* globals PDFJS */ +/* globals pdfjsDistBuildPdf, pdfjsDistWebPdfViewer */ 'use strict'; -if (typeof PDFJS === 'undefined' || !PDFJS.PDFViewer || !PDFJS.getDocument) { - alert('Please build the pdfjs-dist library using\n' + - ' `gulp dist-install`'); +if (!pdfjsDistBuildPdf.getDocument || !pdfjsDistWebPdfViewer.PDFViewer) { + alert('Please build the pdfjs-dist library using\n `gulp dist-install`'); } var USE_ONLY_CSS_ZOOM = true; @@ -27,7 +26,7 @@ var MAX_IMAGE_SIZE = 1024 * 1024; var CMAP_URL = '../../node_modules/pdfjs-dist/cmaps/'; var CMAP_PACKED = true; -PDFJS.GlobalWorkerOptions.workerSrc = +pdfjsDistBuildPdf.GlobalWorkerOptions.workerSrc = '../../node_modules/pdfjs-dist/build/pdf.worker.js'; var DEFAULT_URL = '../../web/compressed.tracemonkey-pldi-09.pdf'; @@ -62,7 +61,7 @@ var PDFViewerApplication = { this.setTitleUsingUrl(url); // Loading document. - var loadingTask = PDFJS.getDocument({ + var loadingTask = pdfjsDistBuildPdf.getDocument({ url: url, maxImageSize: MAX_IMAGE_SIZE, cMapUrl: CMAP_URL, @@ -88,15 +87,15 @@ var PDFViewerApplication = { var l10n = self.l10n; var loadingErrorMessage; - if (exception instanceof PDFJS.InvalidPDFException) { + if (exception instanceof pdfjsDistBuildPdf.InvalidPDFException) { // change error message also for other builds loadingErrorMessage = l10n.get('invalid_file_error', null, 'Invalid or corrupted PDF file.'); - } else if (exception instanceof PDFJS.MissingPDFException) { + } else if (exception instanceof pdfjsDistBuildPdf.MissingPDFException) { // special message for missing PDFs loadingErrorMessage = l10n.get('missing_file_error', null, 'Missing PDF file.'); - } else if (exception instanceof PDFJS.UnexpectedResponseException) { + } else if (exception instanceof pdfjsDistBuildPdf.UnexpectedResponseException) { loadingErrorMessage = l10n.get('unexpected_response_error', null, 'Unexpected server response.'); } else { @@ -138,14 +137,14 @@ var PDFViewerApplication = { }, get loadingBar() { - var bar = new PDFJS.ProgressBar('#loadingBar', {}); + var bar = new pdfjsDistWebPdfViewer.ProgressBar('#loadingBar', {}); - return PDFJS.shadow(this, 'loadingBar', bar); + return pdfjsDistBuildPdf.shadow(this, 'loadingBar', bar); }, setTitleUsingUrl: function pdfViewSetTitleUsingUrl(url) { this.url = url; - var title = PDFJS.getFilenameFromUrl(url) || url; + var title = pdfjsDistBuildPdf.getFilenameFromUrl(url) || url; try { title = decodeURIComponent(title); } catch (e) { @@ -166,8 +165,7 @@ var PDFViewerApplication = { console.log('PDF ' + pdfDocument.fingerprint + ' [' + info.PDFFormatVersion + ' ' + (info.Producer || '-').trim() + ' / ' + (info.Creator || '-').trim() + ']' + - ' (PDF.js: ' + (PDFJS.version || '-') + - (!PDFJS.disableWebGL ? ' [WebGL]' : '') + ')'); + ' (PDF.js: ' + (pdfjsDistBuildPdf.version || '-') + ')'); var pdfTitle; if (metadata && metadata.has('dc:title')) { @@ -197,7 +195,8 @@ var PDFViewerApplication = { error: function pdfViewError(message, moreInfo) { var l10n = this.l10n; var moreInfoText = [l10n.get('error_version_info', - {version: PDFJS.version || '?', build: PDFJS.build || '?'}, + { version: pdfjsDistBuildPdf.version || '?', + build: pdfjsDistBuildPdf.build || '?' }, 'PDF.js v{{version}} (build: {{build}})')]; if (moreInfo) { @@ -295,13 +294,13 @@ var PDFViewerApplication = { }, initUI: function pdfViewInitUI() { - var linkService = new PDFJS.PDFLinkService(); + var linkService = new pdfjsDistWebPdfViewer.PDFLinkService(); this.pdfLinkService = linkService; - this.l10n = PDFJS.NullL10n; + this.l10n = pdfjsDistWebPdfViewer.NullL10n; var container = document.getElementById('viewerContainer'); - var pdfViewer = new PDFJS.PDFViewer({ + var pdfViewer = new pdfjsDistWebPdfViewer.PDFViewer({ container: container, linkService: linkService, l10n: this.l10n, @@ -311,7 +310,7 @@ var PDFViewerApplication = { this.pdfViewer = pdfViewer; linkService.setViewer(pdfViewer); - this.pdfHistory = new PDFJS.PDFHistory({ + this.pdfHistory = new pdfjsDistWebPdfViewer.PDFHistory({ linkService: linkService }); linkService.setHistory(this.pdfHistory); diff --git a/examples/text-only/pdf2svg.js b/examples/text-only/pdf2svg.js index eeb53bfb6..328121a54 100644 --- a/examples/text-only/pdf2svg.js +++ b/examples/text-only/pdf2svg.js @@ -18,7 +18,7 @@ var PAGE_NUMBER = 1; var PAGE_SCALE = 1.5; var SVG_NS = 'http://www.w3.org/2000/svg'; -PDFJS.GlobalWorkerOptions.workerSrc = +pdfjsDistBuildPdf.GlobalWorkerOptions.workerSrc = '../../node_modules/pdfjs-dist/build/pdf.worker.js'; function buildSVG(viewport, textContent) { @@ -33,8 +33,8 @@ function buildSVG(viewport, textContent) { textContent.items.forEach(function (textItem) { // we have to take in account viewport transform, which includes scale, // rotation and Y-axis flip, and not forgetting to flip text. - var tx = PDFJS.Util.transform( - PDFJS.Util.transform(viewport.transform, textItem.transform), + var tx = pdfjsDistBuildPdf.Util.transform( + pdfjsDistBuildPdf.Util.transform(viewport.transform, textItem.transform), [1, 0, 0, -1, 0, 0]); var style = textContent.styles[textItem.fontName]; // adding text element @@ -49,7 +49,7 @@ function buildSVG(viewport, textContent) { function pageLoaded() { // Loading document and page text content - PDFJS.getDocument({url: PDF_PATH}).then(function (pdfDocument) { + pdfjsDistBuildPdf.getDocument({url: PDF_PATH}).then(function (pdfDocument) { pdfDocument.getPage(PAGE_NUMBER).then(function (page) { var viewport = page.getViewport(PAGE_SCALE); page.getTextContent().then(function (textContent) { @@ -62,7 +62,7 @@ function pageLoaded() { } document.addEventListener('DOMContentLoaded', function () { - if (typeof PDFJS === 'undefined') { + if (typeof pdfjsDistBuildPdf === 'undefined') { alert('Built version of PDF.js was not found.\n' + 'Please run `gulp dist-install`.'); return; diff --git a/gulpfile.js b/gulpfile.js index 3568da316..54ef27640 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -934,7 +934,6 @@ gulp.task('jsdoc', function (done) { var JSDOC_FILES = [ 'src/doc_helper.js', 'src/display/api.js', - 'src/display/global.js', 'src/shared/util.js', 'src/core/annotation.js' ]; diff --git a/src/display/global.js b/src/display/global.js deleted file mode 100644 index 0941c431d..000000000 --- a/src/display/global.js +++ /dev/null @@ -1,82 +0,0 @@ -/* Copyright 2015 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 { - createBlob, createPromiseCapability, InvalidPDFException, isLittleEndian, - MissingPDFException, OPS, PageViewport, PasswordException, PasswordResponses, - removeNullCharacters, shadow, UnexpectedResponseException, - UnknownErrorException, UNSUPPORTED_FEATURES, Util -} from '../shared/util'; -import { - getDocument, LoopbackPort, PDFDataRangeTransport, PDFWorker -} from './api'; -import { AnnotationLayer } from './annotation_layer'; -import { getFilenameFromUrl } from './dom_utils'; -import globalScope from '../shared/global_scope'; -import { GlobalWorkerOptions } from './worker_options'; -import { Metadata } from './metadata'; -import { renderTextLayer } from './text_layer'; -import { SVGGraphics } from './svg'; - -// The global PDFJS object is now deprecated and will not be supported in -// the future. The members below are maintained for backward compatibility -// and shall not be extended or modified. If the global.js is included as -// a module, we will create a global PDFJS object instance or use existing. -if (!globalScope.PDFJS) { - globalScope.PDFJS = {}; -} -var PDFJS = globalScope.PDFJS; - -PDFJS.OPS = OPS; -PDFJS.UNSUPPORTED_FEATURES = UNSUPPORTED_FEATURES; -PDFJS.shadow = shadow; -PDFJS.createBlob = createBlob; -Object.defineProperty(PDFJS, 'isLittleEndian', { - configurable: true, - get: function PDFJS_isLittleEndian() { - return shadow(PDFJS, 'isLittleEndian', isLittleEndian()); - }, -}); -PDFJS.removeNullCharacters = removeNullCharacters; -PDFJS.PasswordResponses = PasswordResponses; -PDFJS.PasswordException = PasswordException; -PDFJS.UnknownErrorException = UnknownErrorException; -PDFJS.InvalidPDFException = InvalidPDFException; -PDFJS.MissingPDFException = MissingPDFException; -PDFJS.UnexpectedResponseException = UnexpectedResponseException; -PDFJS.Util = Util; -PDFJS.PageViewport = PageViewport; -PDFJS.createPromiseCapability = createPromiseCapability; - -PDFJS.getDocument = getDocument; -PDFJS.LoopbackPort = LoopbackPort; -PDFJS.PDFDataRangeTransport = PDFDataRangeTransport; -PDFJS.PDFWorker = PDFWorker; -PDFJS.GlobalWorkerOptions = GlobalWorkerOptions; - -PDFJS.getFilenameFromUrl = getFilenameFromUrl; - -PDFJS.AnnotationLayer = AnnotationLayer; - -PDFJS.renderTextLayer = renderTextLayer; - -PDFJS.Metadata = Metadata; - -PDFJS.SVGGraphics = SVGGraphics; - -export { - globalScope, - PDFJS, -}; diff --git a/src/doc_helper.js b/src/doc_helper.js index 69b055144..fd640b786 100644 --- a/src/doc_helper.js +++ b/src/doc_helper.js @@ -18,15 +18,6 @@ It is not for use in the executable code. */ -/** - * PDFJS scope object that contains all functions, objects and variables related - * to the PDF.js. - * @constructor - */ -function PDFJS() { // eslint-disable-line no-unused-vars - // Mock class constructor. See src/display/api.js. -} - /** * Represents the eventual result of an asynchronous operation. * @external Promise diff --git a/src/pdf.js b/src/pdf.js index 63fa57b5c..ea3a3cd83 100644 --- a/src/pdf.js +++ b/src/pdf.js @@ -22,7 +22,6 @@ var pdfjsBuild = typeof PDFJSDev !== 'undefined' ? PDFJSDev.eval('BUNDLE_BUILD') : void 0; var pdfjsSharedUtil = require('./shared/util.js'); -var pdfjsDisplayGlobal = require('./display/global.js'); var pdfjsDisplayAPI = require('./display/api.js'); var pdfjsDisplayTextLayer = require('./display/text_layer.js'); var pdfjsDisplayAnnotationLayer = require('./display/annotation_layer.js'); @@ -66,7 +65,6 @@ if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) { }); } -exports.PDFJS = pdfjsDisplayGlobal.PDFJS; exports.build = pdfjsDisplayAPI.build; exports.version = pdfjsDisplayAPI.version; exports.getDocument = pdfjsDisplayAPI.getDocument; @@ -91,6 +89,7 @@ exports.createObjectURL = pdfjsSharedUtil.createObjectURL; exports.removeNullCharacters = pdfjsSharedUtil.removeNullCharacters; exports.shadow = pdfjsSharedUtil.shadow; exports.createBlob = pdfjsSharedUtil.createBlob; +exports.Util = pdfjsSharedUtil.Util; exports.RenderingCancelledException = pdfjsDisplayDOMUtils.RenderingCancelledException; exports.getFilenameFromUrl = pdfjsDisplayDOMUtils.getFilenameFromUrl; diff --git a/src/shared/compatibility.js b/src/shared/compatibility.js index 1cf763637..5a4911357 100644 --- a/src/shared/compatibility.js +++ b/src/shared/compatibility.js @@ -13,32 +13,26 @@ * limitations under the License. */ /* eslint-disable mozilla/use-includes-instead-of-indexOf */ -/* globals PDFJS */ + +const globalScope = require('./global_scope'); // Skip compatibility checks for the extensions and if we already ran // this module. if ((typeof PDFJSDev === 'undefined' || !PDFJSDev.test('FIREFOX || MOZCENTRAL')) && - (typeof PDFJS === 'undefined' || !PDFJS.compatibilityChecked)) { + !globalScope._pdfjsCompatibilityChecked) { + +globalScope._pdfjsCompatibilityChecked = true; // In the Chrome extension, most of the polyfills are unnecessary. // We support down to Chrome 49, because it's still commonly used by Windows XP // users - https://github.com/mozilla/pdf.js/issues/9397 if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('CHROME')) { -const globalScope = require('./global_scope'); const isNodeJS = require('./is_node'); const hasDOM = typeof window === 'object' && typeof document === 'object'; -// Initializing PDFJS global object here, it case if we need to change/disable -// some PDF.js features, e.g. range requests -if (typeof PDFJS === 'undefined') { - globalScope.PDFJS = {}; -} - -PDFJS.compatibilityChecked = true; - // Support: Node.js (function checkNodeBtoa() { if (globalScope.btoa || !isNodeJS()) { diff --git a/test/driver.js b/test/driver.js index 1206b912c..ac7d804ef 100644 --- a/test/driver.js +++ b/test/driver.js @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* globals PDFJS, pdfjsDistBuildPdf */ +/* globals pdfjsDistBuildPdf, pdfjsDistWebPdfViewer */ 'use strict'; @@ -69,7 +69,7 @@ var rasterizeTextLayer = (function rasterizeTextLayerClosure() { foreignObject.appendChild(div); // Rendering text layer as HTML. - var task = PDFJS.renderTextLayer({ + var task = pdfjsDistBuildPdf.renderTextLayer({ textContent, container: div, viewport, @@ -204,11 +204,11 @@ var rasterizeAnnotationLayer = (function rasterizeAnnotationLayerClosure() { div, annotations, page, - linkService: new PDFJS.SimpleLinkService(), + linkService: new pdfjsDistWebPdfViewer.SimpleLinkService(), imageResourcesPath, renderInteractiveForms, }; - PDFJS.AnnotationLayer.render(parameters); + pdfjsDistBuildPdf.AnnotationLayer.render(parameters); // Inline SVG images from text annotations. var images = div.getElementsByTagName('img'); @@ -271,7 +271,7 @@ var Driver = (function DriverClosure() { // eslint-disable-line no-unused-vars */ function Driver(options) { // Configure the global worker options. - PDFJS.GlobalWorkerOptions.workerSrc = WORKER_SRC; + pdfjsDistBuildPdf.GlobalWorkerOptions.workerSrc = WORKER_SRC; // Set the passed options this.inflight = options.inflight; @@ -358,7 +358,7 @@ var Driver = (function DriverClosure() { // eslint-disable-line no-unused-vars let absoluteUrl = new URL(task.file, window.location).href; try { - PDFJS.getDocument({ + pdfjsDistBuildPdf.getDocument({ url: absoluteUrl, password: task.password, nativeImageDecoderSupport: task.nativeImageDecoderSupport, diff --git a/test/unit/api_spec.js b/test/unit/api_spec.js index f879ba7c3..35e729283 100644 --- a/test/unit/api_spec.js +++ b/test/unit/api_spec.js @@ -58,266 +58,265 @@ describe('api', function() { }, WAIT_TIMEOUT); } - describe('PDFJS', function() { - describe('getDocument', function() { - it('creates pdf doc from URL', function(done) { - var loadingTask = getDocument(basicApiGetDocumentParams); + describe('getDocument', function() { + it('creates pdf doc from URL', function(done) { + var loadingTask = getDocument(basicApiGetDocumentParams); - var isProgressReportedResolved = false; - var progressReportedCapability = createPromiseCapability(); + var isProgressReportedResolved = false; + var progressReportedCapability = createPromiseCapability(); - // Attach the callback that is used to report loading progress; - // similarly to how viewer.js works. - loadingTask.onProgress = function (progressData) { - if (!isProgressReportedResolved) { - isProgressReportedResolved = true; - progressReportedCapability.resolve(progressData); - } - }; + // Attach the callback that is used to report loading progress; + // similarly to how viewer.js works. + loadingTask.onProgress = function (progressData) { + if (!isProgressReportedResolved) { + isProgressReportedResolved = true; + progressReportedCapability.resolve(progressData); + } + }; - var promises = [ - progressReportedCapability.promise, - loadingTask.promise - ]; - Promise.all(promises).then(function (data) { - expect((data[0].loaded / data[0].total) > 0).toEqual(true); - expect(data[1] instanceof PDFDocumentProxy).toEqual(true); - expect(loadingTask).toEqual(data[1].loadingTask); - loadingTask.destroy().then(done); - }).catch(function (reason) { - done.fail(reason); - }); + var promises = [ + progressReportedCapability.promise, + loadingTask.promise + ]; + Promise.all(promises).then(function (data) { + expect((data[0].loaded / data[0].total) > 0).toEqual(true); + expect(data[1] instanceof PDFDocumentProxy).toEqual(true); + expect(loadingTask).toEqual(data[1].loadingTask); + loadingTask.destroy().then(done); + }).catch(function (reason) { + done.fail(reason); }); - it('creates pdf doc from URL and aborts before worker initialized', - function(done) { - var loadingTask = getDocument(basicApiGetDocumentParams); - let destroyed = loadingTask.destroy(); + }); + it('creates pdf doc from URL and aborts before worker initialized', + function(done) { + var loadingTask = getDocument(basicApiGetDocumentParams); + let destroyed = loadingTask.destroy(); - loadingTask.promise.then(function(reason) { - done.fail('shall fail loading'); - }).catch(function (reason) { - expect(true).toEqual(true); - destroyed.then(done); - }); + loadingTask.promise.then(function(reason) { + done.fail('shall fail loading'); + }).catch(function (reason) { + expect(true).toEqual(true); + destroyed.then(done); }); - it('creates pdf doc from URL and aborts loading after worker initialized', - function(done) { - var loadingTask = getDocument(basicApiGetDocumentParams); - // This can be somewhat random -- we cannot guarantee perfect - // 'Terminate' message to the worker before/after setting up pdfManager. - var destroyed = loadingTask._worker.promise.then(function () { - return loadingTask.destroy(); - }); - destroyed.then(function (data) { - expect(true).toEqual(true); - done(); - }).catch(function (reason) { - done.fail(reason); - }); + }); + it('creates pdf doc from URL and aborts loading after worker initialized', + function(done) { + var loadingTask = getDocument(basicApiGetDocumentParams); + // This can be somewhat random -- we cannot guarantee perfect + // 'Terminate' message to the worker before/after setting up pdfManager. + var destroyed = loadingTask._worker.promise.then(function () { + return loadingTask.destroy(); }); - it('creates pdf doc from typed array', function(done) { - var typedArrayPdf; - if (isNodeJS()) { - typedArrayPdf = NodeFileReaderFactory.fetch({ - path: TEST_PDFS_PATH.node + basicApiFileName, - }); + destroyed.then(function (data) { + expect(true).toEqual(true); + done(); + }).catch(function (reason) { + done.fail(reason); + }); + }); + it('creates pdf doc from typed array', function(done) { + var typedArrayPdf; + if (isNodeJS()) { + typedArrayPdf = NodeFileReaderFactory.fetch({ + path: TEST_PDFS_PATH.node + basicApiFileName, + }); + } else { + let nonBinaryRequest = false; + let request = new XMLHttpRequest(); + request.open('GET', TEST_PDFS_PATH.dom + basicApiFileName, false); + try { + request.responseType = 'arraybuffer'; + nonBinaryRequest = request.responseType !== 'arraybuffer'; + } catch (e) { + nonBinaryRequest = true; + } + if (nonBinaryRequest && request.overrideMimeType) { + request.overrideMimeType('text/plain; charset=x-user-defined'); + } + request.send(null); + + if (nonBinaryRequest) { + typedArrayPdf = stringToBytes(request.responseText); } else { - let nonBinaryRequest = false; - let request = new XMLHttpRequest(); - request.open('GET', TEST_PDFS_PATH.dom + basicApiFileName, false); - try { - request.responseType = 'arraybuffer'; - nonBinaryRequest = request.responseType !== 'arraybuffer'; - } catch (e) { - nonBinaryRequest = true; - } - if (nonBinaryRequest && request.overrideMimeType) { - request.overrideMimeType('text/plain; charset=x-user-defined'); - } - request.send(null); - - if (nonBinaryRequest) { - typedArrayPdf = stringToBytes(request.responseText); - } else { - typedArrayPdf = new Uint8Array(request.response); - } + typedArrayPdf = new Uint8Array(request.response); } - // Sanity check to make sure that we fetched the entire PDF file. - expect(typedArrayPdf.length).toEqual(basicApiFileLength); + } + // Sanity check to make sure that we fetched the entire PDF file. + expect(typedArrayPdf.length).toEqual(basicApiFileLength); - var loadingTask = getDocument(typedArrayPdf); - loadingTask.promise.then(function(data) { - expect(data instanceof PDFDocumentProxy).toEqual(true); - loadingTask.destroy().then(done); - }).catch(function (reason) { - done.fail(reason); - }); + var loadingTask = getDocument(typedArrayPdf); + loadingTask.promise.then(function(data) { + expect(data instanceof PDFDocumentProxy).toEqual(true); + loadingTask.destroy().then(done); + }).catch(function (reason) { + done.fail(reason); }); - it('creates pdf doc from invalid PDF file', function(done) { - // A severely corrupt PDF file (even Adobe Reader fails to open it). - var loadingTask = getDocument(buildGetDocumentParams('bug1020226.pdf')); - loadingTask.promise.then(function () { - done.fail('shall fail loading'); - }).catch(function (error) { - expect(error instanceof InvalidPDFException).toEqual(true); - loadingTask.destroy().then(done); - }); + }); + it('creates pdf doc from invalid PDF file', function(done) { + // A severely corrupt PDF file (even Adobe Reader fails to open it). + var loadingTask = getDocument(buildGetDocumentParams('bug1020226.pdf')); + loadingTask.promise.then(function () { + done.fail('shall fail loading'); + }).catch(function (error) { + expect(error instanceof InvalidPDFException).toEqual(true); + loadingTask.destroy().then(done); }); - it('creates pdf doc from non-existent URL', function(done) { - if (isNodeJS()) { - pending('XMLHttpRequest is not supported in Node.js.'); + }); + it('creates pdf doc from non-existent URL', function(done) { + if (isNodeJS()) { + pending('XMLHttpRequest is not supported in Node.js.'); + } + var loadingTask = getDocument( + buildGetDocumentParams('non-existent.pdf')); + loadingTask.promise.then(function(error) { + done.fail('shall fail loading'); + }).catch(function (error) { + expect(error instanceof MissingPDFException).toEqual(true); + loadingTask.destroy().then(done); + }); + }); + it('creates pdf doc from PDF file protected with user and owner password', + function (done) { + var loadingTask = getDocument(buildGetDocumentParams('pr6531_1.pdf')); + + var isPasswordNeededResolved = false; + var passwordNeededCapability = createPromiseCapability(); + var isPasswordIncorrectResolved = false; + var passwordIncorrectCapability = createPromiseCapability(); + + // Attach the callback that is used to request a password; + // similarly to how viewer.js handles passwords. + loadingTask.onPassword = function (updatePassword, reason) { + if (reason === PasswordResponses.NEED_PASSWORD && + !isPasswordNeededResolved) { + isPasswordNeededResolved = true; + passwordNeededCapability.resolve(); + + updatePassword('qwerty'); // Provide an incorrect password. + return; } - var loadingTask = getDocument( - buildGetDocumentParams('non-existent.pdf')); - loadingTask.promise.then(function(error) { - done.fail('shall fail loading'); - }).catch(function (error) { - expect(error instanceof MissingPDFException).toEqual(true); - loadingTask.destroy().then(done); - }); + if (reason === PasswordResponses.INCORRECT_PASSWORD && + !isPasswordIncorrectResolved) { + isPasswordIncorrectResolved = true; + passwordIncorrectCapability.resolve(); + + updatePassword('asdfasdf'); // Provide the correct password. + return; + } + // Shouldn't get here. + expect(false).toEqual(true); + }; + + var promises = [ + passwordNeededCapability.promise, + passwordIncorrectCapability.promise, + loadingTask.promise + ]; + Promise.all(promises).then(function (data) { + expect(data[2] instanceof PDFDocumentProxy).toEqual(true); + loadingTask.destroy().then(done); + }).catch(function (reason) { + done.fail(reason); }); - it('creates pdf doc from PDF file protected with user and owner password', - function (done) { - var loadingTask = getDocument(buildGetDocumentParams('pr6531_1.pdf')); + }); + it('creates pdf doc from PDF file protected with only a user password', + function (done) { + var filename = 'pr6531_2.pdf'; - var isPasswordNeededResolved = false; - var passwordNeededCapability = createPromiseCapability(); - var isPasswordIncorrectResolved = false; - var passwordIncorrectCapability = createPromiseCapability(); - - // Attach the callback that is used to request a password; - // similarly to how viewer.js handles passwords. - loadingTask.onPassword = function (updatePassword, reason) { - if (reason === PasswordResponses.NEED_PASSWORD && - !isPasswordNeededResolved) { - isPasswordNeededResolved = true; - passwordNeededCapability.resolve(); - - updatePassword('qwerty'); // Provide an incorrect password. - return; - } - if (reason === PasswordResponses.INCORRECT_PASSWORD && - !isPasswordIncorrectResolved) { - isPasswordIncorrectResolved = true; - passwordIncorrectCapability.resolve(); - - updatePassword('asdfasdf'); // Provide the correct password. - return; - } - // Shouldn't get here. - expect(false).toEqual(true); - }; - - var promises = [ - passwordNeededCapability.promise, - passwordIncorrectCapability.promise, - loadingTask.promise - ]; - Promise.all(promises).then(function (data) { - expect(data[2] instanceof PDFDocumentProxy).toEqual(true); - loadingTask.destroy().then(done); - }).catch(function (reason) { - done.fail(reason); - }); - }); - it('creates pdf doc from PDF file protected with only a user password', - function (done) { - var filename = 'pr6531_2.pdf'; - - var passwordNeededLoadingTask = getDocument( - buildGetDocumentParams(filename, { - password: '', - })); - var result1 = passwordNeededLoadingTask.promise.then(function () { - done.fail('shall fail with no password'); - return Promise.reject(new Error('loadingTask should be rejected')); - }, function (data) { - expect(data instanceof PasswordException).toEqual(true); - expect(data.code).toEqual(PasswordResponses.NEED_PASSWORD); - return passwordNeededLoadingTask.destroy(); - }); - - var passwordIncorrectLoadingTask = getDocument( - buildGetDocumentParams(filename, { - password: 'qwerty', - })); - var result2 = passwordIncorrectLoadingTask.promise.then(function () { - done.fail('shall fail with wrong password'); - return Promise.reject(new Error('loadingTask should be rejected')); - }, function (data) { - expect(data instanceof PasswordException).toEqual(true); - expect(data.code).toEqual(PasswordResponses.INCORRECT_PASSWORD); - return passwordIncorrectLoadingTask.destroy(); - }); - - var passwordAcceptedLoadingTask = getDocument( - buildGetDocumentParams(filename, { - password: 'asdfasdf', - })); - var result3 = passwordAcceptedLoadingTask.promise.then(function (data) { - expect(data instanceof PDFDocumentProxy).toEqual(true); - return passwordAcceptedLoadingTask.destroy(); - }); - Promise.all([result1, result2, result3]).then(function () { - done(); - }).catch(function (reason) { - done.fail(reason); - }); + var passwordNeededLoadingTask = getDocument( + buildGetDocumentParams(filename, { + password: '', + })); + var result1 = passwordNeededLoadingTask.promise.then(function () { + done.fail('shall fail with no password'); + return Promise.reject(new Error('loadingTask should be rejected')); + }, function (data) { + expect(data instanceof PasswordException).toEqual(true); + expect(data.code).toEqual(PasswordResponses.NEED_PASSWORD); + return passwordNeededLoadingTask.destroy(); }); - it('creates pdf doc from password protected PDF file and aborts/throws ' + - 'in the onPassword callback (issue 7806)', function (done) { - var filename = 'issue3371.pdf'; + var passwordIncorrectLoadingTask = getDocument( + buildGetDocumentParams(filename, { + password: 'qwerty', + })); + var result2 = passwordIncorrectLoadingTask.promise.then(function () { + done.fail('shall fail with wrong password'); + return Promise.reject(new Error('loadingTask should be rejected')); + }, function (data) { + expect(data instanceof PasswordException).toEqual(true); + expect(data.code).toEqual(PasswordResponses.INCORRECT_PASSWORD); + return passwordIncorrectLoadingTask.destroy(); + }); - var passwordNeededLoadingTask = getDocument( - buildGetDocumentParams(filename)); - var passwordIncorrectLoadingTask = getDocument( - buildGetDocumentParams(filename, { - password: 'qwerty', - })); + var passwordAcceptedLoadingTask = getDocument( + buildGetDocumentParams(filename, { + password: 'asdfasdf', + })); + var result3 = passwordAcceptedLoadingTask.promise.then(function (data) { + expect(data instanceof PDFDocumentProxy).toEqual(true); + return passwordAcceptedLoadingTask.destroy(); + }); + Promise.all([result1, result2, result3]).then(function () { + done(); + }).catch(function (reason) { + done.fail(reason); + }); + }); - let passwordNeededDestroyed; - passwordNeededLoadingTask.onPassword = function (callback, reason) { - if (reason === PasswordResponses.NEED_PASSWORD) { - passwordNeededDestroyed = passwordNeededLoadingTask.destroy(); - return; - } - // Shouldn't get here. - expect(false).toEqual(true); - }; - var result1 = passwordNeededLoadingTask.promise.then(function () { - done.fail('shall fail since the loadingTask should be destroyed'); - return Promise.reject(new Error('loadingTask should be rejected')); - }, function (reason) { - expect(reason instanceof PasswordException).toEqual(true); - expect(reason.code).toEqual(PasswordResponses.NEED_PASSWORD); - return passwordNeededDestroyed; - }); + it('creates pdf doc from password protected PDF file and aborts/throws ' + + 'in the onPassword callback (issue 7806)', function (done) { + var filename = 'issue3371.pdf'; - passwordIncorrectLoadingTask.onPassword = function (callback, reason) { - if (reason === PasswordResponses.INCORRECT_PASSWORD) { - throw new Error('Incorrect password'); - } - // Shouldn't get here. - expect(false).toEqual(true); - }; - var result2 = passwordIncorrectLoadingTask.promise.then(function () { - done.fail('shall fail since the onPassword callback should throw'); - return Promise.reject(new Error('loadingTask should be rejected')); - }, function (reason) { - expect(reason instanceof PasswordException).toEqual(true); - expect(reason.code).toEqual(PasswordResponses.INCORRECT_PASSWORD); - return passwordIncorrectLoadingTask.destroy(); - }); + var passwordNeededLoadingTask = getDocument( + buildGetDocumentParams(filename)); + var passwordIncorrectLoadingTask = getDocument( + buildGetDocumentParams(filename, { + password: 'qwerty', + })); - Promise.all([result1, result2]).then(function () { - done(); - }).catch(function (reason) { - done.fail(reason); - }); + let passwordNeededDestroyed; + passwordNeededLoadingTask.onPassword = function (callback, reason) { + if (reason === PasswordResponses.NEED_PASSWORD) { + passwordNeededDestroyed = passwordNeededLoadingTask.destroy(); + return; + } + // Shouldn't get here. + expect(false).toEqual(true); + }; + var result1 = passwordNeededLoadingTask.promise.then(function () { + done.fail('shall fail since the loadingTask should be destroyed'); + return Promise.reject(new Error('loadingTask should be rejected')); + }, function (reason) { + expect(reason instanceof PasswordException).toEqual(true); + expect(reason.code).toEqual(PasswordResponses.NEED_PASSWORD); + return passwordNeededDestroyed; + }); + + passwordIncorrectLoadingTask.onPassword = function (callback, reason) { + if (reason === PasswordResponses.INCORRECT_PASSWORD) { + throw new Error('Incorrect password'); + } + // Shouldn't get here. + expect(false).toEqual(true); + }; + var result2 = passwordIncorrectLoadingTask.promise.then(function () { + done.fail('shall fail since the onPassword callback should throw'); + return Promise.reject(new Error('loadingTask should be rejected')); + }, function (reason) { + expect(reason instanceof PasswordException).toEqual(true); + expect(reason.code).toEqual(PasswordResponses.INCORRECT_PASSWORD); + return passwordIncorrectLoadingTask.destroy(); + }); + + Promise.all([result1, result2]).then(function () { + done(); + }).catch(function (reason) { + done.fail(reason); }); }); }); + describe('PDFWorker', function() { if (isNodeJS()) { pending('Worker is not supported in Node.js.'); diff --git a/web/pdf_viewer.component.js b/web/pdf_viewer.component.js index de940eaed..34dc65251 100644 --- a/web/pdf_viewer.component.js +++ b/web/pdf_viewer.component.js @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/* eslint-disable no-unused-vars */ import { AnnotationLayerBuilder, DefaultAnnotationLayerFactory @@ -25,31 +26,28 @@ import { DownloadManager } from './download_manager.js'; import { GenericL10n } from './genericl10n.js'; import { PDFFindController } from './pdf_find_controller.js'; import { PDFHistory } from './pdf_history.js'; -import pdfjsLib from './pdfjs.js'; import { PDFPageView } from './pdf_page_view.js'; import { PDFSinglePageViewer } from './pdf_single_page_viewer'; import { PDFViewer } from './pdf_viewer.js'; -let { PDFJS, } = pdfjsLib; - -PDFJS.PDFViewer = PDFViewer; -PDFJS.PDFSinglePageViewer = PDFSinglePageViewer; -PDFJS.PDFPageView = PDFPageView; -PDFJS.PDFLinkService = PDFLinkService; -PDFJS.SimpleLinkService = SimpleLinkService; -PDFJS.TextLayerBuilder = TextLayerBuilder; -PDFJS.DefaultTextLayerFactory = DefaultTextLayerFactory; -PDFJS.AnnotationLayerBuilder = AnnotationLayerBuilder; -PDFJS.DefaultAnnotationLayerFactory = DefaultAnnotationLayerFactory; -PDFJS.PDFHistory = PDFHistory; -PDFJS.PDFFindController = PDFFindController; -PDFJS.EventBus = EventBus; - -PDFJS.DownloadManager = DownloadManager; -PDFJS.ProgressBar = ProgressBar; -PDFJS.GenericL10n = GenericL10n; -PDFJS.NullL10n = NullL10n; +const pdfjsVersion = PDFJSDev.eval('BUNDLE_VERSION'); +const pdfjsBuild = PDFJSDev.eval('BUNDLE_BUILD'); export { - PDFJS, + PDFViewer, + PDFSinglePageViewer, + PDFPageView, + PDFLinkService, + SimpleLinkService, + TextLayerBuilder, + DefaultTextLayerFactory, + AnnotationLayerBuilder, + DefaultAnnotationLayerFactory, + PDFHistory, + PDFFindController, + EventBus, + DownloadManager, + ProgressBar, + GenericL10n, + NullL10n, };