diff --git a/examples/mobile-viewer/viewer.js b/examples/mobile-viewer/viewer.js index 15037fc77..dc3276ce4 100644 --- a/examples/mobile-viewer/viewer.js +++ b/examples/mobile-viewer/viewer.js @@ -21,8 +21,8 @@ if (typeof PDFJS === 'undefined' || !PDFJS.PDFViewer || !PDFJS.getDocument) { ' `gulp dist-install`'); } -PDFJS.useOnlyCssZoom = true; -PDFJS.disableTextLayer = true; +var USE_ONLY_CSS_ZOOM = true; +var TEXT_LAYER_MODE = 0; // DISABLE PDFJS.maxImageSize = 1024 * 1024; PDFJS.workerSrc = '../../node_modules/pdfjs-dist/build/pdf.worker.js'; PDFJS.cMapUrl = '../../node_modules/pdfjs-dist/cmaps/'; @@ -298,6 +298,8 @@ var PDFViewerApplication = { container: container, linkService: linkService, l10n: this.l10n, + useOnlyCssZoom: USE_ONLY_CSS_ZOOM, + textLayerMode: TEXT_LAYER_MODE, }); this.pdfViewer = pdfViewer; linkService.setViewer(pdfViewer); diff --git a/extensions/chromium/preferences_schema.json b/extensions/chromium/preferences_schema.json index fa350567e..6ab4be3e6 100644 --- a/extensions/chromium/preferences_schema.json +++ b/extensions/chromium/preferences_schema.json @@ -70,11 +70,16 @@ "type": "boolean", "default": false }, - "disableTextLayer": { - "title": "Disable text selection layer", - "description": "Whether to disable the text selection layer.", - "type": "boolean", - "default": false + "textLayerMode": { + "title": "Text layer mode", + "description": "Controls if the text layer is enabled, and the selection mode that is used.\n 0 = Disabled.\n 1 = Enabled.\n 2 = (Experimental) Enabled, with enhanced text selection.", + "type": "integer", + "enum": [ + 0, + 1, + 2 + ], + "default": 1 }, "useOnlyCssZoom": { "type": "boolean", @@ -107,10 +112,6 @@ "description": "Whether to prevent the extension from reporting the extension and browser version to the extension developers.", "default": false }, - "enhanceTextSelection": { - "type": "boolean", - "default": false - }, "renderer": { "type": "string", "enum": [ diff --git a/src/display/annotation_layer.js b/src/display/annotation_layer.js index 74b5a0c7f..048bfb562 100644 --- a/src/display/annotation_layer.js +++ b/src/display/annotation_layer.js @@ -14,8 +14,7 @@ */ import { - addLinkAttributes, DOMSVGFactory, getDefaultSetting, getFilenameFromUrl, - LinkTarget + addLinkAttributes, DOMSVGFactory, getFilenameFromUrl, LinkTarget } from './dom_utils'; import { AnnotationBorderStyleType, AnnotationType, stringToPDFString, unreachable, @@ -30,7 +29,8 @@ import { * @property {PageViewport} viewport * @property {IPDFLinkService} linkService * @property {DownloadManager} downloadManager - * @property {string} imageResourcesPath + * @property {string} imageResourcesPath - (optional) Path for image resources, + * mainly for annotation icons. Include trailing slash. * @property {boolean} renderInteractiveForms * @property {Object} svgFactory */ @@ -281,17 +281,21 @@ class LinkAnnotationElement extends AnnotationElement { render() { this.container.className = 'linkAnnotation'; + let { data, linkService, } = this; let link = document.createElement('a'); + addLinkAttributes(link, { - url: this.data.url, - target: (this.data.newWindow ? LinkTarget.BLANK : undefined), + url: data.url, + target: (data.newWindow ? + LinkTarget.BLANK : linkService.externalLinkTarget), + rel: linkService.externalLinkRel, }); - if (!this.data.url) { - if (this.data.action) { - this._bindNamedAction(link, this.data.action); + if (!data.url) { + if (data.action) { + this._bindNamedAction(link, data.action); } else { - this._bindLink(link, this.data.dest); + this._bindLink(link, data.dest); } } @@ -1183,7 +1187,9 @@ class FileAttachmentAnnotationElement extends AnnotationElement { * @property {Array} annotations * @property {PDFPage} page * @property {IPDFLinkService} linkService - * @property {string} imageResourcesPath + * @property {DownloadManager} downloadManager + * @property {string} imageResourcesPath - (optional) Path for image resources, + * mainly for annotation icons. Include trailing slash. * @property {boolean} renderInteractiveForms */ @@ -1208,8 +1214,7 @@ class AnnotationLayer { viewport: parameters.viewport, linkService: parameters.linkService, downloadManager: parameters.downloadManager, - imageResourcesPath: parameters.imageResourcesPath || - getDefaultSetting('imageResourcesPath'), + imageResourcesPath: parameters.imageResourcesPath || '', renderInteractiveForms: parameters.renderInteractiveForms || false, svgFactory: new DOMSVGFactory(), }); diff --git a/src/display/api.js b/src/display/api.js index cfa95f00d..e73515d6b 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -707,6 +707,8 @@ var PDFDocumentProxy = (function PDFDocumentProxyClosure() { * calling of PDFPage.getViewport method. * @property {string} intent - Rendering intent, can be 'display' or 'print' * (default value is 'display'). + * @property {boolean} enableWebGL - (optional) Enables WebGL accelerated + * rendering for some operations. The default value is `false`. * @property {boolean} renderInteractiveForms - (optional) Whether or not * interactive form elements are rendered in the display * layer. If so, we do not render them on canvas as well. @@ -743,7 +745,7 @@ var PDFPageProxy = (function PDFPageProxyClosure() { this.pageIndex = pageIndex; this.pageInfo = pageInfo; this.transport = transport; - this._stats = (getDefaultSetting('enableStats') ? + this._stats = (getDefaultSetting('pdfBug') ? new StatTimer() : DummyStatTimer); this.commonObjs = transport.commonObjs; this.objs = new PDFObjects(); @@ -828,9 +830,7 @@ var PDFPageProxy = (function PDFPageProxyClosure() { var renderingIntent = (params.intent === 'print' ? 'print' : 'display'); var canvasFactory = params.canvasFactory || new DOMCanvasFactory(); let webGLContext = new WebGLContext({ - // TODO: When moving this parameter from `PDFJS` to {RenderParameters}, - // change its name to `enableWebGL` instead. - enable: !getDefaultSetting('disableWebGL'), + enable: params.enableWebGL, }); if (!this.intentStates[renderingIntent]) { diff --git a/src/display/dom_utils.js b/src/display/dom_utils.js index 3cf577c52..f5e130d26 100644 --- a/src/display/dom_utils.js +++ b/src/display/dom_utils.js @@ -274,7 +274,7 @@ var RenderingCancelledException = (function RenderingCancelledException() { return RenderingCancelledException; })(); -var LinkTarget = { +const LinkTarget = { NONE: 0, // Default value. SELF: 1, BLANK: 2, @@ -282,7 +282,7 @@ var LinkTarget = { TOP: 4, }; -var LinkTargetStringMap = [ +const LinkTargetStringMap = [ '', '_self', '_blank', @@ -294,8 +294,10 @@ var LinkTargetStringMap = [ * @typedef ExternalLinkParameters * @typedef {Object} ExternalLinkParameters * @property {string} url - An absolute URL. - * @property {LinkTarget} target - The link target. - * @property {string} rel - The link relationship. + * @property {LinkTarget} target - (optional) The link target. + * The default value is `LinkTarget.NONE`. + * @property {string} rel - (optional) The link relationship. + * The default value is `DEFAULT_LINK_REL`. */ /** @@ -303,22 +305,16 @@ var LinkTargetStringMap = [ * @param {HTMLLinkElement} link - The link element. * @param {ExternalLinkParameters} params */ -function addLinkAttributes(link, params) { - var url = params && params.url; +function addLinkAttributes(link, { url, target, rel, } = {}) { link.href = link.title = (url ? removeNullCharacters(url) : ''); if (url) { - var target = params.target; - if (typeof target === 'undefined') { - target = getDefaultSetting('externalLinkTarget'); - } - link.target = LinkTargetStringMap[target]; + const LinkTargetValues = Object.values(LinkTarget); + let targetIndex = + LinkTargetValues.includes(target) ? target : LinkTarget.NONE; + link.target = LinkTargetStringMap[targetIndex]; - var rel = params.rel; - if (typeof rel === 'undefined') { - rel = getDefaultSetting('externalLinkRel'); - } - link.rel = rel; + link.rel = (typeof rel === 'string' ? rel : DEFAULT_LINK_REL); } } @@ -349,8 +345,6 @@ function getDefaultSetting(id) { return globalSettings ? globalSettings.disableFontFace : false; case 'disableCreateObjectURL': return globalSettings ? globalSettings.disableCreateObjectURL : false; - case 'disableWebGL': - return globalSettings ? globalSettings.disableWebGL : true; case 'cMapUrl': return globalSettings ? globalSettings.cMapUrl : null; case 'cMapPacked': @@ -363,49 +357,13 @@ function getDefaultSetting(id) { return globalSettings ? globalSettings.workerSrc : null; case 'maxImageSize': return globalSettings ? globalSettings.maxImageSize : -1; - case 'imageResourcesPath': - return globalSettings ? globalSettings.imageResourcesPath : ''; case 'isEvalSupported': return globalSettings ? globalSettings.isEvalSupported : true; - case 'externalLinkTarget': - if (!globalSettings) { - return LinkTarget.NONE; - } - switch (globalSettings.externalLinkTarget) { - case LinkTarget.NONE: - case LinkTarget.SELF: - case LinkTarget.BLANK: - case LinkTarget.PARENT: - case LinkTarget.TOP: - return globalSettings.externalLinkTarget; - } - warn('PDFJS.externalLinkTarget is invalid: ' + - globalSettings.externalLinkTarget); - // Reset the external link target, to suppress further warnings. - globalSettings.externalLinkTarget = LinkTarget.NONE; - return LinkTarget.NONE; - case 'externalLinkRel': - return globalSettings ? globalSettings.externalLinkRel : DEFAULT_LINK_REL; - case 'enableStats': - return !!(globalSettings && globalSettings.enableStats); default: throw new Error('Unknown default setting: ' + id); } } -function isExternalLinkTargetSet() { - var externalLinkTarget = getDefaultSetting('externalLinkTarget'); - switch (externalLinkTarget) { - case LinkTarget.NONE: - return false; - case LinkTarget.SELF: - case LinkTarget.BLANK: - case LinkTarget.PARENT: - case LinkTarget.TOP: - return true; - } -} - class StatTimer { constructor(enable = true) { this.enabled = !!enable; @@ -483,7 +441,6 @@ class DummyStatTimer { export { RenderingCancelledException, addLinkAttributes, - isExternalLinkTargetSet, getFilenameFromUrl, LinkTarget, getDefaultSetting, diff --git a/src/display/global.js b/src/display/global.js index b6be09482..23627c439 100644 --- a/src/display/global.js +++ b/src/display/global.js @@ -13,10 +13,6 @@ * limitations under the License. */ -import { - addLinkAttributes, DEFAULT_LINK_REL, getFilenameFromUrl, - isExternalLinkTargetSet, isValidUrl, LinkTarget -} from './dom_utils'; import { createBlob, createObjectURL, createPromiseCapability, getVerbosityLevel, InvalidPDFException, isLittleEndian, MissingPDFException, OPS, PageViewport, @@ -24,6 +20,7 @@ import { shadow, UnexpectedResponseException, UnknownErrorException, UNSUPPORTED_FEATURES, Util, VERBOSITY_LEVELS } from '../shared/util'; +import { DEFAULT_LINK_REL, getFilenameFromUrl, LinkTarget } from './dom_utils'; import { getDocument, LoopbackPort, PDFDataRangeTransport, PDFWorker } from './api'; @@ -42,11 +39,6 @@ if (!globalScope.PDFJS) { } var PDFJS = globalScope.PDFJS; -if (typeof PDFJSDev !== 'undefined') { - PDFJS.version = PDFJSDev.eval('BUNDLE_VERSION'); - PDFJS.build = PDFJSDev.eval('BUNDLE_BUILD'); -} - PDFJS.pdfBug = false; if (PDFJS.verbosity !== undefined) { @@ -67,7 +59,6 @@ Object.defineProperty(PDFJS, 'verbosity', { PDFJS.VERBOSITY_LEVELS = VERBOSITY_LEVELS; PDFJS.OPS = OPS; PDFJS.UNSUPPORTED_FEATURES = UNSUPPORTED_FEATURES; -PDFJS.isValidUrl = isValidUrl; PDFJS.shadow = shadow; PDFJS.createBlob = createBlob; PDFJS.createObjectURL = function PDFJS_createObjectURL(data, contentType) { @@ -120,14 +111,6 @@ PDFJS.cMapPacked = PDFJS.cMapPacked === undefined ? false : PDFJS.cMapPacked; PDFJS.disableFontFace = (PDFJS.disableFontFace === undefined ? false : PDFJS.disableFontFace); -/** - * Path for image resources, mainly for annotation icons. Include trailing - * slash. - * @var {string} - */ -PDFJS.imageResourcesPath = (PDFJS.imageResourcesPath === undefined ? - '' : PDFJS.imageResourcesPath); - /** * Path and filename of the worker file. Required when the worker is enabled * in development mode. If unspecified in the production build, the worker @@ -192,16 +175,9 @@ PDFJS.postMessageTransfers = (PDFJS.postMessageTransfers === undefined ? PDFJS.disableCreateObjectURL = (PDFJS.disableCreateObjectURL === undefined ? false : PDFJS.disableCreateObjectURL); -/** - * Disables WebGL usage. - * @var {boolean} - */ -PDFJS.disableWebGL = (PDFJS.disableWebGL === undefined ? - true : PDFJS.disableWebGL); - /** * Specifies the |target| attribute for external links. - * The constants from PDFJS.LinkTarget should be used: + * The constants from {LinkTarget} should be used: * - NONE [default] * - SELF * - BLANK @@ -233,10 +209,7 @@ PDFJS.LoopbackPort = LoopbackPort; PDFJS.PDFDataRangeTransport = PDFDataRangeTransport; PDFJS.PDFWorker = PDFWorker; -PDFJS.LinkTarget = LinkTarget; -PDFJS.addLinkAttributes = addLinkAttributes; PDFJS.getFilenameFromUrl = getFilenameFromUrl; -PDFJS.isExternalLinkTargetSet = isExternalLinkTargetSet; PDFJS.AnnotationLayer = AnnotationLayer; diff --git a/src/pdf.js b/src/pdf.js index 38e5e458c..644ff8a37 100644 --- a/src/pdf.js +++ b/src/pdf.js @@ -91,4 +91,5 @@ exports.createBlob = pdfjsSharedUtil.createBlob; exports.RenderingCancelledException = pdfjsDisplayDOMUtils.RenderingCancelledException; exports.getFilenameFromUrl = pdfjsDisplayDOMUtils.getFilenameFromUrl; +exports.LinkTarget = pdfjsDisplayDOMUtils.LinkTarget; exports.addLinkAttributes = pdfjsDisplayDOMUtils.addLinkAttributes; diff --git a/src/shared/compatibility.js b/src/shared/compatibility.js index 3b2221f6f..86ec6e1d2 100644 --- a/src/shared/compatibility.js +++ b/src/shared/compatibility.js @@ -26,12 +26,10 @@ if ((typeof PDFJSDev === 'undefined' || // users - https://github.com/mozilla/pdf.js/issues/9397 if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('CHROME')) { -var globalScope = require('./global_scope'); - +const globalScope = require('./global_scope'); const isNodeJS = require('./is_node'); var userAgent = (typeof navigator !== 'undefined' && navigator.userAgent) || ''; -var isAndroid = /Android/.test(userAgent); var isIOSChrome = userAgent.indexOf('CriOS') >= 0; var isIE = userAgent.indexOf('Trident') >= 0; var isIOS = /\b(iPad|iPhone|iPod)(?=;)/.test(userAgent); @@ -80,18 +78,6 @@ PDFJS.compatibilityChecked = true; } })(); -// Checks if navigator.language is supported -// Support: IE<11 -(function checkNavigatorLanguage() { - if (typeof navigator === 'undefined') { - return; - } - if ('language' in navigator) { - return; - } - PDFJS.locale = navigator.userLanguage || 'en-US'; -})(); - // Support: Safari 6.0+, iOS (function checkRangeRequests() { // Safari has issues with cached range requests see: @@ -103,25 +89,6 @@ PDFJS.compatibilityChecked = true; } })(); -// Support: Android, iOS -(function checkCanvasSizeLimitation() { - if (isIOS || isAndroid) { - // 5MP - PDFJS.maxCanvasPixels = 5242880; - } -})(); - -// Disable fullscreen support for certain problematic configurations. -// Support: IE11+ (when embedded). -(function checkFullscreenSupport() { - if (!hasDOM) { - return; - } - if (isIE && window.parent !== window) { - PDFJS.disableFullscreen = true; - } -})(); - // Provides document.currentScript support // Support: IE, Chrome<29. (function checkCurrentScript() { diff --git a/test/driver.js b/test/driver.js index a1274000e..ee5e3c5db 100644 --- a/test/driver.js +++ b/test/driver.js @@ -18,6 +18,7 @@ var WAITING_TIME = 100; // ms var PDF_TO_CSS_UNITS = 96.0 / 72.0; +const IMAGE_RESOURCES_PATH = '/web/images/'; /** * @class @@ -164,6 +165,7 @@ var rasterizeAnnotationLayer = (function rasterizeAnnotationLayerClosure() { } function rasterizeAnnotationLayer(ctx, viewport, annotations, page, + imageResourcesPath, renderInteractiveForms) { return new Promise(function (resolve) { // Building SVG with size of the viewport. @@ -194,6 +196,7 @@ var rasterizeAnnotationLayer = (function rasterizeAnnotationLayerClosure() { annotations, page, linkService: new PDFJS.SimpleLinkService(), + imageResourcesPath, renderInteractiveForms, }; PDFJS.AnnotationLayer.render(parameters); @@ -251,8 +254,7 @@ var Driver = (function DriverClosure() { // eslint-disable-line no-unused-vars PDFJS.workerSrc = '../build/generic/build/pdf.worker.js'; PDFJS.cMapPacked = true; PDFJS.cMapUrl = '../external/bcmaps/'; - PDFJS.enableStats = true; - PDFJS.imageResourcesPath = '/web/images/'; + PDFJS.pdfBug = true; // Set the passed options this.inflight = options.inflight; @@ -506,7 +508,9 @@ var Driver = (function DriverClosure() { // eslint-disable-line no-unused-vars function(annotations) { return rasterizeAnnotationLayer(annotationLayerContext, viewport, annotations, - page, renderForms); + page, + IMAGE_RESOURCES_PATH, + renderForms); }); } else { annotationLayerCanvas = null; diff --git a/test/unit/dom_utils_spec.js b/test/unit/dom_utils_spec.js index 314459450..938aafd83 100644 --- a/test/unit/dom_utils_spec.js +++ b/test/unit/dom_utils_spec.js @@ -13,11 +13,8 @@ * limitations under the License. */ -import { - DOMSVGFactory, getFilenameFromUrl, isExternalLinkTargetSet, LinkTarget -} from '../../src/display/dom_utils'; +import { DOMSVGFactory, getFilenameFromUrl } from '../../src/display/dom_utils'; import isNodeJS from '../../src/shared/is_node'; -import { PDFJS } from '../../src/display/global'; describe('dom_utils', function() { describe('DOMSVGFactory', function() { @@ -95,37 +92,4 @@ describe('dom_utils', function() { expect(result).toEqual(expected); }); }); - - describe('isExternalLinkTargetSet', function() { - var savedExternalLinkTarget; - - beforeAll(function (done) { - savedExternalLinkTarget = PDFJS.externalLinkTarget; - done(); - }); - - afterAll(function () { - PDFJS.externalLinkTarget = savedExternalLinkTarget; - }); - - it('handles the predefined LinkTargets', function() { - for (var key in LinkTarget) { - var linkTarget = LinkTarget[key]; - PDFJS.externalLinkTarget = linkTarget; - - expect(isExternalLinkTargetSet()).toEqual(!!linkTarget); - } - }); - - it('handles incorrect LinkTargets', function() { - var targets = [true, '', false, -1, '_blank', null]; - - for (var i = 0, ii = targets.length; i < ii; i++) { - var linkTarget = targets[i]; - PDFJS.externalLinkTarget = linkTarget; - - expect(isExternalLinkTargetSet()).toEqual(false); - } - }); - }); }); diff --git a/web/annotation_layer_builder.js b/web/annotation_layer_builder.js index 2c96778ca..10f1eeec0 100644 --- a/web/annotation_layer_builder.js +++ b/web/annotation_layer_builder.js @@ -21,6 +21,8 @@ import { SimpleLinkService } from './pdf_link_service'; * @typedef {Object} AnnotationLayerBuilderOptions * @property {HTMLDivElement} pageDiv * @property {PDFPage} pdfPage + * @property {string} imageResourcesPath - (optional) Path for image resources, + * mainly for annotation icons. Include trailing slash. * @property {boolean} renderInteractiveForms * @property {IPDFLinkService} linkService * @property {DownloadManager} downloadManager @@ -32,11 +34,13 @@ class AnnotationLayerBuilder { * @param {AnnotationLayerBuilderOptions} options */ constructor({ pageDiv, pdfPage, linkService, downloadManager, - renderInteractiveForms = false, l10n = NullL10n, }) { + imageResourcesPath = '', renderInteractiveForms = false, + l10n = NullL10n, }) { this.pageDiv = pageDiv; this.pdfPage = pdfPage; this.linkService = linkService; this.downloadManager = downloadManager; + this.imageResourcesPath = imageResourcesPath; this.renderInteractiveForms = renderInteractiveForms; this.l10n = l10n; @@ -59,6 +63,7 @@ class AnnotationLayerBuilder { div: this.div, annotations, page: this.pdfPage, + imageResourcesPath: this.imageResourcesPath, renderInteractiveForms: this.renderInteractiveForms, linkService: this.linkService, downloadManager: this.downloadManager, @@ -104,15 +109,19 @@ class DefaultAnnotationLayerFactory { /** * @param {HTMLDivElement} pageDiv * @param {PDFPage} pdfPage + * @param {string} imageResourcesPath - (optional) Path for image resources, + * mainly for annotation icons. Include trailing slash. * @param {boolean} renderInteractiveForms * @param {IL10n} l10n * @returns {AnnotationLayerBuilder} */ - createAnnotationLayerBuilder(pageDiv, pdfPage, renderInteractiveForms = false, + createAnnotationLayerBuilder(pageDiv, pdfPage, imageResourcesPath = '', + renderInteractiveForms = false, l10n = NullL10n) { return new AnnotationLayerBuilder({ pageDiv, pdfPage, + imageResourcesPath, renderInteractiveForms, linkService: new SimpleLinkService(), l10n, diff --git a/web/app.js b/web/app.js index e3128b118..e1891650d 100644 --- a/web/app.js +++ b/web/app.js @@ -18,11 +18,11 @@ import { animationStarted, DEFAULT_SCALE_VALUE, getPDFFileNameFromURL, isFileSchema, isValidRotation, MAX_SCALE, MIN_SCALE, noContextMenuHandler, normalizeWheelEventDelta, parseQueryString, PresentationModeState, - ProgressBar, RendererType + ProgressBar, RendererType, TextLayerMode } from './ui_utils'; import { build, createBlob, getDocument, getFilenameFromUrl, InvalidPDFException, - MissingPDFException, OPS, PDFJS, PDFWorker, shadow, + LinkTarget, MissingPDFException, OPS, PDFJS, PDFWorker, shadow, UnexpectedResponseException, UNSUPPORTED_FEATURES, version } from 'pdfjs-lib'; import { CursorTool, PDFCursorTools } from './pdf_cursor_tools'; @@ -44,6 +44,7 @@ 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; @@ -138,6 +139,7 @@ let PDFViewerApplication = { isInitialViewSet: false, downloadComplete: false, viewerPrefs: { + enableWebGL: false, sidebarViewOnLoad: SidebarView.NONE, pdfBugEnabled: false, showPreviousViewOnLoad: true, @@ -145,7 +147,7 @@ let PDFViewerApplication = { disablePageMode: false, disablePageLabels: false, renderer: 'canvas', - enhanceTextSelection: false, + textLayerMode: TextLayerMode.ENABLE, renderInteractiveForms: false, enablePrintAutoRotate: false, }, @@ -183,10 +185,11 @@ let PDFViewerApplication = { this.eventBus.dispatch('localized'); }); - if (this.isViewerEmbedded && !PDFJS.isExternalLinkTargetSet()) { + if (this.isViewerEmbedded && + PDFJS.externalLinkTarget === LinkTarget.NONE) { // Prevent external links from "replacing" the viewer, // when it's embedded in e.g. an iframe or an object. - PDFJS.externalLinkTarget = PDFJS.LinkTarget.TOP; + PDFJS.externalLinkTarget = LinkTarget.TOP; } this.initialized = true; @@ -201,7 +204,7 @@ let PDFViewerApplication = { return Promise.all([ preferences.get('enableWebGL').then(function resolved(value) { - PDFJS.disableWebGL = !value; + viewerPrefs['enableWebGL'] = value; }), preferences.get('sidebarViewOnLoad').then(function resolved(value) { viewerPrefs['sidebarViewOnLoad'] = value; @@ -215,14 +218,11 @@ let PDFViewerApplication = { preferences.get('defaultZoomValue').then(function resolved(value) { viewerPrefs['defaultZoomValue'] = value; }), - preferences.get('enhanceTextSelection').then(function resolved(value) { - viewerPrefs['enhanceTextSelection'] = value; - }), - preferences.get('disableTextLayer').then(function resolved(value) { - if (PDFJS.disableTextLayer === true) { + preferences.get('textLayerMode').then(function resolved(value) { + if (viewerPrefs['textLayerMode'] === TextLayerMode.DISABLE) { return; } - PDFJS.disableTextLayer = value; + viewerPrefs['textLayerMode'] = value; }), preferences.get('disableRange').then(function resolved(value) { if (PDFJS.disableRange === true) { @@ -249,7 +249,7 @@ let PDFViewerApplication = { PDFJS.useOnlyCssZoom = value; }), preferences.get('externalLinkTarget').then(function resolved(value) { - if (PDFJS.isExternalLinkTargetSet()) { + if (PDFJS.externalLinkTarget !== LinkTarget.NONE) { return; } PDFJS.externalLinkTarget = value; @@ -305,7 +305,7 @@ let PDFViewerApplication = { PDFJS.disableHistory = (hashParams['disablehistory'] === 'true'); } if ('webgl' in hashParams) { - PDFJS.disableWebGL = (hashParams['webgl'] !== 'true'); + viewerPrefs['enableWebGL'] = (hashParams['webgl'] === 'true'); } if ('useonlycsszoom' in hashParams) { PDFJS.useOnlyCssZoom = (hashParams['useonlycsszoom'] === 'true'); @@ -321,7 +321,7 @@ let PDFViewerApplication = { if ('textlayer' in hashParams) { switch (hashParams['textlayer']) { case 'off': - PDFJS.disableTextLayer = true; + viewerPrefs['textLayerMode'] = TextLayerMode.DISABLE; break; case 'visible': case 'shadow': @@ -333,8 +333,7 @@ let PDFViewerApplication = { } if ('pdfbug' in hashParams) { PDFJS.pdfBug = true; - let pdfBug = hashParams['pdfbug']; - let enabled = pdfBug.split(','); + let enabled = hashParams['pdfbug'].split(','); waitOn.push(loadAndEnablePDFBug(enabled)); } // Locale can be changed only when special debugging flags is present in @@ -353,7 +352,9 @@ let PDFViewerApplication = { * @private */ _initializeL10n() { - this.l10n = this.externalServices.createL10n(); + this.l10n = this.externalServices.createL10n({ + locale: PDFJS.locale, + }); return this.l10n.getDirection().then((dir) => { document.getElementsByTagName('html')[0].dir = dir; }); @@ -377,6 +378,8 @@ let PDFViewerApplication = { let pdfLinkService = new PDFLinkService({ eventBus, + externalLinkTarget: PDFJS.externalLinkTarget, + externalLinkRel: PDFJS.externalLinkRel, }); this.pdfLinkService = pdfLinkService; @@ -393,10 +396,14 @@ let PDFViewerApplication = { linkService: pdfLinkService, downloadManager, renderer: viewerPrefs['renderer'], + enableWebGL: viewerPrefs['enableWebGL'], l10n: this.l10n, - enhanceTextSelection: viewerPrefs['enhanceTextSelection'], + textLayerMode: viewerPrefs['textLayerMode'], + imageResourcesPath: PDFJS.imageResourcesPath, renderInteractiveForms: viewerPrefs['renderInteractiveForms'], enablePrintAutoRotate: viewerPrefs['enablePrintAutoRotate'], + useOnlyCssZoom: PDFJS.useOnlyCssZoom, + maxCanvasPixels: PDFJS.maxCanvasPixels, }); pdfRenderingQueue.setViewer(this.pdfViewer); pdfLinkService.setViewer(this.pdfViewer); @@ -561,7 +568,7 @@ let PDFViewerApplication = { support = false; } } - if (support && PDFJS.disableFullscreen === true) { + if (support && viewerCompatibilityParams['disableFullscreen'] === true) { support = false; } @@ -1168,7 +1175,7 @@ let PDFViewerApplication = { info.PDFFormatVersion + ' ' + (info.Producer || '-').trim() + ' / ' + (info.Creator || '-').trim() + ']' + ' (PDF.js: ' + (version || '-') + - (!PDFJS.disableWebGL ? ' [WebGL]' : '') + ')'); + (this.viewerPrefs['enableWebGL'] ? ' [WebGL]' : '') + ')'); let pdfTitle; if (metadata && metadata.has('dc:title')) { @@ -1550,7 +1557,6 @@ function loadAndEnablePDFBug(enabledTabs) { script.onload = function () { PDFBug.enable(enabledTabs); PDFBug.init({ - PDFJS, OPS, }, appConfig.mainContainer); resolve(); @@ -1715,8 +1721,7 @@ function webViewerPageRendered(evt) { thumbnailView.setImage(pageView); } - if (PDFJS.pdfBug && typeof Stats !== 'undefined' && Stats.enabled && - pageView.stats) { + if (typeof Stats !== 'undefined' && Stats.enabled && pageView.stats) { Stats.add(pageNumber, pageView.stats); } @@ -2005,7 +2010,7 @@ function webViewerPageChanging(evt) { } // we need to update stats - if (PDFJS.pdfBug && typeof Stats !== 'undefined' && Stats.enabled) { + if (typeof Stats !== 'undefined' && Stats.enabled) { let pageView = PDFViewerApplication.pdfViewer.getPageView(page - 1); if (pageView && pageView.stats) { Stats.add(page, pageView.stats); diff --git a/web/base_viewer.js b/web/base_viewer.js index 521b193a7..2b966379a 100644 --- a/web/base_viewer.js +++ b/web/base_viewer.js @@ -17,7 +17,7 @@ import { createPromiseCapability, PDFJS } from 'pdfjs-lib'; import { CSS_UNITS, DEFAULT_SCALE, DEFAULT_SCALE_VALUE, isValidRotation, MAX_AUTO_SCALE, NullL10n, PresentationModeState, RendererType, - SCROLLBAR_PADDING, UNKNOWN_SCALE, VERTICAL_PADDING, watchScroll + SCROLLBAR_PADDING, TextLayerMode, UNKNOWN_SCALE, VERTICAL_PADDING, watchScroll } from './ui_utils'; import { PDFRenderingQueue, RenderingStates } from './pdf_rendering_queue'; import { AnnotationLayerBuilder } from './annotation_layer_builder'; @@ -39,15 +39,26 @@ const DEFAULT_CACHE_SIZE = 10; * @property {PDFRenderingQueue} renderingQueue - (optional) The rendering * queue object. * @property {boolean} removePageBorders - (optional) Removes the border shadow - * around the pages. The default is false. - * @property {boolean} enhanceTextSelection - (optional) Enables the improved - * text selection behaviour. The default is `false`. + * around the pages. The default value is `false`. + * @property {number} textLayerMode - (optional) Controls if the text layer used + * for selection and searching is created, and if the improved text selection + * behaviour is enabled. The constants from {TextLayerMode} should be used. + * The default value is `TextLayerMode.ENABLE`. + * @property {string} imageResourcesPath - (optional) Path for image resources, + * mainly for annotation icons. Include trailing slash. * @property {boolean} renderInteractiveForms - (optional) Enables rendering of * interactive form elements. The default is `false`. * @property {boolean} enablePrintAutoRotate - (optional) Enables automatic * rotation of pages whose orientation differ from the first page upon * printing. The default is `false`. * @property {string} renderer - 'canvas' or 'svg'. The default is 'canvas'. + * @property {boolean} enableWebGL - (optional) Enables WebGL accelerated + * rendering for some operations. The default value is `false`. + * @property {boolean} useOnlyCssZoom - (optional) Enables CSS only zooming. + * The default value is `false`. + * @property {number} maxCanvasPixels - (optional) The maximum supported canvas + * size in total pixels, i.e. width * height. Use -1 for no limit. + * The default value is 4096 * 4096 (16 mega-pixels). * @property {IL10n} l10n - Localization service. */ @@ -107,10 +118,16 @@ class BaseViewer { this.linkService = options.linkService || new SimpleLinkService(); this.downloadManager = options.downloadManager || null; this.removePageBorders = options.removePageBorders || false; + this.textLayerMode = Number.isInteger(options.textLayerMode) ? + options.textLayerMode : TextLayerMode.ENABLE; this.enhanceTextSelection = options.enhanceTextSelection || false; + this.imageResourcesPath = options.imageResourcesPath || ''; this.renderInteractiveForms = options.renderInteractiveForms || false; this.enablePrintAutoRotate = options.enablePrintAutoRotate || false; this.renderer = options.renderer || RendererType.CANVAS; + this.enableWebGL = options.enableWebGL || false; + this.useOnlyCssZoom = options.useOnlyCssZoom || false; + this.maxCanvasPixels = options.maxCanvasPixels; this.l10n = options.l10n || NullL10n; this.defaultRenderingQueue = !options.renderingQueue; @@ -362,7 +379,7 @@ class BaseViewer { let viewport = pdfPage.getViewport(scale * CSS_UNITS); for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) { let textLayerFactory = null; - if (!PDFJS.disableTextLayer) { + if (this.textLayerMode !== TextLayerMode.DISABLE) { textLayerFactory = this; } let pageView = new PDFPageView({ @@ -373,10 +390,14 @@ class BaseViewer { defaultViewport: viewport.clone(), renderingQueue: this.renderingQueue, textLayerFactory, + textLayerMode: this.textLayerMode, annotationLayerFactory: this, - enhanceTextSelection: this.enhanceTextSelection, + imageResourcesPath: this.imageResourcesPath, renderInteractiveForms: this.renderInteractiveForms, renderer: this.renderer, + enableWebGL: this.enableWebGL, + useOnlyCssZoom: this.useOnlyCssZoom, + maxCanvasPixels: this.maxCanvasPixels, l10n: this.l10n, }); bindOnAfterAndBeforeDraw(pageView); @@ -872,15 +893,19 @@ class BaseViewer { /** * @param {HTMLDivElement} pageDiv * @param {PDFPage} pdfPage + * @param {string} imageResourcesPath - (optional) Path for image resources, + * mainly for annotation icons. Include trailing slash. * @param {boolean} renderInteractiveForms * @param {IL10n} l10n * @returns {AnnotationLayerBuilder} */ - createAnnotationLayerBuilder(pageDiv, pdfPage, renderInteractiveForms = false, + createAnnotationLayerBuilder(pageDiv, pdfPage, imageResourcesPath = '', + renderInteractiveForms = false, l10n = NullL10n) { return new AnnotationLayerBuilder({ pageDiv, pdfPage, + imageResourcesPath, renderInteractiveForms, linkService: this.linkService, downloadManager: this.downloadManager, diff --git a/web/chromecom.js b/web/chromecom.js index 9afeab538..533361467 100644 --- a/web/chromecom.js +++ b/web/chromecom.js @@ -342,7 +342,7 @@ ChromeExternalServices.createDownloadManager = function() { ChromeExternalServices.createPreferences = function() { return new ChromePreferences(); }; -ChromeExternalServices.createL10n = function() { +ChromeExternalServices.createL10n = function(options) { return new GenericL10n(navigator.language); }; PDFViewerApplication.externalServices = ChromeExternalServices; diff --git a/web/debugger.js b/web/debugger.js index c02f86d10..57a4ed4e4 100644 --- a/web/debugger.js +++ b/web/debugger.js @@ -462,7 +462,6 @@ var Stats = (function Stats() { manager: null, init(pdfjsLib) { this.panel.setAttribute('style', 'padding: 5px;'); - pdfjsLib.PDFJS.enableStats = true; }, enabled: false, active: false, diff --git a/web/default_preferences.json b/web/default_preferences.json index 6c7c64545..29e2515e8 100644 --- a/web/default_preferences.json +++ b/web/default_preferences.json @@ -9,10 +9,9 @@ "disableStream": false, "disableAutoFetch": false, "disableFontFace": false, - "disableTextLayer": false, + "textLayerMode": 1, "useOnlyCssZoom": false, "externalLinkTarget": 0, - "enhanceTextSelection": false, "renderer": "canvas", "renderInteractiveForms": false, "enablePrintAutoRotate": false, diff --git a/web/firefoxcom.js b/web/firefoxcom.js index 9853867b7..c5cb40640 100644 --- a/web/firefoxcom.js +++ b/web/firefoxcom.js @@ -264,7 +264,7 @@ PDFViewerApplication.externalServices = { return new FirefoxPreferences(); }, - createL10n() { + createL10n(options) { let mozL10n = document.mozL10n; // TODO refactor mozL10n.setExternalLocalizerServices return new MozL10n(mozL10n); diff --git a/web/genericcom.js b/web/genericcom.js index 29d131c5b..36412a809 100644 --- a/web/genericcom.js +++ b/web/genericcom.js @@ -17,7 +17,6 @@ import { DefaultExternalServices, PDFViewerApplication } from './app'; import { BasePreferences } from './preferences'; import { DownloadManager } from './download_manager'; import { GenericL10n } from './genericl10n'; -import { PDFJS } from 'pdfjs-lib'; if (typeof PDFJSDev !== 'undefined' && !PDFJSDev.test('GENERIC')) { throw new Error('Module "pdfjs-web/genericcom" shall not be used outside ' + @@ -49,8 +48,8 @@ GenericExternalServices.createDownloadManager = function() { GenericExternalServices.createPreferences = function() { return new GenericPreferences(); }; -GenericExternalServices.createL10n = function () { - return new GenericL10n(PDFJS.locale); +GenericExternalServices.createL10n = function(options) { + return new GenericL10n(options.locale); }; PDFViewerApplication.externalServices = GenericExternalServices; diff --git a/web/interfaces.js b/web/interfaces.js index f694a9086..455185b9b 100644 --- a/web/interfaces.js +++ b/web/interfaces.js @@ -145,11 +145,13 @@ class IPDFAnnotationLayerFactory { /** * @param {HTMLDivElement} pageDiv * @param {PDFPage} pdfPage - * @param {IL10n} l10n + * @param {string} imageResourcesPath - (optional) Path for image resources, + * mainly for annotation icons. Include trailing slash. * @param {boolean} renderInteractiveForms + * @param {IL10n} l10n * @returns {AnnotationLayerBuilder} */ - createAnnotationLayerBuilder(pageDiv, pdfPage, + createAnnotationLayerBuilder(pageDiv, pdfPage, imageResourcesPath = '', renderInteractiveForms = false, l10n = undefined) {} } diff --git a/web/pdf_link_service.js b/web/pdf_link_service.js index 7062a69ae..91df46320 100644 --- a/web/pdf_link_service.js +++ b/web/pdf_link_service.js @@ -19,6 +19,11 @@ import { parseQueryString } from './ui_utils'; /** * @typedef {Object} PDFLinkServiceOptions * @property {EventBus} eventBus - The application event bus. + * @property {number} externalLinkTarget - (optional) Specifies the `target` + * attribute for external links. Must use one of the values from {LinkTarget}. + * Defaults to using no target. + * @property {string} externalLinkRel - (optional) Specifies the `rel` attribute + * for external links. Defaults to stripping the referrer. */ /** @@ -30,8 +35,12 @@ class PDFLinkService { /** * @param {PDFLinkServiceOptions} options */ - constructor({ eventBus, } = {}) { + constructor({ eventBus, externalLinkTarget = null, + externalLinkRel = null, } = {}) { this.eventBus = eventBus || getGlobalEventBus(); + this.externalLinkTarget = externalLinkTarget; + this.externalLinkRel = externalLinkRel; + this.baseUrl = null; this.pdfDocument = null; this.pdfViewer = null; @@ -409,6 +418,11 @@ function isValidExplicitDestination(dest) { } class SimpleLinkService { + constructor() { + this.externalLinkTarget = null; + this.externalLinkRel = null; + } + /** * @returns {number} */ diff --git a/web/pdf_outline_viewer.js b/web/pdf_outline_viewer.js index 7aee5b626..05b94016c 100644 --- a/web/pdf_outline_viewer.js +++ b/web/pdf_outline_viewer.js @@ -13,9 +13,7 @@ * limitations under the License. */ -import { - addLinkAttributes, PDFJS, removeNullCharacters -} from 'pdfjs-lib'; +import { addLinkAttributes, LinkTarget, removeNullCharacters } from 'pdfjs-lib'; const DEFAULT_TITLE = '\u2013'; @@ -68,20 +66,22 @@ class PDFOutlineViewer { /** * @private */ - _bindLink(element, item) { - if (item.url) { + _bindLink(element, { url, newWindow, dest, }) { + let { linkService, } = this; + + if (url) { addLinkAttributes(element, { - url: item.url, - target: (item.newWindow ? PDFJS.LinkTarget.BLANK : undefined), + url, + target: (newWindow ? LinkTarget.BLANK : linkService.externalLinkTarget), + rel: linkService.externalLinkRel, }); return; } - let destination = item.dest; - element.href = this.linkService.getDestinationHash(destination); + element.href = this.linkService.getDestinationHash(dest); element.onclick = () => { - if (destination) { - this.linkService.navigateTo(destination); + if (dest) { + this.linkService.navigateTo(dest); } return false; }; @@ -90,12 +90,12 @@ class PDFOutlineViewer { /** * @private */ - _setStyles(element, item) { + _setStyles(element, { bold, italic, }) { let styleStr = ''; - if (item.bold) { + if (bold) { styleStr += 'font-weight: bold;'; } - if (item.italic) { + if (italic) { styleStr += 'font-style: italic;'; } diff --git a/web/pdf_page_view.js b/web/pdf_page_view.js index 50e1ac1a3..3b4f91425 100644 --- a/web/pdf_page_view.js +++ b/web/pdf_page_view.js @@ -15,13 +15,14 @@ import { approximateFraction, CSS_UNITS, DEFAULT_SCALE, getOutputScale, NullL10n, - RendererType, roundToDivide + RendererType, roundToDivide, TextLayerMode } from './ui_utils'; import { - createPromiseCapability, PDFJS, RenderingCancelledException, SVGGraphics + createPromiseCapability, RenderingCancelledException, SVGGraphics } from 'pdfjs-lib'; import { getGlobalEventBus } from './dom_events'; import { RenderingStates } from './pdf_rendering_queue'; +import { viewerCompatibilityParams } from './viewer_compatibility'; /** * @typedef {Object} PDFPageViewOptions @@ -32,15 +33,28 @@ import { RenderingStates } from './pdf_rendering_queue'; * @property {PageViewport} defaultViewport - The page viewport. * @property {PDFRenderingQueue} renderingQueue - The rendering queue object. * @property {IPDFTextLayerFactory} textLayerFactory + * @property {number} textLayerMode - (optional) Controls if the text layer used + * for selection and searching is created, and if the improved text selection + * behaviour is enabled. The constants from {TextLayerMode} should be used. + * The default value is `TextLayerMode.ENABLE`. * @property {IPDFAnnotationLayerFactory} annotationLayerFactory - * @property {boolean} enhanceTextSelection - Turns on the text selection - * enhancement. The default is `false`. + * @property {string} imageResourcesPath - (optional) Path for image resources, + * mainly for annotation icons. Include trailing slash. * @property {boolean} renderInteractiveForms - Turns on rendering of * interactive form elements. The default is `false`. * @property {string} renderer - 'canvas' or 'svg'. The default is 'canvas'. + * @property {boolean} enableWebGL - (optional) Enables WebGL accelerated + * rendering for some operations. The default value is `false`. + * @property {boolean} useOnlyCssZoom - (optional) Enables CSS only zooming. + * The default value is `false`. + * @property {number} maxCanvasPixels - (optional) The maximum supported canvas + * size in total pixels, i.e. width * height. Use -1 for no limit. + * The default value is 4096 * 4096 (16 mega-pixels). * @property {IL10n} l10n - Localization service. */ +const MAX_CANVAS_PIXELS = viewerCompatibilityParams.maxCanvasPixels || 16777216; + /** * @implements {IRenderableView} */ @@ -62,14 +76,19 @@ class PDFPageView { this.viewport = defaultViewport; this.pdfPageRotate = defaultViewport.rotation; this.hasRestrictedScaling = false; - this.enhanceTextSelection = options.enhanceTextSelection || false; + this.textLayerMode = Number.isInteger(options.textLayerMode) ? + options.textLayerMode : TextLayerMode.ENABLE; + this.imageResourcesPath = options.imageResourcesPath || ''; this.renderInteractiveForms = options.renderInteractiveForms || false; + this.useOnlyCssZoom = options.useOnlyCssZoom || false; + this.maxCanvasPixels = options.maxCanvasPixels || MAX_CANVAS_PIXELS; this.eventBus = options.eventBus || getGlobalEventBus(); this.renderingQueue = options.renderingQueue; this.textLayerFactory = options.textLayerFactory; this.annotationLayerFactory = options.annotationLayerFactory; this.renderer = options.renderer || RendererType.CANVAS; + this.enableWebGL = options.enableWebGL || false; this.l10n = options.l10n || NullL10n; this.paintTask = null; @@ -208,17 +227,17 @@ class PDFPageView { } let isScalingRestricted = false; - if (this.canvas && PDFJS.maxCanvasPixels > 0) { + if (this.canvas && this.maxCanvasPixels > 0) { let outputScale = this.outputScale; if (((Math.floor(this.viewport.width) * outputScale.sx) | 0) * ((Math.floor(this.viewport.height) * outputScale.sy) | 0) > - PDFJS.maxCanvasPixels) { + this.maxCanvasPixels) { isScalingRestricted = true; } } if (this.canvas) { - if (PDFJS.useOnlyCssZoom || + if (this.useOnlyCssZoom || (this.hasRestrictedScaling && isScalingRestricted)) { this.cssTransform(this.canvas, true); @@ -371,7 +390,7 @@ class PDFPageView { } let textLayer = null; - if (this.textLayerFactory) { + if (this.textLayerMode !== TextLayerMode.DISABLE && this.textLayerFactory) { let textLayerDiv = document.createElement('div'); textLayerDiv.className = 'textLayer'; textLayerDiv.style.width = canvasWrapper.style.width; @@ -385,7 +404,7 @@ class PDFPageView { textLayer = this.textLayerFactory. createTextLayerBuilder(textLayerDiv, this.id - 1, this.viewport, - this.enhanceTextSelection); + this.textLayerMode === TextLayerMode.ENABLE_ENHANCE); } this.textLayer = textLayer; @@ -465,7 +484,7 @@ class PDFPageView { if (this.annotationLayerFactory) { if (!this.annotationLayer) { this.annotationLayer = this.annotationLayerFactory. - createAnnotationLayerBuilder(div, pdfPage, + createAnnotationLayerBuilder(div, pdfPage, this.imageResourcesPath, this.renderInteractiveForms, this.l10n); } this.annotationLayer.render(this.viewport, 'display'); @@ -517,7 +536,7 @@ class PDFPageView { let outputScale = getOutputScale(ctx); this.outputScale = outputScale; - if (PDFJS.useOnlyCssZoom) { + if (this.useOnlyCssZoom) { let actualSizeViewport = viewport.clone({ scale: CSS_UNITS, }); // Use a scale that makes the canvas have the originally intended size // of the page. @@ -526,9 +545,9 @@ class PDFPageView { outputScale.scaled = true; } - if (PDFJS.maxCanvasPixels > 0) { + if (this.maxCanvasPixels > 0) { let pixelsInViewport = viewport.width * viewport.height; - let maxScale = Math.sqrt(PDFJS.maxCanvasPixels / pixelsInViewport); + let maxScale = Math.sqrt(this.maxCanvasPixels / pixelsInViewport); if (outputScale.sx > maxScale || outputScale.sy > maxScale) { outputScale.sx = maxScale; outputScale.sy = maxScale; @@ -555,6 +574,7 @@ class PDFPageView { canvasContext: ctx, transform, viewport: this.viewport, + enableWebGL: this.enableWebGL, renderInteractiveForms: this.renderInteractiveForms, }; let renderTask = this.pdfPage.render(renderContext); diff --git a/web/ui_utils.js b/web/ui_utils.js index bfff86ae5..ec45ac04c 100644 --- a/web/ui_utils.js +++ b/web/ui_utils.js @@ -37,6 +37,12 @@ const RendererType = { SVG: 'svg', }; +const TextLayerMode = { + DISABLE: 0, + ENABLE: 1, + ENABLE_ENHANCE: 2, +}; + // Replaces {{arguments}} with their values. function formatL10nValue(text, args) { if (!args) { @@ -65,14 +71,6 @@ let NullL10n = { }, }; -/** - * Disables fullscreen support, and by extension Presentation Mode, - * in browsers which support the fullscreen API. - * @var {boolean} - */ -PDFJS.disableFullscreen = (PDFJS.disableFullscreen === undefined ? - false : PDFJS.disableFullscreen); - /** * Enables CSS only zooming. * @var {boolean} @@ -95,13 +93,6 @@ PDFJS.maxCanvasPixels = (PDFJS.maxCanvasPixels === undefined ? PDFJS.disableHistory = (PDFJS.disableHistory === undefined ? false : PDFJS.disableHistory); -/** - * Disables creation of the text layer that used for text selection and search. - * @var {boolean} - */ -PDFJS.disableTextLayer = (PDFJS.disableTextLayer === undefined ? - false : PDFJS.disableTextLayer); - if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('FIREFOX || MOZCENTRAL')) { /** @@ -110,7 +101,7 @@ if (typeof PDFJSDev === 'undefined' || */ PDFJS.locale = (PDFJS.locale === undefined && typeof navigator !== 'undefined' ? - navigator.language : PDFJS.locale); + navigator.language : PDFJS.locale) || 'en-US'; } /** @@ -677,6 +668,7 @@ export { cloneObj, PresentationModeState, RendererType, + TextLayerMode, mozL10n, NullL10n, EventBus, diff --git a/web/viewer_compatibility.js b/web/viewer_compatibility.js new file mode 100644 index 000000000..e6aadea80 --- /dev/null +++ b/web/viewer_compatibility.js @@ -0,0 +1,44 @@ +/* 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 isAndroid = /Android/.test(userAgent); + const isIE = /Trident/.test(userAgent); + const isIOS = /\b(iPad|iPhone|iPod)(?=;)/.test(userAgent); + + // Disable fullscreen support for certain problematic configurations. + // Support: IE11+ (when embedded). + (function checkFullscreenSupport() { + if (isIE && window.parent !== window) { + compatibilityParams.disableFullscreen = true; + } + })(); + + // Limit canvas size to 5 mega-pixels on mobile. + // Support: Android, iOS + (function checkCanvasSizeLimitation() { + if (isIOS || isAndroid) { + compatibilityParams.maxCanvasPixels = 5242880; + } + })(); +} +const viewerCompatibilityParams = Object.freeze(compatibilityParams); + +export { + viewerCompatibilityParams, +};