Merge pull request #9493 from Snuffleupagus/refactor-api-options

[api-major] Move the remaining options from, and completely remove, the global `PDFJS` object
This commit is contained in:
Tim van der Meij 2018-03-03 14:48:54 +01:00 committed by GitHub
commit c33bf800cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 966 additions and 852 deletions

View File

@ -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,
});

View File

@ -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) {

View File

@ -15,20 +15,20 @@
'use strict';
if (!PDFJS.PDFViewer || !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.
//
// PDFJS.cMapUrl = '../../node_modules/pdfjs-dist/cmaps/';
// PDFJS.cMapPacked = true;
var CMAP_URL = '../../node_modules/pdfjs-dist/cmaps/';
var CMAP_PACKED = true;
var DEFAULT_URL = '../../web/compressed.tracemonkey-pldi-09.pdf';
var PAGE_TO_VIEW = 1;
@ -37,18 +37,22 @@ var SCALE = 1.0;
var container = document.getElementById('pageContainer');
// Loading document.
PDFJS.getDocument(DEFAULT_URL).then(function (pdfDocument) {
pdfjsDistBuildPdf.getDocument({
url: DEFAULT_URL,
cMapUrl: CMAP_URL,
cMapPacked: CMAP_PACKED,
}).then(function(pdfDocument) {
// 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);

View File

@ -15,20 +15,20 @@
'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.
//
// PDFJS.cMapUrl = '../../node_modules/pdfjs-dist/cmaps/';
// PDFJS.cMapPacked = true;
var CMAP_URL = '../../node_modules/pdfjs-dist/cmaps/';
var CMAP_PACKED = true;
var DEFAULT_URL = '../../web/compressed.tracemonkey-pldi-09.pdf';
var SEARCH_FOR = ''; // try 'Mozilla';
@ -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,11 @@ container.addEventListener('pagesinit', function () {
});
// Loading document.
PDFJS.getDocument(DEFAULT_URL).then(function (pdfDocument) {
pdfjsDistBuildPdf.getDocument({
url: DEFAULT_URL,
cMapUrl: CMAP_URL,
cMapPacked: CMAP_PACKED,
}).then(function(pdfDocument) {
// Document loaded, specifying document for the viewer and
// the (optional) linkService.
pdfViewer.setDocument(pdfDocument);

View File

@ -15,20 +15,20 @@
'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.
//
// PDFJS.cMapUrl = '../../node_modules/pdfjs-dist/cmaps/';
// PDFJS.cMapPacked = true;
var CMAP_URL = '../../node_modules/pdfjs-dist/cmaps/';
var CMAP_PACKED = true;
var DEFAULT_URL = '../../web/compressed.tracemonkey-pldi-09.pdf';
var SEARCH_FOR = ''; // try 'Mozilla';
@ -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,11 @@ container.addEventListener('pagesinit', function () {
});
// Loading document.
PDFJS.getDocument(DEFAULT_URL).then(function (pdfDocument) {
pdfjsDistBuildPdf.getDocument({
url: DEFAULT_URL,
cMapUrl: CMAP_URL,
cMapPacked: CMAP_PACKED,
}).then(function(pdfDocument) {
// Document loaded, specifying document for the viewer and
// the (optional) linkService.
pdfSinglePageViewer.setDocument(pdfDocument);

View File

@ -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
//

View File

@ -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;

View File

@ -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;

View File

@ -12,22 +12,21 @@
* 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;
var TEXT_LAYER_MODE = 0; // DISABLE
PDFJS.maxImageSize = 1024 * 1024;
PDFJS.cMapUrl = '../../node_modules/pdfjs-dist/cmaps/';
PDFJS.cMapPacked = true;
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,12 @@ var PDFViewerApplication = {
this.setTitleUsingUrl(url);
// Loading document.
var loadingTask = PDFJS.getDocument(url);
var loadingTask = pdfjsDistBuildPdf.getDocument({
url: url,
maxImageSize: MAX_IMAGE_SIZE,
cMapUrl: CMAP_URL,
cMapPacked: CMAP_PACKED,
});
this.pdfLoadingTask = loadingTask;
loadingTask.onProgress = function (progressData) {
@ -83,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 {
@ -133,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) {
@ -161,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')) {
@ -192,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) {
@ -290,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,
@ -306,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);

View File

@ -38,29 +38,31 @@ function renderDocument(pdf, svgLib) {
Promise.all([System.import('pdfjs/display/api'),
System.import('pdfjs/display/svg'),
System.import('pdfjs/display/global'),
System.import('pdfjs/display/worker_options'),
System.import('pdfjs/display/network'),
System.resolve('pdfjs/worker_loader')])
.then(function (modules) {
var api = modules[0];
var svg = modules[1];
var global = modules[2];
var GlobalWorkerOptions = modules[3].GlobalWorkerOptions;
var network = modules[4];
var GlobalWorkerOptions = modules[2].GlobalWorkerOptions;
var network = modules[3];
api.setPDFNetworkStreamFactory((params) => {
return new network.PDFNetworkStream(params);
});
// In production, change this to point to the built `pdf.worker.js` file.
GlobalWorkerOptions.workerSrc = modules[5];
GlobalWorkerOptions.workerSrc = modules[4];
// In production, change this to point to where the cMaps are placed.
global.PDFJS.cMapUrl = '../../external/bcmaps/';
global.PDFJS.cMapPacked = true;
var CMAP_URL = '../../external/bcmaps/';
var CMAP_PACKED = true;
// Fetch the PDF document from the URL using promises.
api.getDocument(url).then(function (doc) {
api.getDocument({
url: url,
cMapUrl: CMAP_URL,
cMapPacked: CMAP_PACKED,
}).then(function(doc) {
renderDocument(doc, svg);
});
});

View File

@ -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;

View File

@ -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'
];

View File

@ -614,7 +614,7 @@ var WorkerMessageHandler = {
var evaluatorOptions = {
forceDataSchema: data.disableCreateObjectURL,
maxImageSize: data.maxImageSize === undefined ? -1 : data.maxImageSize,
maxImageSize: data.maxImageSize,
disableFontFace: data.disableFontFace,
nativeImageDecoderSupport: data.nativeImageDecoderSupport,
ignoreErrors: data.ignoreErrors,

View File

@ -18,14 +18,15 @@ import {
assert, createPromiseCapability, getVerbosityLevel, info, InvalidPDFException,
isArrayBuffer, isNum, isSameOrigin, MessageHandler, MissingPDFException,
NativeImageDecoding, PageViewport, PasswordException, setVerbosityLevel,
stringToBytes, UnexpectedResponseException, UnknownErrorException,
shadow, stringToBytes, UnexpectedResponseException, UnknownErrorException,
unreachable, Util, warn
} from '../shared/util';
import {
DOMCanvasFactory, DOMCMapReaderFactory, DummyStatTimer, getDefaultSetting,
DOMCanvasFactory, DOMCMapReaderFactory, DummyStatTimer,
RenderingCancelledException, StatTimer
} from './dom_utils';
import { FontFaceObject, FontLoader } from './font_loader';
import { apiCompatibilityParams } from './api_compatibility';
import { CanvasGraphics } from './canvas';
import globalScope from '../shared/global_scope';
import { GlobalWorkerOptions } from './worker_options';
@ -142,6 +143,10 @@ function setPDFNetworkStreamFactory(pdfNetworkStreamFactory) {
* with limited image support through stubs (useful for SVG conversion),
* and 'none' where JPEG images will be decoded entirely by PDF.js.
* The default value is 'decode'.
* @property {string} cMapUrl - (optional) The URL where the predefined
* Adobe CMaps are located. Include trailing slash.
* @property {boolean} cMapPacked - (optional) Specifies if the Adobe CMaps are
* binary packed.
* @property {Object} CMapReaderFactory - (optional) The factory that will be
* used when reading built-in CMap files. Providing a custom factory is useful
* for environments without `XMLHttpRequest` support, such as e.g. Node.js.
@ -150,6 +155,34 @@ function setPDFNetworkStreamFactory(pdfNetworkStreamFactory) {
* `getOperatorList`, `getTextContent`, and `RenderTask`, when the associated
* PDF data cannot be successfully parsed, instead of attempting to recover
* whatever possible of the data. The default value is `false`.
* @property {number} maxImageSize - (optional) The maximum allowed image size
* in total pixels, i.e. width * height. Images above this value will not be
* rendered. Use -1 for no limit, which is also the default value.
* @property {boolean} isEvalSupported - (optional) Determines if we can eval
* strings as JS. Primarily used to improve performance of font rendering,
* and when parsing PDF functions. The default value is `true`.
* @property {boolean} disableFontFace - (optional) By default fonts are
* converted to OpenType fonts and loaded via font face rules. If disabled,
* fonts will be rendered using a built-in font renderer that constructs the
* glyphs with primitive path commands. The default value is `false`.
* @property {boolean} disableRange - (optional) Disable range request loading
* of PDF files. When enabled, and if the server supports partial content
* requests, then the PDF will be fetched in chunks.
* The default value is `false`.
* @property {boolean} disableStream - (optional) Disable streaming of PDF file
* data. By default PDF.js attempts to load PDFs in chunks.
* The default value is `false`.
* @property {boolean} disableAutoFetch - (optional) Disable pre-fetching of PDF
* file data. When range requests are enabled PDF.js will automatically keep
* fetching more data even if it isn't needed to display the current page.
* The default value is `false`.
* NOTE: It is also necessary to disable streaming, see above,
* in order for disabling of pre-fetching to work correctly.
* @property {boolean} disableCreateObjectURL - (optional) Disable the use of
* `URL.createObjectURL`, for compatibility with older browsers.
* The default value is `false`.
* @property {boolean} pdfBug - (optional) Enables special hooks for debugging
* PDF.js (see `web/debugger.js`). The default value is `false`.
*/
/**
@ -195,10 +228,10 @@ function getDocument(src) {
source = src;
}
var params = {};
let params = Object.create(null);
var rangeTransport = null;
let worker = null;
var CMapReaderFactory = DOMCMapReaderFactory;
let CMapReaderFactory = DOMCMapReaderFactory;
for (var key in source) {
if (key === 'url' && typeof window !== 'undefined') {
@ -236,12 +269,36 @@ function getDocument(src) {
params.rangeChunkSize = params.rangeChunkSize || DEFAULT_RANGE_CHUNK_SIZE;
params.ignoreErrors = params.stopAtErrors !== true;
params.pdfBug = params.pdfBug === true;
const nativeImageDecoderValues = Object.values(NativeImageDecoding);
const NativeImageDecoderValues = Object.values(NativeImageDecoding);
if (params.nativeImageDecoderSupport === undefined ||
!nativeImageDecoderValues.includes(params.nativeImageDecoderSupport)) {
!NativeImageDecoderValues.includes(params.nativeImageDecoderSupport)) {
params.nativeImageDecoderSupport = NativeImageDecoding.DECODE;
}
if (!Number.isInteger(params.maxImageSize)) {
params.maxImageSize = -1;
}
if (typeof params.isEvalSupported !== 'boolean') {
params.isEvalSupported = true;
}
if (typeof params.disableFontFace !== 'boolean') {
params.disableFontFace = false;
}
if (typeof params.disableRange !== 'boolean') {
params.disableRange = apiCompatibilityParams.disableRange || false;
}
if (typeof params.disableStream !== 'boolean') {
params.disableStream = apiCompatibilityParams.disableStream || false;
}
if (typeof params.disableAutoFetch !== 'boolean') {
params.disableAutoFetch = false;
}
if (typeof params.disableCreateObjectURL !== 'boolean') {
params.disableCreateObjectURL =
apiCompatibilityParams.disableCreateObjectURL || false;
}
// Set the main-thread verbosity level.
setVerbosityLevel(params.verbosity);
@ -275,15 +332,28 @@ function getDocument(src) {
let networkStream;
if (rangeTransport) {
networkStream = new PDFDataTransportStream(params, rangeTransport);
networkStream = new PDFDataTransportStream({
length: params.length,
initialData: params.initialData,
disableRange: params.disableRange,
disableStream: params.disableStream,
}, rangeTransport);
} else if (!params.data) {
networkStream = createPDFNetworkStream(params);
networkStream = createPDFNetworkStream({
url: params.url,
length: params.length,
httpHeaders: params.httpHeaders,
withCredentials: params.withCredentials,
rangeChunkSize: params.rangeChunkSize,
disableRange: params.disableRange,
disableStream: params.disableStream,
});
}
var messageHandler = new MessageHandler(docId, workerId, worker.port);
messageHandler.postMessageTransfers = worker.postMessageTransfers;
var transport = new WorkerTransport(messageHandler, task, networkStream,
CMapReaderFactory);
params, CMapReaderFactory);
task._transport = transport;
messageHandler.send('Ready', null);
});
@ -306,19 +376,15 @@ function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
if (worker.destroyed) {
return Promise.reject(new Error('Worker was destroyed'));
}
let apiVersion =
typeof PDFJSDev !== 'undefined' ? PDFJSDev.eval('BUNDLE_VERSION') : null;
source.disableRange = getDefaultSetting('disableRange');
source.disableAutoFetch = getDefaultSetting('disableAutoFetch');
source.disableStream = getDefaultSetting('disableStream');
if (pdfDataRangeTransport) {
source.length = pdfDataRangeTransport.length;
source.initialData = pdfDataRangeTransport.initialData;
}
return worker.messageHandler.sendWithPromise('GetDocRequest', {
docId,
apiVersion,
apiVersion: (typeof PDFJSDev !== 'undefined' ?
PDFJSDev.eval('BUNDLE_VERSION') : null),
source: {
data: source.data,
url: source.url,
@ -327,14 +393,14 @@ function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
rangeChunkSize: source.rangeChunkSize,
length: source.length,
},
maxImageSize: getDefaultSetting('maxImageSize'),
disableFontFace: getDefaultSetting('disableFontFace'),
disableCreateObjectURL: getDefaultSetting('disableCreateObjectURL'),
maxImageSize: source.maxImageSize,
disableFontFace: source.disableFontFace,
disableCreateObjectURL: source.disableCreateObjectURL,
postMessageTransfers: worker.postMessageTransfers,
docBaseUrl: source.docBaseUrl,
nativeImageDecoderSupport: source.nativeImageDecoderSupport,
ignoreErrors: source.ignoreErrors,
isEvalSupported: getDefaultSetting('isEvalSupported'),
isEvalSupported: source.isEvalSupported,
}).then(function (workerId) {
if (worker.destroyed) {
throw new Error('Worker was destroyed');
@ -660,6 +726,10 @@ var PDFDocumentProxy = (function PDFDocumentProxyClosure() {
destroy: function PDFDocumentProxy_destroy() {
return this.loadingTask.destroy();
},
get loadingParams() {
return this.transport.loadingParams;
},
};
return PDFDocumentProxy;
})();
@ -757,12 +827,12 @@ var PDFDocumentProxy = (function PDFDocumentProxyClosure() {
* @alias PDFPageProxy
*/
var PDFPageProxy = (function PDFPageProxyClosure() {
function PDFPageProxy(pageIndex, pageInfo, transport) {
function PDFPageProxy(pageIndex, pageInfo, transport, pdfBug = false) {
this.pageIndex = pageIndex;
this.pageInfo = pageInfo;
this.transport = transport;
this._stats = (getDefaultSetting('pdfBug') ?
new StatTimer() : DummyStatTimer);
this._stats = (pdfBug ? new StatTimer() : DummyStatTimer);
this._pdfBug = pdfBug;
this.commonObjs = transport.commonObjs;
this.objs = new PDFObjects();
this.cleanupAfterRender = false;
@ -899,7 +969,8 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
intentState.operatorList,
this.pageNumber,
canvasFactory,
webGLContext);
webGLContext,
this._pdfBug);
internalRenderTask.useRequestAnimationFrame = renderingIntent !== 'print';
if (!intentState.renderTasks) {
intentState.renderTasks = [];
@ -1544,14 +1615,15 @@ var PDFWorker = (function PDFWorkerClosure() {
*/
var WorkerTransport = (function WorkerTransportClosure() {
function WorkerTransport(messageHandler, loadingTask, networkStream,
CMapReaderFactory) {
params, CMapReaderFactory) {
this.messageHandler = messageHandler;
this.loadingTask = loadingTask;
this.commonObjs = new PDFObjects();
this.fontLoader = new FontLoader(loadingTask.docId);
this._params = params;
this.CMapReaderFactory = new CMapReaderFactory({
baseUrl: getDefaultSetting('cMapUrl'),
isCompressed: getDefaultSetting('cMapPacked'),
baseUrl: params.cMapUrl,
isCompressed: params.cMapPacked,
});
this.destroyed = false;
@ -1795,6 +1867,7 @@ var WorkerTransport = (function WorkerTransportClosure() {
switch (type) {
case 'Font':
var exportedData = data[2];
let params = this._params;
if ('error' in exportedData) {
var exportedError = exportedData.error;
@ -1803,8 +1876,8 @@ var WorkerTransport = (function WorkerTransportClosure() {
break;
}
var fontRegistry = null;
if (getDefaultSetting('pdfBug') && globalScope.FontInspector &&
globalScope['FontInspector'].enabled) {
if (params.pdfBug && globalScope.FontInspector &&
globalScope.FontInspector.enabled) {
fontRegistry = {
registerFont(font, url) {
globalScope['FontInspector'].fontAdded(font, url);
@ -1812,8 +1885,8 @@ var WorkerTransport = (function WorkerTransportClosure() {
};
}
var font = new FontFaceObject(exportedData, {
isEvalSupported: getDefaultSetting('isEvalSupported'),
disableFontFace: getDefaultSetting('disableFontFace'),
isEvalSupported: params.isEvalSupported,
disableFontFace: params.disableFontFace,
fontRegistry,
});
var fontReady = (fontObjs) => {
@ -2010,7 +2083,8 @@ var WorkerTransport = (function WorkerTransportClosure() {
if (this.destroyed) {
throw new Error('Transport destroyed');
}
var page = new PDFPageProxy(pageIndex, pageInfo, this);
let page = new PDFPageProxy(pageIndex, pageInfo, this,
this._params.pdfBug);
this.pageCache[pageIndex] = page;
return page;
});
@ -2091,6 +2165,16 @@ var WorkerTransport = (function WorkerTransportClosure() {
this.fontLoader.clear();
});
},
get loadingParams() {
let params = this._params;
return shadow(this, 'loadingParams', {
disableRange: params.disableRange,
disableStream: params.disableStream,
disableAutoFetch: params.disableAutoFetch,
disableCreateObjectURL: params.disableCreateObjectURL,
});
},
};
return WorkerTransport;
@ -2260,7 +2344,8 @@ var InternalRenderTask = (function InternalRenderTaskClosure() {
let canvasInRendering = new WeakMap();
function InternalRenderTask(callback, params, objs, commonObjs, operatorList,
pageNumber, canvasFactory, webGLContext) {
pageNumber, canvasFactory, webGLContext,
pdfBug = false) {
this.callback = callback;
this.params = params;
this.objs = objs;
@ -2270,6 +2355,7 @@ var InternalRenderTask = (function InternalRenderTaskClosure() {
this.pageNumber = pageNumber;
this.canvasFactory = canvasFactory;
this.webGLContext = webGLContext;
this._pdfBug = pdfBug;
this.running = false;
this.graphicsReadyCallback = null;
@ -2303,7 +2389,7 @@ var InternalRenderTask = (function InternalRenderTaskClosure() {
if (this.cancelled) {
return;
}
if (getDefaultSetting('pdfBug') && globalScope.StepperManager &&
if (this._pdfBug && globalScope.StepperManager &&
globalScope.StepperManager.enabled) {
this.stepper = globalScope.StepperManager.create(this.pageNumber - 1);
this.stepper.init(this.operatorList);

View File

@ -0,0 +1,50 @@
/* Copyright 2018 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.
*/
let compatibilityParams = Object.create(null);
if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {
const userAgent =
(typeof navigator !== 'undefined' && navigator.userAgent) || '';
const isIE = /Trident/.test(userAgent);
const isIOS = /\b(iPad|iPhone|iPod)(?=;)/.test(userAgent);
const isIOSChrome = /CriOS/.test(userAgent);
const isSafari = /Safari\//.test(userAgent) &&
!/(Chrome\/|Android\s)/.test(userAgent);
// Checks if possible to use URL.createObjectURL()
// Support: IE, Chrome on iOS
(function checkOnBlobSupport() {
// Sometimes IE and Chrome on iOS losing the data created with
// createObjectURL(), see issues #3977 and #8081.
if (isIE || isIOSChrome) {
compatibilityParams.disableCreateObjectURL = true;
}
})();
// Support: Safari 6.0+, iOS
(function checkRangeRequests() {
// Safari has issues with cached range requests, see issue #3260.
// Last tested with version 6.0.4.
if (isSafari || isIOS) {
compatibilityParams.disableRange = true;
compatibilityParams.disableStream = true;
}
})();
}
const apiCompatibilityParams = Object.freeze(compatibilityParams);
export {
apiCompatibilityParams,
};

View File

@ -17,7 +17,6 @@ import {
assert, CMapCompressionType, removeNullCharacters, stringToBytes,
unreachable, warn
} from '../shared/util';
import globalScope from '../shared/global_scope';
const DEFAULT_LINK_REL = 'noopener noreferrer nofollow';
const SVG_NS = 'http://www.w3.org/2000/svg';
@ -69,8 +68,9 @@ class DOMCMapReaderFactory {
fetch({ name, }) {
if (!this.baseUrl) {
return Promise.reject(new Error('CMap baseUrl must be specified, ' +
'see "PDFJS.cMapUrl" (and also "PDFJS.cMapPacked").'));
return Promise.reject(new Error(
'The CMap "baseUrl" parameter must be specified, ensure that ' +
'the "cMapUrl" and "cMapPacked" API parameters are provided.'));
}
if (!name) {
return Promise.reject(new Error('CMap name must be specified.'));
@ -328,36 +328,6 @@ function getFilenameFromUrl(url) {
return url.substring(url.lastIndexOf('/', end) + 1, end);
}
function getDefaultSetting(id) {
// The list of the settings and their default is maintained for backward
// compatibility and shall not be extended or modified. See also global.js.
var globalSettings = globalScope.PDFJS;
switch (id) {
case 'pdfBug':
return globalSettings ? globalSettings.pdfBug : false;
case 'disableAutoFetch':
return globalSettings ? globalSettings.disableAutoFetch : false;
case 'disableStream':
return globalSettings ? globalSettings.disableStream : false;
case 'disableRange':
return globalSettings ? globalSettings.disableRange : false;
case 'disableFontFace':
return globalSettings ? globalSettings.disableFontFace : false;
case 'disableCreateObjectURL':
return globalSettings ? globalSettings.disableCreateObjectURL : false;
case 'cMapUrl':
return globalSettings ? globalSettings.cMapUrl : null;
case 'cMapPacked':
return globalSettings ? globalSettings.cMapPacked : false;
case 'maxImageSize':
return globalSettings ? globalSettings.maxImageSize : -1;
case 'isEvalSupported':
return globalSettings ? globalSettings.isEvalSupported : true;
default:
throw new Error('Unknown default setting: ' + id);
}
}
class StatTimer {
constructor(enable = true) {
this.enabled = !!enable;
@ -437,7 +407,6 @@ export {
addLinkAttributes,
getFilenameFromUrl,
LinkTarget,
getDefaultSetting,
DEFAULT_LINK_REL,
DOMCanvasFactory,
DOMCMapReaderFactory,

View File

@ -336,13 +336,17 @@ var IsEvalSupportedCached = {
};
var FontFaceObject = (function FontFaceObjectClosure() {
function FontFaceObject(translatedData, options) {
function FontFaceObject(translatedData, { isEvalSupported = true,
disableFontFace = false,
fontRegistry = null, }) {
this.compiledGlyphs = Object.create(null);
// importing translated data
for (var i in translatedData) {
this[i] = translatedData[i];
}
this.options = options;
this.isEvalSupported = isEvalSupported !== false;
this.disableFontFace = disableFontFace === true;
this.fontRegistry = fontRegistry;
}
FontFaceObject.prototype = {
createNativeFontFace: function FontFaceObject_createNativeFontFace() {
@ -350,30 +354,20 @@ var FontFaceObject = (function FontFaceObjectClosure() {
throw new Error('Not implemented: createNativeFontFace');
}
if (!this.data) {
return null;
}
if (this.options.disableFontFace) {
this.disableFontFace = true;
if (!this.data || this.disableFontFace) {
return null;
}
var nativeFontFace = new FontFace(this.loadedName, this.data, {});
if (this.options.fontRegistry) {
this.options.fontRegistry.registerFont(this);
if (this.fontRegistry) {
this.fontRegistry.registerFont(this);
}
return nativeFontFace;
},
createFontFaceRule: function FontFaceObject_createFontFaceRule() {
if (!this.data) {
return null;
}
if (this.options.disableFontFace) {
this.disableFontFace = true;
if (!this.data || this.disableFontFace) {
return null;
}
@ -384,8 +378,8 @@ var FontFaceObject = (function FontFaceObjectClosure() {
var url = ('url(data:' + this.mimetype + ';base64,' + btoa(data) + ');');
var rule = '@font-face { font-family:"' + fontName + '";src:' + url + '}';
if (this.options.fontRegistry) {
this.options.fontRegistry.registerFont(this, url);
if (this.fontRegistry) {
this.fontRegistry.registerFont(this, url);
}
return rule;
@ -398,7 +392,7 @@ var FontFaceObject = (function FontFaceObjectClosure() {
var current, i, len;
// If we can, compile cmds into JS for MAXIMUM SPEED
if (this.options.isEvalSupported && IsEvalSupportedCached.value) {
if (this.isEvalSupported && IsEvalSupportedCached.value) {
var args, js = '';
for (i = 0, len = cmds.length; i < len; i++) {
current = cmds[i];

View File

@ -1,188 +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, createObjectURL, createPromiseCapability, InvalidPDFException,
isLittleEndian, MissingPDFException, OPS, PageViewport, PasswordException,
PasswordResponses, removeNullCharacters, shadow, UnexpectedResponseException,
UnknownErrorException, UNSUPPORTED_FEATURES, Util
} from '../shared/util';
import { DEFAULT_LINK_REL, getFilenameFromUrl, LinkTarget } from './dom_utils';
import {
getDocument, LoopbackPort, PDFDataRangeTransport, PDFWorker
} from './api';
import { AnnotationLayer } from './annotation_layer';
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.pdfBug = false;
PDFJS.OPS = OPS;
PDFJS.UNSUPPORTED_FEATURES = UNSUPPORTED_FEATURES;
PDFJS.shadow = shadow;
PDFJS.createBlob = createBlob;
PDFJS.createObjectURL = function PDFJS_createObjectURL(data, contentType) {
return createObjectURL(data, contentType, PDFJS.disableCreateObjectURL);
};
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;
/**
* The maximum allowed image size in total pixels e.g. width * height. Images
* above this value will not be drawn. Use -1 for no limit.
* @var {number}
*/
PDFJS.maxImageSize = (PDFJS.maxImageSize === undefined ?
-1 : PDFJS.maxImageSize);
/**
* The url of where the predefined Adobe CMaps are located. Include trailing
* slash.
* @var {string}
*/
PDFJS.cMapUrl = (PDFJS.cMapUrl === undefined ? null : PDFJS.cMapUrl);
/**
* Specifies if CMaps are binary packed.
* @var {boolean}
*/
PDFJS.cMapPacked = PDFJS.cMapPacked === undefined ? false : PDFJS.cMapPacked;
/**
* By default fonts are converted to OpenType fonts and loaded via font face
* rules. If disabled, the font will be rendered using a built in font
* renderer that constructs the glyphs with primitive path commands.
* @var {boolean}
*/
PDFJS.disableFontFace = (PDFJS.disableFontFace === undefined ?
false : PDFJS.disableFontFace);
/**
* Disable range request loading of PDF files. When enabled and if the server
* supports partial content requests then the PDF will be fetched in chunks.
* Enabled (false) by default.
* @var {boolean}
*/
PDFJS.disableRange = (PDFJS.disableRange === undefined ?
false : PDFJS.disableRange);
/**
* Disable streaming of PDF file data. By default PDF.js attempts to load PDF
* in chunks. This default behavior can be disabled.
* @var {boolean}
*/
PDFJS.disableStream = (PDFJS.disableStream === undefined ?
false : PDFJS.disableStream);
/**
* Disable pre-fetching of PDF file data. When range requests are enabled
* PDF.js will automatically keep fetching more data even if it isn't needed
* to display the current page. This default behavior can be disabled.
*
* NOTE: It is also necessary to disable streaming, see above,
* in order for disabling of pre-fetching to work correctly.
* @var {boolean}
*/
PDFJS.disableAutoFetch = (PDFJS.disableAutoFetch === undefined ?
false : PDFJS.disableAutoFetch);
/**
* Enables special hooks for debugging PDF.js.
* @var {boolean}
*/
PDFJS.pdfBug = (PDFJS.pdfBug === undefined ? false : PDFJS.pdfBug);
/**
* Disables URL.createObjectURL usage.
* @var {boolean}
*/
PDFJS.disableCreateObjectURL = (PDFJS.disableCreateObjectURL === undefined ?
false : PDFJS.disableCreateObjectURL);
/**
* Specifies the |target| attribute for external links.
* The constants from {LinkTarget} should be used:
* - NONE [default]
* - SELF
* - BLANK
* - PARENT
* - TOP
* @var {number}
*/
PDFJS.externalLinkTarget = (PDFJS.externalLinkTarget === undefined ?
LinkTarget.NONE : PDFJS.externalLinkTarget);
/**
* Specifies the |rel| attribute for external links. Defaults to stripping
* the referrer.
* @var {string}
*/
PDFJS.externalLinkRel = (PDFJS.externalLinkRel === undefined ?
DEFAULT_LINK_REL : PDFJS.externalLinkRel);
/**
* Determines if we can eval strings as JS. Primarily used to improve
* performance for font rendering.
* @var {boolean}
*/
PDFJS.isEvalSupported = (PDFJS.isEvalSupported === undefined ?
true : PDFJS.isEvalSupported);
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,
};

View File

@ -14,7 +14,7 @@
*/
import { AbortException, createPromiseCapability, Util } from '../shared/util';
import { getDefaultSetting } from './dom_utils';
import globalScope from '../shared/global_scope';
/**
* Text layer render parameters.
@ -107,11 +107,9 @@ var renderTextLayer = (function renderTextLayerClosure() {
textDiv.setAttribute('style', textDivProperties.style);
textDiv.textContent = geom.str;
// |fontName| is only used by the Font Inspector. This test will succeed
// when e.g. the Font Inspector is off but the Stepper is on, but it's
// not worth the effort to do a more accurate test. We only use `dataset`
// here to make the font name available for the debugger.
if (getDefaultSetting('pdfBug')) {
// `fontName` is only used by the FontInspector, and we only use `dataset`
// here to make the font name available in the debugger.
if (task._fontInspectorEnabled) {
textDiv.dataset.fontName = geom.fontName;
}
if (angle !== 0) {
@ -479,6 +477,8 @@ var renderTextLayer = (function renderTextLayerClosure() {
this._textDivs = textDivs || [];
this._textContentItemsStr = textContentItemsStr || [];
this._enhanceTextSelection = !!enhanceTextSelection;
this._fontInspectorEnabled = !!(globalScope.FontInspector &&
globalScope.FontInspector.enabled);
this._reader = null;
this._layoutTextLastFontSize = null;

View File

@ -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

View File

@ -22,13 +22,13 @@ 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');
var pdfjsDisplayDOMUtils = require('./display/dom_utils.js');
var pdfjsDisplaySVG = require('./display/svg.js');
let pdfjsDisplayWorkerOptions = require('./display/worker_options.js');
let pdfjsDisplayAPICompatibility = require('./display/api_compatibility.js');
if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {
const isNodeJS = require('./shared/is_node.js');
@ -65,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;
@ -90,9 +89,12 @@ 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;
exports.LinkTarget = pdfjsDisplayDOMUtils.LinkTarget;
exports.addLinkAttributes = pdfjsDisplayDOMUtils.addLinkAttributes;
exports.GlobalWorkerOptions = pdfjsDisplayWorkerOptions.GlobalWorkerOptions;
exports.apiCompatibilityParams =
pdfjsDisplayAPICompatibility.apiCompatibilityParams;

View File

@ -13,38 +13,25 @@
* 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');
var userAgent = (typeof navigator !== 'undefined' && navigator.userAgent) || '';
var isIOSChrome = userAgent.indexOf('CriOS') >= 0;
var isIE = userAgent.indexOf('Trident') >= 0;
var isIOS = /\b(iPad|iPhone|iPod)(?=;)/.test(userAgent);
var isSafari = /Safari\//.test(userAgent) &&
!/(Chrome\/|Android\s)/.test(userAgent);
var 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;
const hasDOM = typeof window === 'object' && typeof document === 'object';
// Support: Node.js
(function checkNodeBtoa() {
@ -68,27 +55,6 @@ PDFJS.compatibilityChecked = true;
};
})();
// Checks if possible to use URL.createObjectURL()
// Support: IE, Chrome on iOS
(function checkOnBlobSupport() {
// sometimes IE and Chrome on iOS loosing the data created with
// createObjectURL(), see #3977 and #8081
if (isIE || isIOSChrome) {
PDFJS.disableCreateObjectURL = true;
}
})();
// Support: Safari 6.0+, iOS
(function checkRangeRequests() {
// Safari has issues with cached range requests see:
// https://github.com/mozilla/pdf.js/issues/3260
// Last tested with version 6.0.4.
if (isSafari || isIOS) {
PDFJS.disableRange = true;
PDFJS.disableStream = true;
}
})();
// Provides document.currentScript support
// Support: IE, Chrome<29.
(function checkCurrentScript() {

View File

@ -12,12 +12,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* globals PDFJS, pdfjsDistBuildPdf */
/* globals pdfjsDistBuildPdf, pdfjsDistWebPdfViewer */
'use strict';
const WAITING_TIME = 100; // ms
const PDF_TO_CSS_UNITS = 96.0 / 72.0;
const CMAP_URL = '../external/bcmaps/';
const CMAP_PACKED = true;
const IMAGE_RESOURCES_PATH = '/web/images/';
const WORKER_SRC = '../build/generic/build/pdf.worker.js';
@ -67,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,
@ -202,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');
@ -269,11 +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;
PDFJS.cMapPacked = true;
PDFJS.cMapUrl = '../external/bcmaps/';
PDFJS.pdfBug = true;
pdfjsDistBuildPdf.GlobalWorkerOptions.workerSrc = WORKER_SRC;
// Set the passed options
this.inflight = options.inflight;
@ -359,13 +357,16 @@ var Driver = (function DriverClosure() { // eslint-disable-line no-unused-vars
this._log('Loading file "' + task.file + '"\n');
let absoluteUrl = new URL(task.file, window.location).href;
PDFJS.disableRange = task.disableRange;
PDFJS.disableAutoFetch = !task.enableAutoFetch;
try {
PDFJS.getDocument({
pdfjsDistBuildPdf.getDocument({
url: absoluteUrl,
password: task.password,
nativeImageDecoderSupport: task.nativeImageDecoderSupport,
cMapUrl: CMAP_URL,
cMapPacked: CMAP_PACKED,
disableRange: task.disableRange,
disableAutoFetch: !task.enableAutoFetch,
pdfBug: true,
}).then((doc) => {
task.pdfDoc = doc;
this._nextPage(task, failure);

View File

@ -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.');

View File

@ -281,8 +281,9 @@ describe('cmap', function() {
done.fail('No CMap should be loaded');
}, function (reason) {
expect(reason instanceof Error).toEqual(true);
expect(reason.message).toEqual('CMap baseUrl must be specified, ' +
'see "PDFJS.cMapUrl" (and also "PDFJS.cMapPacked").');
expect(reason.message).toEqual(
'The CMap "baseUrl" parameter must be specified, ensure that ' +
'the "cMapUrl" and "cMapPacked" API parameters are provided.');
done();
});
});

View File

@ -51,8 +51,9 @@ class NodeCMapReaderFactory {
fetch({ name, }) {
if (!this.baseUrl) {
return Promise.reject(new Error('CMap baseUrl must be specified, ' +
'see "PDFJS.cMapUrl" (and also "PDFJS.cMapPacked").'));
return Promise.reject(new Error(
'The CMap "baseUrl" parameter must be specified, ensure that ' +
'the "cMapUrl" and "cMapPacked" API parameters are provided.'));
}
if (!name) {
return Promise.reject(new Error('CMap name must be specified.'));

View File

@ -22,12 +22,13 @@ import {
} from './ui_utils';
import {
build, createBlob, getDocument, getFilenameFromUrl, GlobalWorkerOptions,
InvalidPDFException, LinkTarget, MissingPDFException, OPS, PDFJS, PDFWorker,
shadow, UnexpectedResponseException, UNSUPPORTED_FEATURES, version
InvalidPDFException, LinkTarget, MissingPDFException, OPS, PDFWorker, shadow,
UnexpectedResponseException, UNSUPPORTED_FEATURES, version
} from 'pdfjs-lib';
import { CursorTool, PDFCursorTools } from './pdf_cursor_tools';
import { PDFRenderingQueue, RenderingStates } from './pdf_rendering_queue';
import { PDFSidebar, SidebarView } from './pdf_sidebar';
import { AppOptions } from './app_options';
import { getGlobalEventBus } from './dom_events';
import { OverlayManager } from './overlay_manager';
import { PasswordPrompt } from './password_prompt';
@ -44,39 +45,23 @@ import { PDFThumbnailViewer } from './pdf_thumbnail_viewer';
import { PDFViewer } from './pdf_viewer';
import { SecondaryToolbar } from './secondary_toolbar';
import { Toolbar } from './toolbar';
import { viewerCompatibilityParams } from './viewer_compatibility';
import { ViewHistory } from './view_history';
const DEFAULT_SCALE_DELTA = 1.1;
const DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT = 5000;
function configure(PDFJS) {
PDFJS.imageResourcesPath = './images/';
if (typeof PDFJSDev !== 'undefined' &&
PDFJSDev.test('FIREFOX || MOZCENTRAL || GENERIC || CHROME')) {
GlobalWorkerOptions.workerSrc = '../build/pdf.worker.js';
}
if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) {
PDFJS.cMapUrl = '../external/bcmaps/';
GlobalWorkerOptions.workerSrc = '../src/worker_loader.js';
} else {
PDFJS.cMapUrl = '../web/cmaps/';
}
PDFJS.cMapPacked = true;
}
const DefaultExternalServices = {
updateFindControlState(data) {},
initPassiveLoading(callbacks) {},
fallback(data, callback) {},
reportTelemetry(data) {},
createDownloadManager() {
createDownloadManager(options) {
throw new Error('Not implemented: createDownloadManager');
},
createPreferences() {
throw new Error('Not implemented: createPreferences');
},
createL10n() {
createL10n(options) {
throw new Error('Not implemented: createL10n');
},
supportsIntegratedFind: false,
@ -138,19 +123,6 @@ let PDFViewerApplication = {
l10n: null,
isInitialViewSet: false,
downloadComplete: false,
viewerPrefs: {
enableWebGL: false,
sidebarViewOnLoad: SidebarView.NONE,
pdfBugEnabled: false,
showPreviousViewOnLoad: true,
defaultZoomValue: '',
disablePageMode: false,
disablePageLabels: false,
renderer: 'canvas',
textLayerMode: TextLayerMode.ENABLE,
renderInteractiveForms: false,
enablePrintAutoRotate: false,
},
isViewerEmbedded: (window.parent !== window),
url: '',
baseUrl: '',
@ -161,8 +133,6 @@ let PDFViewerApplication = {
// Called once when the document is loaded.
initialize(appConfig) {
this.preferences = this.externalServices.createPreferences();
configure(PDFJS);
this.appConfig = appConfig;
return this._readPreferences().then(() => {
@ -186,10 +156,10 @@ let PDFViewerApplication = {
});
if (this.isViewerEmbedded &&
PDFJS.externalLinkTarget === LinkTarget.NONE) {
AppOptions.get('externalLinkTarget') === LinkTarget.NONE) {
// Prevent external links from "replacing" the viewer,
// when it's embedded in e.g. an iframe or an object.
PDFJS.externalLinkTarget = LinkTarget.TOP;
AppOptions.set('externalLinkTarget', LinkTarget.TOP);
}
this.initialized = true;
@ -200,74 +170,74 @@ let PDFViewerApplication = {
* @private
*/
_readPreferences() {
let { preferences, viewerPrefs, } = this;
let { preferences, } = this;
return Promise.all([
preferences.get('enableWebGL').then(function resolved(value) {
viewerPrefs['enableWebGL'] = value;
AppOptions.set('enableWebGL', value);
}),
preferences.get('sidebarViewOnLoad').then(function resolved(value) {
viewerPrefs['sidebarViewOnLoad'] = value;
AppOptions.set('sidebarViewOnLoad', value);
}),
preferences.get('pdfBugEnabled').then(function resolved(value) {
viewerPrefs['pdfBugEnabled'] = value;
AppOptions.set('pdfBugEnabled', value);
}),
preferences.get('showPreviousViewOnLoad').then(function resolved(value) {
viewerPrefs['showPreviousViewOnLoad'] = value;
AppOptions.set('showPreviousViewOnLoad', value);
}),
preferences.get('defaultZoomValue').then(function resolved(value) {
viewerPrefs['defaultZoomValue'] = value;
AppOptions.set('defaultZoomValue', value);
}),
preferences.get('textLayerMode').then(function resolved(value) {
if (viewerPrefs['textLayerMode'] === TextLayerMode.DISABLE) {
if (AppOptions.get('textLayerMode') === TextLayerMode.DISABLE) {
return;
}
viewerPrefs['textLayerMode'] = value;
AppOptions.set('textLayerMode', value);
}),
preferences.get('disableRange').then(function resolved(value) {
if (PDFJS.disableRange === true) {
if (AppOptions.get('disableRange') === true) {
return;
}
PDFJS.disableRange = value;
AppOptions.set('disableRange', value);
}),
preferences.get('disableStream').then(function resolved(value) {
if (PDFJS.disableStream === true) {
if (AppOptions.get('disableStream') === true) {
return;
}
PDFJS.disableStream = value;
AppOptions.set('disableStream', value);
}),
preferences.get('disableAutoFetch').then(function resolved(value) {
PDFJS.disableAutoFetch = value;
AppOptions.set('disableAutoFetch', value);
}),
preferences.get('disableFontFace').then(function resolved(value) {
if (PDFJS.disableFontFace === true) {
if (AppOptions.get('disableFontFace') === true) {
return;
}
PDFJS.disableFontFace = value;
AppOptions.set('disableFontFace', value);
}),
preferences.get('useOnlyCssZoom').then(function resolved(value) {
PDFJS.useOnlyCssZoom = value;
AppOptions.set('useOnlyCssZoom', value);
}),
preferences.get('externalLinkTarget').then(function resolved(value) {
if (PDFJS.externalLinkTarget !== LinkTarget.NONE) {
if (AppOptions.get('externalLinkTarget') !== LinkTarget.NONE) {
return;
}
PDFJS.externalLinkTarget = value;
AppOptions.set('externalLinkTarget', value);
}),
preferences.get('renderer').then(function resolved(value) {
viewerPrefs['renderer'] = value;
AppOptions.set('renderer', value);
}),
preferences.get('renderInteractiveForms').then(function resolved(value) {
viewerPrefs['renderInteractiveForms'] = value;
AppOptions.set('renderInteractiveForms', value);
}),
preferences.get('disablePageMode').then(function resolved(value) {
viewerPrefs['disablePageMode'] = value;
AppOptions.set('disablePageMode', value);
}),
preferences.get('disablePageLabels').then(function resolved(value) {
viewerPrefs['disablePageLabels'] = value;
AppOptions.set('disablePageLabels', value);
}),
preferences.get('enablePrintAutoRotate').then(function resolved(value) {
viewerPrefs['enablePrintAutoRotate'] = value;
AppOptions.set('enablePrintAutoRotate', value);
}),
]).catch(function(reason) { });
},
@ -276,11 +246,11 @@ let PDFViewerApplication = {
* @private
*/
_parseHashParameters() {
let { appConfig, viewerPrefs, } = this;
let { appConfig, } = this;
let waitOn = [];
if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION') ||
viewerPrefs['pdfBugEnabled']) {
AppOptions.get('pdfBugEnabled')) {
// Special debugging flags in the hash section of the URL.
let hash = document.location.hash.substring(1);
let hashParams = parseQueryString(hash);
@ -290,38 +260,42 @@ let PDFViewerApplication = {
waitOn.push(loadFakeWorker());
}
if ('disablerange' in hashParams) {
PDFJS.disableRange = (hashParams['disablerange'] === 'true');
AppOptions.set('disableRange', hashParams['disablerange'] === 'true');
}
if ('disablestream' in hashParams) {
PDFJS.disableStream = (hashParams['disablestream'] === 'true');
AppOptions.set('disableStream', hashParams['disablestream'] === 'true');
}
if ('disableautofetch' in hashParams) {
PDFJS.disableAutoFetch = (hashParams['disableautofetch'] === 'true');
AppOptions.set('disableAutoFetch',
hashParams['disableautofetch'] === 'true');
}
if ('disablefontface' in hashParams) {
PDFJS.disableFontFace = (hashParams['disablefontface'] === 'true');
AppOptions.set('disableFontFace',
hashParams['disablefontface'] === 'true');
}
if ('disablehistory' in hashParams) {
PDFJS.disableHistory = (hashParams['disablehistory'] === 'true');
AppOptions.set('disableHistory',
hashParams['disablehistory'] === 'true');
}
if ('webgl' in hashParams) {
viewerPrefs['enableWebGL'] = (hashParams['webgl'] === 'true');
AppOptions.set('enableWebGL', hashParams['webgl'] === 'true');
}
if ('useonlycsszoom' in hashParams) {
PDFJS.useOnlyCssZoom = (hashParams['useonlycsszoom'] === 'true');
AppOptions.set('useOnlyCssZoom',
hashParams['useonlycsszoom'] === 'true');
}
if ('verbosity' in hashParams) {
PDFJS.verbosity = hashParams['verbosity'] | 0;
AppOptions.set('verbosity', hashParams['verbosity'] | 0);
}
if ((typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) &&
hashParams['disablebcmaps'] === 'true') {
PDFJS.cMapUrl = '../external/cmaps/';
PDFJS.cMapPacked = false;
AppOptions.set('cMapUrl', '../external/cmaps/');
AppOptions.set('cMapPacked', false);
}
if ('textlayer' in hashParams) {
switch (hashParams['textlayer']) {
case 'off':
viewerPrefs['textLayerMode'] = TextLayerMode.DISABLE;
AppOptions.set('textLayerMode', TextLayerMode.DISABLE);
break;
case 'visible':
case 'shadow':
@ -332,7 +306,7 @@ let PDFViewerApplication = {
}
}
if ('pdfbug' in hashParams) {
PDFJS.pdfBug = true;
AppOptions.set('pdfBug', true);
let enabled = hashParams['pdfbug'].split(',');
waitOn.push(loadAndEnablePDFBug(enabled));
}
@ -341,7 +315,7 @@ let PDFViewerApplication = {
// It is not possible to change locale for Firefox extension builds.
if ((typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION') ||
!PDFJSDev.test('FIREFOX || MOZCENTRAL')) && 'locale' in hashParams) {
PDFJS.locale = hashParams['locale'];
AppOptions.set('locale', hashParams['locale']);
}
}
@ -353,7 +327,7 @@ let PDFViewerApplication = {
*/
_initializeL10n() {
this.l10n = this.externalServices.createL10n({
locale: PDFJS.locale,
locale: AppOptions.get('locale'),
});
return this.l10n.getDirection().then((dir) => {
document.getElementsByTagName('html')[0].dir = dir;
@ -364,7 +338,7 @@ let PDFViewerApplication = {
* @private
*/
_initializeViewerComponents() {
let { appConfig, viewerPrefs, } = this;
let { appConfig, } = this;
return new Promise((resolve, reject) => {
this.overlayManager = new OverlayManager();
@ -378,12 +352,14 @@ let PDFViewerApplication = {
let pdfLinkService = new PDFLinkService({
eventBus,
externalLinkTarget: PDFJS.externalLinkTarget,
externalLinkRel: PDFJS.externalLinkRel,
externalLinkTarget: AppOptions.get('externalLinkTarget'),
externalLinkRel: AppOptions.get('externalLinkRel'),
});
this.pdfLinkService = pdfLinkService;
let downloadManager = this.externalServices.createDownloadManager();
let downloadManager = this.externalServices.createDownloadManager({
disableCreateObjectURL: AppOptions.get('disableCreateObjectURL'),
});
this.downloadManager = downloadManager;
let container = appConfig.mainContainer;
@ -395,15 +371,15 @@ let PDFViewerApplication = {
renderingQueue: pdfRenderingQueue,
linkService: pdfLinkService,
downloadManager,
renderer: viewerPrefs['renderer'],
enableWebGL: viewerPrefs['enableWebGL'],
renderer: AppOptions.get('renderer'),
enableWebGL: AppOptions.get('enableWebGL'),
l10n: this.l10n,
textLayerMode: viewerPrefs['textLayerMode'],
imageResourcesPath: PDFJS.imageResourcesPath,
renderInteractiveForms: viewerPrefs['renderInteractiveForms'],
enablePrintAutoRotate: viewerPrefs['enablePrintAutoRotate'],
useOnlyCssZoom: PDFJS.useOnlyCssZoom,
maxCanvasPixels: PDFJS.maxCanvasPixels,
textLayerMode: AppOptions.get('textLayerMode'),
imageResourcesPath: AppOptions.get('imageResourcesPath'),
renderInteractiveForms: AppOptions.get('renderInteractiveForms'),
enablePrintAutoRotate: AppOptions.get('enablePrintAutoRotate'),
useOnlyCssZoom: AppOptions.get('useOnlyCssZoom'),
maxCanvasPixels: AppOptions.get('maxCanvasPixels'),
});
pdfRenderingQueue.setViewer(this.pdfViewer);
pdfLinkService.setViewer(this.pdfViewer);
@ -568,7 +544,7 @@ let PDFViewerApplication = {
support = false;
}
}
if (support && viewerCompatibilityParams['disableFullscreen'] === true) {
if (support && AppOptions.get('disableFullscreen') === true) {
support = false;
}
@ -723,6 +699,11 @@ let PDFViewerApplication = {
return this.open(file, args);
});
}
// Set the necessary global worker parameters, using the available options.
const workerParameters = AppOptions.getAll('worker');
for (let key in workerParameters) {
GlobalWorkerOptions[key] = workerParameters[key];
}
let parameters = Object.create(null);
if (typeof file === 'string') { // URL
@ -740,8 +721,11 @@ let PDFViewerApplication = {
PDFJSDev.test('FIREFOX || MOZCENTRAL || CHROME')) {
parameters.docBaseUrl = this.baseUrl;
}
// TODO: Remove this once all options are moved from the `PDFJS` object.
parameters.verbosity = PDFJS.verbosity;
// Set the necessary API parameters, using the available options.
const apiParameters = AppOptions.getAll('api');
for (let key in apiParameters) {
parameters[key] = apiParameters[key];
}
if (args) {
for (let prop in args) {
@ -952,7 +936,11 @@ let PDFViewerApplication = {
// the loading bar will not be completely filled, nor will it be hidden.
// To prevent displaying a partially filled loading bar permanently, we
// hide it when no data has been loaded during a certain amount of time.
if (PDFJS.disableAutoFetch && percent) {
const disableAutoFetch = this.pdfDocument ?
this.pdfDocument.loadingParams['disableAutoFetch'] :
AppOptions.get('disableAutoFetch');
if (disableAutoFetch && percent) {
if (this.disableAutoFetchLoadingBarTimeout) {
clearTimeout(this.disableAutoFetchLoadingBarTimeout);
this.disableAutoFetchLoadingBarTimeout = null;
@ -1013,10 +1001,10 @@ let PDFViewerApplication = {
firstPagePromise.then((pdfPage) => {
this.loadingBar.setWidth(this.appConfig.viewerContainer);
if (!PDFJS.disableHistory && !this.isViewerEmbedded) {
if (!AppOptions.get('disableHistory') && !this.isViewerEmbedded) {
// The browsing history is only enabled when the viewer is standalone,
// i.e. not when it is embedded in a web page.
let resetHistory = !this.viewerPrefs['showPreviousViewOnLoad'];
let resetHistory = !AppOptions.get('showPreviousViewOnLoad');
this.pdfHistory.initialize(id, resetHistory);
if (this.pdfHistory.initialBookmark) {
@ -1043,19 +1031,19 @@ let PDFViewerApplication = {
Promise.all([storePromise, pageModePromise]).then(
([values = {}, pageMode]) => {
// Initialize the default values, from user preferences.
let hash = this.viewerPrefs['defaultZoomValue'] ?
('zoom=' + this.viewerPrefs['defaultZoomValue']) : null;
let hash = AppOptions.get('defaultZoomValue') ?
('zoom=' + AppOptions.get('defaultZoomValue')) : null;
let rotation = null;
let sidebarView = this.viewerPrefs['sidebarViewOnLoad'];
let sidebarView = AppOptions.get('sidebarViewOnLoad');
if (values.exists && this.viewerPrefs['showPreviousViewOnLoad']) {
if (values.exists && AppOptions.get('showPreviousViewOnLoad')) {
hash = 'page=' + values.page +
'&zoom=' + (this.viewerPrefs['defaultZoomValue'] || values.zoom) +
'&zoom=' + (AppOptions.get('defaultZoomValue') || values.zoom) +
',' + values.scrollLeft + ',' + values.scrollTop;
rotation = parseInt(values.rotation, 10);
sidebarView = sidebarView || (values.sidebarView | 0);
}
if (pageMode && !this.viewerPrefs['disablePageMode']) {
if (pageMode && !AppOptions.get('disablePageMode')) {
// Always let the user preference/history take precedence.
sidebarView = sidebarView || apiPageModeToSidebarView(pageMode);
}
@ -1099,7 +1087,7 @@ let PDFViewerApplication = {
});
pdfDocument.getPageLabels().then((labels) => {
if (!labels || this.viewerPrefs['disablePageLabels']) {
if (!labels || AppOptions.get('disablePageLabels')) {
return;
}
let i = 0, numLabels = labels.length;
@ -1177,7 +1165,7 @@ let PDFViewerApplication = {
info.PDFFormatVersion + ' ' + (info.Producer || '-').trim() +
' / ' + (info.Creator || '-').trim() + ']' +
' (PDF.js: ' + (version || '-') +
(this.viewerPrefs['enableWebGL'] ? ' [WebGL]' : '') + ')');
(AppOptions.get('enableWebGL') ? ' [WebGL]' : '') + ')');
let pdfTitle;
if (metadata && metadata.has('dc:title')) {
@ -1527,6 +1515,9 @@ if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {
function loadFakeWorker() {
return new Promise(function(resolve, reject) {
if (!GlobalWorkerOptions.workerSrc) {
GlobalWorkerOptions.workerSrc = AppOptions.get('workerSrc');
}
if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) {
if (typeof SystemJS === 'object') {
SystemJS.import('pdfjs/core/worker').then((worker) => {
@ -1580,12 +1571,12 @@ function webViewerInitialized() {
if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {
let queryString = document.location.search.substring(1);
let params = parseQueryString(queryString);
file = 'file' in params ? params.file : appConfig.defaultUrl;
file = 'file' in params ? params.file : AppOptions.get('defaultUrl');
validateFileURL(file);
} else if (PDFJSDev.test('FIREFOX || MOZCENTRAL')) {
file = window.location.href.split('#')[0];
} else if (PDFJSDev.test('CHROME')) {
file = appConfig.defaultUrl;
file = AppOptions.get('defaultUrl');
}
if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {
@ -1621,7 +1612,7 @@ function webViewerInitialized() {
if (typeof PDFJSDev !== 'undefined' &&
PDFJSDev.test('FIREFOX || MOZCENTRAL') &&
!PDFViewerApplication.supportsDocumentFonts) {
PDFJS.disableFontFace = true;
AppOptions.set('disableFontFace', true);
PDFViewerApplication.l10n.get('web_fonts_disabled', null,
'Web fonts are disabled: unable to use embedded PDF fonts.').
then((msg) => {
@ -1884,7 +1875,7 @@ if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {
webViewerFileInputChange = function webViewerFileInputChange(evt) {
let file = evt.fileInput.files[0];
if (!PDFJS.disableCreateObjectURL && URL.createObjectURL) {
if (URL.createObjectURL && !AppOptions.get('disableCreateObjectURL')) {
PDFViewerApplication.open(URL.createObjectURL(file));
} else {
// Read the local file into a Uint8Array.
@ -2014,7 +2005,7 @@ function webViewerPageChanging(evt) {
PDFViewerApplication.pdfThumbnailViewer.scrollThumbnailIntoView(page);
}
// we need to update stats
// We need to update stats.
if (typeof Stats !== 'undefined' && Stats.enabled) {
let pageView = PDFViewerApplication.pdfViewer.getPageView(page - 1);
if (pageView && pageView.stats) {

247
web/app_options.js Normal file
View File

@ -0,0 +1,247 @@
/* Copyright 2018 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 { apiCompatibilityParams } from 'pdfjs-lib';
import { viewerCompatibilityParams } from './viewer_compatibility';
const OptionKind = {
VIEWER: 'viewer',
API: 'api',
WORKER: 'worker',
};
/**
* PLEASE NOTE: To avoid introducing unnecessary dependencies, we specify the
* values below *explicitly* rather than relying on imported types;
* compare with the format of `default_preferences.json`.
*/
const defaultOptions = {
defaultUrl: {
/** @type {string} */
value: 'compressed.tracemonkey-pldi-09.pdf',
kind: OptionKind.VIEWER,
},
defaultZoomValue: {
/** @type {string} */
value: '',
kind: OptionKind.VIEWER,
},
disableFullscreen: {
/** @type {boolean} */
value: viewerCompatibilityParams.disableFullscreen || false,
kind: OptionKind.VIEWER,
},
disableHistory: {
/** @type {boolean} */
value: false,
kind: OptionKind.VIEWER,
},
disablePageLabels: {
/** @type {boolean} */
value: false,
kind: OptionKind.VIEWER,
},
disablePageMode: {
/** @type {boolean} */
value: false,
kind: OptionKind.VIEWER,
},
enablePrintAutoRotate: {
/** @type {boolean} */
value: false,
kind: OptionKind.VIEWER,
},
enableWebGL: {
/** @type {boolean} */
value: false,
kind: OptionKind.VIEWER,
},
externalLinkRel: {
/** @type {string} */
value: 'noopener noreferrer nofollow',
kind: OptionKind.VIEWER,
},
externalLinkTarget: {
/** @type {number} */
value: 0,
kind: OptionKind.VIEWER,
},
imageResourcesPath: {
/** @type {string} */
value: './images/',
kind: OptionKind.VIEWER,
},
locale: {
/** @type {string} */
value: (typeof navigator !== 'undefined' ? navigator.language : 'en-US'),
kind: OptionKind.VIEWER,
},
maxCanvasPixels: {
/** @type {number} */
value: viewerCompatibilityParams.maxCanvasPixels || 16777216,
kind: OptionKind.VIEWER,
},
pdfBugEnabled: {
/** @type {boolean} */
value: false,
kind: OptionKind.VIEWER,
},
renderer: {
/** @type {string} */
value: 'canvas',
kind: OptionKind.VIEWER,
},
renderInteractiveForms: {
/** @type {boolean} */
value: false,
kind: OptionKind.VIEWER,
},
showPreviousViewOnLoad: {
/** @type {boolean} */
value: true,
kind: OptionKind.VIEWER,
},
sidebarViewOnLoad: {
/** @type {number} */
value: 0,
kind: OptionKind.VIEWER,
},
textLayerMode: {
/** @type {number} */
value: 1,
kind: OptionKind.VIEWER,
},
useOnlyCssZoom: {
/** @type {boolean} */
value: false,
kind: OptionKind.VIEWER,
},
cMapPacked: {
/** @type {boolean} */
value: true,
kind: OptionKind.API,
},
cMapUrl: {
/** @type {string} */
value: (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION') ?
'../external/bcmaps/' : '../web/cmaps/'),
kind: OptionKind.API,
},
disableAutoFetch: {
/** @type {boolean} */
value: false,
kind: OptionKind.API,
},
disableCreateObjectURL: {
/** @type {boolean} */
value: apiCompatibilityParams.disableCreateObjectURL || false,
kind: OptionKind.API,
},
disableFontFace: {
/** @type {boolean} */
value: false,
kind: OptionKind.API,
},
disableRange: {
/** @type {boolean} */
value: apiCompatibilityParams.disableRange || false,
kind: OptionKind.API,
},
disableStream: {
/** @type {boolean} */
value: apiCompatibilityParams.disableStream || false,
kind: OptionKind.API,
},
isEvalSupported: {
/** @type {boolean} */
value: true,
kind: OptionKind.API,
},
maxImageSize: {
/** @type {number} */
value: -1,
kind: OptionKind.API,
},
pdfBug: {
/** @type {boolean} */
value: false,
kind: OptionKind.API,
},
postMessageTransfers: {
/** @type {boolean} */
value: true,
kind: OptionKind.API,
},
verbosity: {
/** @type {number} */
value: 1,
kind: OptionKind.API,
},
workerPort: {
/** @type {Object} */
value: null,
kind: OptionKind.WORKER,
},
workerSrc: {
/** @type {string} */
value: (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION') ?
'../src/worker_loader.js' : '../build/pdf.worker.js'),
kind: OptionKind.WORKER,
},
};
const userOptions = Object.create(null);
class AppOptions {
constructor() {
throw new Error('Cannot initialize AppOptions.');
}
static get(name) {
let defaultOption = defaultOptions[name], userOption = userOptions[name];
if (userOption !== undefined) {
return userOption;
}
return (defaultOption !== undefined ? defaultOption.value : undefined);
}
static getAll(kind = null) {
let options = Object.create(null);
for (let name in defaultOptions) {
let defaultOption = defaultOptions[name], userOption = userOptions[name];
if (kind && defaultOption.kind !== kind) {
continue;
}
options[name] = (userOption !== undefined ?
userOption : defaultOption.value);
}
return options;
}
static set(name, value) {
userOptions[name] = value;
}
static remove(name) {
delete userOptions[name];
}
}
export {
AppOptions,
OptionKind,
};

View File

@ -13,7 +13,6 @@
* limitations under the License.
*/
import { createPromiseCapability, PDFJS } from 'pdfjs-lib';
import {
CSS_UNITS, DEFAULT_SCALE, DEFAULT_SCALE_VALUE, isValidRotation,
MAX_AUTO_SCALE, NullL10n, PresentationModeState, RendererType,
@ -21,6 +20,7 @@ import {
} from './ui_utils';
import { PDFRenderingQueue, RenderingStates } from './pdf_rendering_queue';
import { AnnotationLayerBuilder } from './annotation_layer_builder';
import { createPromiseCapability } from 'pdfjs-lib';
import { getGlobalEventBus } from './dom_events';
import { PDFPageView } from './pdf_page_view';
import { SimpleLinkService } from './pdf_link_service';
@ -408,7 +408,7 @@ class BaseViewer {
// starts to create the correct size canvas. Wait until one page is
// rendered so we don't tie up too many resources early on.
onePageRenderedCapability.promise.then(() => {
if (PDFJS.disableAutoFetch) {
if (pdfDocument.loadingParams['disableAutoFetch']) {
// XXX: Printing is semi-broken with auto fetch disabled.
pagesCapability.resolve();
return;

View File

@ -363,8 +363,8 @@ ChromeExternalServices.initPassiveLoading = function(callbacks) {
callbacks.onOpenWithURL(url, length, originalURL);
});
};
ChromeExternalServices.createDownloadManager = function() {
return new DownloadManager();
ChromeExternalServices.createDownloadManager = function(options) {
return new DownloadManager(options);
};
ChromeExternalServices.createPreferences = function() {
return new ChromePreferences();

View File

@ -13,13 +13,18 @@
* limitations under the License.
*/
import { createObjectURL, createValidAbsoluteUrl, PDFJS } from 'pdfjs-lib';
import {
apiCompatibilityParams, createObjectURL, createValidAbsoluteUrl
} from 'pdfjs-lib';
if (typeof PDFJSDev !== 'undefined' && !PDFJSDev.test('CHROME || GENERIC')) {
throw new Error('Module "pdfjs-web/download_manager" shall not be used ' +
'outside CHROME and GENERIC builds.');
}
const DISABLE_CREATE_OBJECT_URL =
apiCompatibilityParams.disableCreateObjectURL || false;
function download(blobUrl, filename) {
let a = document.createElement('a');
if (!a.click) {
@ -40,6 +45,10 @@ function download(blobUrl, filename) {
}
class DownloadManager {
constructor({ disableCreateObjectURL = DISABLE_CREATE_OBJECT_URL, }) {
this.disableCreateObjectURL = disableCreateObjectURL;
}
downloadUrl(url, filename) {
if (!createValidAbsoluteUrl(url, 'http://example.com')) {
return; // restricted/invalid URL
@ -53,7 +62,7 @@ class DownloadManager {
filename);
}
let blobUrl = createObjectURL(data, contentType,
PDFJS.disableCreateObjectURL);
this.disableCreateObjectURL);
download(blobUrl, filename);
}
@ -66,7 +75,7 @@ class DownloadManager {
return;
}
if (PDFJS.disableCreateObjectURL) {
if (this.disableCreateObjectURL) {
// URL.createObjectURL is not supported
this.downloadUrl(url, filename);
return;

View File

@ -84,6 +84,10 @@ let FirefoxCom = (function FirefoxComClosure() {
})();
class DownloadManager {
constructor(options) {
this.disableCreateObjectURL = false;
}
downloadUrl(url, filename) {
FirefoxCom.request('download', {
originalUrl: url,
@ -92,7 +96,7 @@ class DownloadManager {
}
downloadData(data, filename, contentType) {
let blobUrl = createObjectURL(data, contentType, false);
let blobUrl = createObjectURL(data, contentType);
FirefoxCom.request('download', {
blobUrl,
@ -256,8 +260,8 @@ PDFViewerApplication.externalServices = {
FirefoxCom.request('reportTelemetry', JSON.stringify(data));
},
createDownloadManager() {
return new DownloadManager();
createDownloadManager(options) {
return new DownloadManager(options);
},
createPreferences() {

View File

@ -42,14 +42,14 @@ class GenericPreferences extends BasePreferences {
}
let GenericExternalServices = Object.create(DefaultExternalServices);
GenericExternalServices.createDownloadManager = function() {
return new DownloadManager();
GenericExternalServices.createDownloadManager = function(options) {
return new DownloadManager(options);
};
GenericExternalServices.createPreferences = function() {
return new GenericPreferences();
};
GenericExternalServices.createL10n = function(options) {
return new GenericL10n(options.locale);
GenericExternalServices.createL10n = function({ locale = 'en-US', }) {
return new GenericL10n(locale);
};
PDFViewerApplication.externalServices = GenericExternalServices;

View File

@ -14,7 +14,7 @@
*/
import {
createObjectURL, createPromiseCapability, getFilenameFromUrl, PDFJS,
createObjectURL, createPromiseCapability, getFilenameFromUrl,
removeNullCharacters
} from 'pdfjs-lib';
@ -74,9 +74,9 @@ class PDFAttachmentViewer {
* @private
*/
_bindPdfLink(button, content, filename) {
if (PDFJS.disableCreateObjectURL) {
throw new Error('bindPdfLink: ' +
'Unsupported "PDFJS.disableCreateObjectURL" value.');
if (this.downloadManager.disableCreateObjectURL) {
throw new Error(
'bindPdfLink: Unsupported "disableCreateObjectURL" value.');
}
let blobUrl;
button.onclick = function() {
@ -141,7 +141,8 @@ class PDFAttachmentViewer {
div.className = 'attachmentsItem';
let button = document.createElement('button');
button.textContent = filename;
if (/\.pdf$/i.test(filename) && !PDFJS.disableCreateObjectURL) {
if (/\.pdf$/i.test(filename) &&
!this.downloadManager.disableCreateObjectURL) {
this._bindPdfLink(button, item.content, filename);
} else {
this._bindLink(button, item.content, filename);

View File

@ -78,10 +78,10 @@ class PDFOutlineViewer {
return;
}
element.href = this.linkService.getDestinationHash(dest);
element.href = linkService.getDestinationHash(dest);
element.onclick = () => {
if (dest) {
this.linkService.navigateTo(dest);
linkService.navigateTo(dest);
}
return false;
};

View File

@ -15,7 +15,6 @@
import { CSS_UNITS, NullL10n } from './ui_utils';
import { PDFPrintServiceFactory, PDFViewerApplication } from './app';
import { PDFJS } from 'pdfjs-lib';
let activeService = null;
let overlayManager = null;
@ -62,6 +61,8 @@ function PDFPrintService(pdfDocument, pagesOverview, printContainer, l10n) {
this.pagesOverview = pagesOverview;
this.printContainer = printContainer;
this.l10n = l10n || NullL10n;
this.disableCreateObjectURL =
pdfDocument.loadingParams['disableCreateObjectURL'];
this.currentPage = -1;
// The temporary canvas where renderPage paints one page at a time.
this.scratchCanvas = document.createElement('canvas');
@ -153,7 +154,7 @@ PDFPrintService.prototype = {
img.style.height = printItem.height;
let scratchCanvas = this.scratchCanvas;
if (('toBlob' in scratchCanvas) && !PDFJS.disableCreateObjectURL) {
if (('toBlob' in scratchCanvas) && !this.disableCreateObjectURL) {
scratchCanvas.toBlob(function(blob) {
img.src = URL.createObjectURL(blob);
});

View File

@ -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,
};

View File

@ -13,7 +13,7 @@
* limitations under the License.
*/
import { createPromiseCapability, PDFJS } from 'pdfjs-lib';
import { createPromiseCapability } from 'pdfjs-lib';
const CSS_UNITS = 96.0 / 72.0;
const DEFAULT_SCALE_VALUE = 'auto';
@ -71,39 +71,6 @@ let NullL10n = {
},
};
/**
* Enables CSS only zooming.
* @var {boolean}
*/
PDFJS.useOnlyCssZoom = (PDFJS.useOnlyCssZoom === undefined ?
false : PDFJS.useOnlyCssZoom);
/**
* The maximum supported canvas size in total pixels e.g. width * height.
* The default value is 4096 * 4096. Use -1 for no limit.
* @var {number}
*/
PDFJS.maxCanvasPixels = (PDFJS.maxCanvasPixels === undefined ?
16777216 : PDFJS.maxCanvasPixels);
/**
* Disables saving of the last position of the viewed PDF.
* @var {boolean}
*/
PDFJS.disableHistory = (PDFJS.disableHistory === undefined ?
false : PDFJS.disableHistory);
if (typeof PDFJSDev === 'undefined' ||
!PDFJSDev.test('FIREFOX || MOZCENTRAL')) {
/**
* Interface locale settings.
* @var {string}
*/
PDFJS.locale =
(PDFJS.locale === undefined && typeof navigator !== 'undefined' ?
navigator.language : PDFJS.locale) || 'en-US';
}
/**
* Returns scale factor for the canvas. It makes sense for the HiDPI displays.
* @return {Object} The object with horizontal (sx) and vertical (sy)

View File

@ -16,18 +16,18 @@
'use strict';
let DEFAULT_URL = 'compressed.tracemonkey-pldi-09.pdf';
if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME')) {
var defaultUrl; // eslint-disable-line no-var
(function rewriteUrlClosure() {
// Run this code outside DOMContentLoaded to make sure that the URL
// is rewritten as soon as possible.
let queryString = document.location.search.slice(1);
let m = /(^|&)file=([^&]*)/.exec(queryString);
DEFAULT_URL = m ? decodeURIComponent(m[2]) : '';
defaultUrl = m ? decodeURIComponent(m[2]) : '';
// Example: chrome-extension://.../http://example.com/file.pdf
let humanReadableUrl = '/' + DEFAULT_URL + location.hash;
let humanReadableUrl = '/' + defaultUrl + location.hash;
history.replaceState(history.state, '', humanReadableUrl);
if (top === window) {
chrome.runtime.sendMessage('showPageAction');
@ -35,9 +35,10 @@ if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME')) {
})();
}
let pdfjsWebApp;
let pdfjsWebApp, pdfjsWebAppOptions;
if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('PRODUCTION')) {
pdfjsWebApp = require('./app.js');
pdfjsWebAppOptions = require('./app_options.js');
}
if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('FIREFOX || MOZCENTRAL')) {
@ -171,7 +172,6 @@ function getViewerConfiguration() {
printContainer: document.getElementById('printContainer'),
openFileInputName: 'fileInput',
debuggerScriptPath: './debugger.js',
defaultUrl: DEFAULT_URL,
};
}
@ -180,14 +180,21 @@ function webViewerLoad() {
if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) {
Promise.all([
SystemJS.import('pdfjs-web/app'),
SystemJS.import('pdfjs-web/app_options'),
SystemJS.import('pdfjs-web/genericcom'),
SystemJS.import('pdfjs-web/pdf_print_service'),
]).then(function([app, ...otherModules]) {
]).then(function([app, appOptions, ...otherModules]) {
window.PDFViewerApplication = app.PDFViewerApplication;
window.PDFViewerApplicationOptions = appOptions.AppOptions;
app.PDFViewerApplication.run(config);
});
} else {
if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME')) {
pdfjsWebAppOptions.AppOptions.set('defaultUrl', defaultUrl);
}
window.PDFViewerApplication = pdfjsWebApp.PDFViewerApplication;
window.PDFViewerApplicationOptions = pdfjsWebAppOptions.AppOptions;
pdfjsWebApp.PDFViewerApplication.run(config);
}
}