diff --git a/src/core/bidi.js b/src/core/bidi.js index 1648e361dfd4b5..041448337f8f96 100644 --- a/src/core/bidi.js +++ b/src/core/bidi.js @@ -17,17 +17,14 @@ (function (root, factory) { if (typeof define === 'function' && define.amd) { - define('pdfjs/core/bidi', ['exports', 'pdfjs/shared/global'], factory); + define('pdfjs/core/bidi', ['exports'], factory); } else if (typeof exports !== 'undefined') { - factory(exports, require('../shared/global.js')); + factory(exports); } else { - factory((root.pdfjsCoreBidi = {}), root.pdfjsSharedGlobal); + factory((root.pdfjsCoreBidi = {})); } -}(this, function (exports, sharedGlobal) { +}(this, function (exports) { -var PDFJS = sharedGlobal.PDFJS; - -var bidi = PDFJS.bidi = (function bidiClosure() { // Character types for symbols from 0000 to 00FF. var baseTypes = [ 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'S', 'B', 'S', 'WS', @@ -430,8 +427,5 @@ var bidi = PDFJS.bidi = (function bidiClosure() { return createBidiText(chars.join(''), isLTR); } - return bidi; -})(); - exports.bidi = bidi; })); diff --git a/src/core/cmap.js b/src/core/cmap.js index f68fa0a53fcd07..273235076df99f 100644 --- a/src/core/cmap.js +++ b/src/core/cmap.js @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* globals PDFJS */ +/* globals window */ 'use strict'; @@ -424,7 +424,7 @@ var IdentityCMap = (function IdentityCMapClosure() { var BinaryCMapReader = (function BinaryCMapReaderClosure() { function fetchBinaryData(url) { - var nonBinaryRequest = PDFJS.disableWorker; + var nonBinaryRequest = typeof window !== 'undefined'; var request = new XMLHttpRequest(); request.open('GET', url, false); if (!nonBinaryRequest) { diff --git a/src/core/document.js b/src/core/document.js index a22019ccae9dc8..5e3b72654f5d39 100644 --- a/src/core/document.js +++ b/src/core/document.js @@ -79,6 +79,7 @@ var Page = (function PageClosure() { this.idCounters = { obj: 0 }; + this.evaluatorOptions = pdfManager.evaluatorOptions; this.resourcesPromise = null; } @@ -224,7 +225,8 @@ var Page = (function PageClosure() { handler, this.pageIndex, 'p' + this.pageIndex + '_', this.idCounters, - this.fontCache); + this.fontCache, + this.evaluatorOptions); var dataPromises = Promise.all([contentStreamPromise, resourcesPromise]); var pageListPromise = dataPromises.then(function(data) { @@ -289,7 +291,8 @@ var Page = (function PageClosure() { handler, self.pageIndex, 'p' + self.pageIndex + '_', self.idCounters, - self.fontCache); + self.fontCache, + self.evaluatorOptions); return partialEvaluator.getTextContent(contentStream, task, diff --git a/src/core/evaluator.js b/src/core/evaluator.js index df4fa095344a4f..574b4ba68346bb 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -12,7 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* globals PDFJS */ 'use strict'; @@ -105,8 +104,15 @@ var getNormalizedUnicodes = coreUnicode.getNormalizedUnicodes; var reverseIfRtl = coreUnicode.reverseIfRtl; var PartialEvaluator = (function PartialEvaluatorClosure() { + var DefaultPartialEvaluatorOptions = { + forceDataSchema: false, + maxImageSize: -1, + disableFontFace: false, + cmapOptions: { url: null, packed: false } + }; + function PartialEvaluator(pdfManager, xref, handler, pageIndex, - uniquePrefix, idCounters, fontCache) { + uniquePrefix, idCounters, fontCache, options) { this.pdfManager = pdfManager; this.xref = xref; this.handler = handler; @@ -114,6 +120,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { this.uniquePrefix = uniquePrefix; this.idCounters = idCounters; this.fontCache = fontCache; + this.options = options || DefaultPartialEvaluatorOptions; } // Trying to minimize Date.now() usage and check every 100 time @@ -272,7 +279,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { warn('Image dimensions are missing, or not numbers.'); return; } - if (PDFJS.maxImageSize !== -1 && w * h > PDFJS.maxImageSize) { + var maxImageSize = this.options.maxImageSize; + if (maxImageSize !== -1 && w * h > maxImageSize) { warn('Image exceeded maximum allowed size and was removed.'); return; } @@ -336,11 +344,13 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { // These JPEGs don't need any more processing so we can just send it. operatorList.addOp(OPS.paintJpegXObject, args); this.handler.send('obj', - [objId, this.pageIndex, 'JpegStream', image.getIR()]); + [objId, this.pageIndex, 'JpegStream', + image.getIR(this.options.forceDataSchema)]); return; } - PDFImage.buildImage(self.handler, self.xref, resources, image, inline). + PDFImage.buildImage(self.handler, self.xref, resources, image, inline, + this.options.forceDataSchema). then(function(imageObj) { var imgData = imageObj.createImageData(/* forceRGBA = */ false); self.handler.send('obj', [objId, self.pageIndex, 'Image', imgData], @@ -448,7 +458,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { var glyphs = font.charsToGlyphs(chars); var isAddToPathSet = !!(state.textRenderingMode & TextRenderingMode.ADD_TO_PATH_FLAG); - if (font.data && (isAddToPathSet || PDFJS.disableFontFace)) { + if (font.data && (isAddToPathSet || this.options.disableFontFace)) { var buildPath = function (fontChar) { if (!font.renderer.hasBuiltPath(fontChar)) { var path = font.renderer.getPathJs(fontChar); @@ -1172,7 +1182,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { function runBidiTransform(textChunk) { var str = textChunk.str.join(''); - var bidiResult = PDFJS.bidi(str, -1, textChunk.vertical); + var bidiResult = bidi(str, -1, textChunk.vertical); return { str: (normalizeWhitespace ? replaceWhitespace(bidiResult.str) : bidiResult.str), @@ -1642,15 +1652,13 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { readToUnicode: function PartialEvaluator_readToUnicode(toUnicode) { var cmap, cmapObj = toUnicode; if (isName(cmapObj)) { - cmap = CMapFactory.create(cmapObj, - { url: PDFJS.cMapUrl, packed: PDFJS.cMapPacked }, null); + cmap = CMapFactory.create(cmapObj, this.options.cmapOptions, null); if (cmap instanceof IdentityCMap) { return new IdentityToUnicodeMap(0, 0xFFFF); } return new ToUnicodeMap(cmap.getMap()); } else if (isStream(cmapObj)) { - cmap = CMapFactory.create(cmapObj, - { url: PDFJS.cMapUrl, packed: PDFJS.cMapPacked }, null); + cmap = CMapFactory.create(cmapObj, this.options.cmapOptions, null); if (cmap instanceof IdentityCMap) { return new IdentityToUnicodeMap(0, 0xFFFF); } @@ -2064,7 +2072,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { properties.cidEncoding = cidEncoding.name; } properties.cMap = CMapFactory.create(cidEncoding, - { url: PDFJS.cMapUrl, packed: PDFJS.cMapPacked }, null); + this.options.cmapOptions, null); properties.vertical = properties.cMap.vertical; } this.extractDataStructures(dict, baseDict, xref, properties); diff --git a/src/core/fonts.js b/src/core/fonts.js index 3504ce518dfc33..f5a6f6dd12e5c7 100644 --- a/src/core/fonts.js +++ b/src/core/fonts.js @@ -12,7 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* globals PDFJS */ 'use strict'; @@ -464,7 +463,7 @@ var ProblematicCharRanges = new Int32Array([ * type1Font.bind(); */ var Font = (function FontClosure() { - function Font(name, file, properties) { + function Font(name, file, properties, cmapOptions) { var charCode, glyphName, fontChar; this.name = name; @@ -500,7 +499,8 @@ var Font = (function FontClosure() { this.fontMatrix = properties.fontMatrix; this.bbox = properties.bbox; - this.toUnicode = properties.toUnicode = this.buildToUnicode(properties); + this.toUnicode = properties.toUnicode = + this.buildToUnicode(properties, cmapOptions); this.toFontChar = []; @@ -2632,7 +2632,7 @@ var Font = (function FontClosure() { * @param {Object} properties Font properties object. * @return {Object} A ToUnicodeMap object. */ - buildToUnicode: function Font_buildToUnicode(properties) { + buildToUnicode: function Font_buildToUnicode(properties, cmapOptions) { // Section 9.10.2 Mapping Character Codes to Unicode Values if (properties.toUnicode && properties.toUnicode.length !== 0) { return properties.toUnicode; @@ -2730,8 +2730,7 @@ var Font = (function FontClosure() { var ucs2CMapName = new Name(registry + '-' + ordering + '-UCS2'); // d) Obtain the CMap with the name constructed in step (c) (available // from the ASN Web site; see the Bibliography). - var ucs2CMap = CMapFactory.create(ucs2CMapName, - { url: PDFJS.cMapUrl, packed: PDFJS.cMapPacked }, null); + var ucs2CMap = CMapFactory.create(ucs2CMapName, cmapOptions, null); var cMap = properties.cMap; toUnicode = []; cMap.forEach(function(charcode, cid) { diff --git a/src/core/image.js b/src/core/image.js index 6329f9d40a2756..40009aef2f6926 100644 --- a/src/core/image.js +++ b/src/core/image.js @@ -51,7 +51,7 @@ var PDFImage = (function PDFImageClosure() { * Decode the image in the main thread if it supported. Resovles the promise * when the image data is ready. */ - function handleImageData(handler, xref, res, image) { + function handleImageData(handler, xref, res, image, forceDataSchema) { if (image instanceof JpegStream && image.isNativelyDecodable(xref, res)) { // For natively supported jpegs send them to the main thread for decoding. var dict = image.dict; @@ -59,7 +59,8 @@ var PDFImage = (function PDFImageClosure() { colorSpace = ColorSpace.parse(colorSpace, xref, res); var numComps = colorSpace.numComps; var decodePromise = handler.sendWithPromise('JpegDecode', - [image.getIR(), numComps]); + [image.getIR(forceDataSchema), + numComps]); return decodePromise.then(function (message) { var data = message.data; return new Stream(data, 0, data.length, image.dict); @@ -184,8 +185,10 @@ var PDFImage = (function PDFImageClosure() { * with a PDFImage when the image is ready to be used. */ PDFImage.buildImage = function PDFImage_buildImage(handler, xref, - res, image, inline) { - var imagePromise = handleImageData(handler, xref, res, image); + res, image, inline, + forceDataSchema) { + var imagePromise = handleImageData(handler, xref, res, image, + forceDataSchema); var smaskPromise; var maskPromise; @@ -193,13 +196,15 @@ var PDFImage = (function PDFImageClosure() { var mask = image.dict.get('Mask'); if (smask) { - smaskPromise = handleImageData(handler, xref, res, smask); + smaskPromise = handleImageData(handler, xref, res, smask, + forceDataSchema); maskPromise = Promise.resolve(null); } else { smaskPromise = Promise.resolve(null); if (mask) { if (isStream(mask)) { - maskPromise = handleImageData(handler, xref, res, mask); + maskPromise = handleImageData(handler, xref, res, mask, + forceDataSchema); } else if (isArray(mask)) { maskPromise = Promise.resolve(mask); } else { diff --git a/src/core/pdf_manager.js b/src/core/pdf_manager.js index 8c6fd9b12c268e..bd5f7933d52fce 100644 --- a/src/core/pdf_manager.js +++ b/src/core/pdf_manager.js @@ -110,8 +110,9 @@ var BasePdfManager = (function BasePdfManagerClosure() { })(); var LocalPdfManager = (function LocalPdfManagerClosure() { - function LocalPdfManager(docId, data, password) { + function LocalPdfManager(docId, data, password, evaluatorOptions) { this._docId = docId; + this.evaluatorOptions = evaluatorOptions; var stream = new Stream(data); this.pdfDocument = new PDFDocument(this, stream, password); this._loadedStreamCapability = createPromiseCapability(); @@ -157,9 +158,10 @@ var LocalPdfManager = (function LocalPdfManagerClosure() { })(); var NetworkPdfManager = (function NetworkPdfManagerClosure() { - function NetworkPdfManager(docId, pdfNetworkStream, args) { + function NetworkPdfManager(docId, pdfNetworkStream, args, evaluatorOptions) { this._docId = docId; this.msgHandler = args.msgHandler; + this.evaluatorOptions = evaluatorOptions; var params = { msgHandler: args.msgHandler, diff --git a/src/core/stream.js b/src/core/stream.js index fceff08fdf9359..470e99d3e477d1 100644 --- a/src/core/stream.js +++ b/src/core/stream.js @@ -12,7 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* globals PDFJS */ 'use strict'; @@ -36,6 +35,7 @@ var Util = sharedUtil.Util; var error = sharedUtil.error; var info = sharedUtil.info; var isArray = sharedUtil.isArray; +var createObjectURL = sharedUtil.createObjectURL; var shadow = sharedUtil.shadow; var warn = sharedUtil.warn; var Dict = corePrimitives.Dict; @@ -963,8 +963,8 @@ var JpegStream = (function JpegStreamClosure() { return this.buffer; }; - JpegStream.prototype.getIR = function JpegStream_getIR() { - return PDFJS.createObjectURL(this.bytes, 'image/jpeg'); + JpegStream.prototype.getIR = function JpegStream_getIR(forceDataSchema) { + return createObjectURL(this.bytes, 'image/jpeg', forceDataSchema); }; /** * Checks if the image can be decoded and displayed by the browser without any diff --git a/src/core/worker.js b/src/core/worker.js index f7fb7a2e475656..cdf804b3e93fd2 100644 --- a/src/core/worker.js +++ b/src/core/worker.js @@ -19,18 +19,16 @@ (function (root, factory) { if (typeof define === 'function' && define.amd) { define('pdfjs/core/worker', ['exports', 'pdfjs/shared/util', - 'pdfjs/core/primitives', 'pdfjs/core/pdf_manager', 'pdfjs/shared/global'], + 'pdfjs/core/primitives', 'pdfjs/core/pdf_manager'], factory); } else if (typeof exports !== 'undefined') { factory(exports, require('../shared/util.js'), require('./primitives.js'), - require('./pdf_manager.js'), require('../shared/global.js')); + require('./pdf_manager.js')); } else { factory((root.pdfjsCoreWorker = {}), root.pdfjsSharedUtil, - root.pdfjsCorePrimitives, root.pdfjsCorePdfManager, - root.pdfjsSharedGlobal); + root.pdfjsCorePrimitives, root.pdfjsCorePdfManager); } -}(this, function (exports, sharedUtil, corePrimitives, corePdfManager, - sharedGlobal) { +}(this, function (exports, sharedUtil, corePrimitives, corePdfManager) { var UNSUPPORTED_FEATURES = sharedUtil.UNSUPPORTED_FEATURES; var InvalidPDFException = sharedUtil.InvalidPDFException; @@ -48,11 +46,11 @@ var createPromiseCapability = sharedUtil.createPromiseCapability; var error = sharedUtil.error; var info = sharedUtil.info; var warn = sharedUtil.warn; +var setVerbosityLevel = sharedUtil.setVerbosityLevel; var Ref = corePrimitives.Ref; var LocalPdfManager = corePdfManager.LocalPdfManager; var NetworkPdfManager = corePdfManager.NetworkPdfManager; -var globalScope = sharedGlobal.globalScope; -var PDFJS = sharedGlobal.PDFJS; +var globalScope = sharedUtil.globalScope; var WorkerTask = (function WorkerTaskClosure() { function WorkerTask(name) { @@ -428,7 +426,7 @@ function setPDFNetworkStreamClass(cls) { PDFNetworkStream = cls; } -var WorkerMessageHandler = PDFJS.WorkerMessageHandler = { +var WorkerMessageHandler = { setup: function wphSetup(handler, port) { var testMessageProcessed = false; handler.on('test', function wphSetupTest(data) { @@ -529,14 +527,15 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = { return loadDocumentCapability.promise; } - function getPdfManager(data) { + function getPdfManager(data, evaluatorOptions) { var pdfManagerCapability = createPromiseCapability(); var pdfManager; var source = data.source; if (source.data) { try { - pdfManager = new LocalPdfManager(docId, source.data, source.password); + pdfManager = new LocalPdfManager(docId, source.data, source.password, + evaluatorOptions); pdfManagerCapability.resolve(pdfManager); } catch (ex) { pdfManagerCapability.reject(ex); @@ -585,7 +584,7 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = { length: fullRequest.contentLength, disableAutoFetch: disableAutoFetch, rangeChunkSize: source.rangeChunkSize - }); + }, evaluatorOptions); pdfManagerCapability.resolve(pdfManager); cancelXHRs = null; }).catch(function (reason) { @@ -681,16 +680,21 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = { ensureNotTerminated(); - PDFJS.maxImageSize = data.maxImageSize === undefined ? - -1 : data.maxImageSize; - PDFJS.disableFontFace = data.disableFontFace; - PDFJS.disableCreateObjectURL = data.disableCreateObjectURL; - PDFJS.verbosity = data.verbosity; - PDFJS.cMapUrl = data.cMapUrl === undefined ? - null : data.cMapUrl; - PDFJS.cMapPacked = data.cMapPacked === true; + var cmapOptions = { + url: data.cMapUrl === undefined ? null : data.cMapUrl, + packed: data.cMapPacked === true + }; + var evaluatorOptions = { + forceDataSchema: data.disableCreateObjectURL, + maxImageSize: data.maxImageSize === undefined ? -1 : data.maxImageSize, + disableFontFace: data.disableFontFace, + cmapOptions: cmapOptions + }; + + // TODO move it to the worker options synchronization place (vs document). + setVerbosityLevel(data.verbosity); - getPdfManager(data).then(function (newPdfManager) { + getPdfManager(data, evaluatorOptions).then(function (newPdfManager) { if (terminated) { // We were in a process of setting up the manager, but it got // terminated in the middle. @@ -985,6 +989,11 @@ function initializeWorker() { handler.send('ready', null); } +if (globalScope.PDFJS) { + // TODO properly handle WorkerMessageHandler as a module export at api.js. + globalScope.PDFJS.WorkerMessageHandler = WorkerMessageHandler; +} + // Worker thread (and not node.js)? if (typeof window === 'undefined' && !(typeof module !== 'undefined' && module.require)) { diff --git a/src/display/annotation_layer.js b/src/display/annotation_layer.js index ea038f2bb92d53..d4939a3aca269c 100644 --- a/src/display/annotation_layer.js +++ b/src/display/annotation_layer.js @@ -31,8 +31,8 @@ var AnnotationBorderStyleType = sharedUtil.AnnotationBorderStyleType; var AnnotationType = sharedUtil.AnnotationType; var Util = sharedUtil.Util; -var addLinkAttributes = sharedUtil.addLinkAttributes; -var getFilenameFromUrl = sharedUtil.getFilenameFromUrl; +var addLinkAttributes = displayDOMUtils.addLinkAttributes; +var getFilenameFromUrl = displayDOMUtils.getFilenameFromUrl; var warn = sharedUtil.warn; var CustomStyle = displayDOMUtils.CustomStyle; diff --git a/src/display/api.js b/src/display/api.js index a9b2432562660d..97da03ad7d3a16 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -20,18 +20,20 @@ if (typeof define === 'function' && define.amd) { define('pdfjs/display/api', ['exports', 'pdfjs/shared/util', 'pdfjs/display/font_loader', 'pdfjs/display/canvas', - 'pdfjs/display/metadata', 'pdfjs/shared/global', 'require'], factory); + 'pdfjs/display/metadata', 'pdfjs/display/dom_utils', + 'pdfjs/shared/global', 'require'], factory); } else if (typeof exports !== 'undefined') { factory(exports, require('../shared/util.js'), require('./font_loader.js'), require('./canvas.js'), require('./metadata.js'), - require('../shared/global.js')); + require('./dom_utils.js'), require('../shared/global.js')); } else { factory((root.pdfjsDisplayAPI = {}), root.pdfjsSharedUtil, root.pdfjsDisplayFontLoader, root.pdfjsDisplayCanvas, - root.pdfjsDisplayMetadata, root.pdfjsSharedGlobal); + root.pdfjsDisplayMetadata, root.pdfjsDisplayDOMUtils, + root.pdfjsSharedGlobal); } }(this, function (exports, sharedUtil, displayFontLoader, displayCanvas, - displayMetadata, sharedGlobal, amdRequire) { + displayMetadata, displayDOMUtils, sharedGlobal, amdRequire) { var InvalidPDFException = sharedUtil.InvalidPDFException; var MessageHandler = sharedUtil.MessageHandler; diff --git a/src/display/canvas.js b/src/display/canvas.js index bd9f68e289f02e..c3234c70727c11 100644 --- a/src/display/canvas.js +++ b/src/display/canvas.js @@ -19,15 +19,18 @@ (function (root, factory) { if (typeof define === 'function' && define.amd) { define('pdfjs/display/canvas', ['exports', 'pdfjs/shared/util', - 'pdfjs/display/pattern_helper', 'pdfjs/display/webgl'], factory); + 'pdfjs/display/dom_utils', 'pdfjs/display/pattern_helper', + 'pdfjs/display/webgl'], factory); } else if (typeof exports !== 'undefined') { - factory(exports, require('../shared/util.js'), + factory(exports, require('../shared/util.js'), require('./dom_utils.js'), require('./pattern_helper.js'), require('./webgl.js')); } else { factory((root.pdfjsDisplayCanvas = {}), root.pdfjsSharedUtil, - root.pdfjsDisplayPatternHelper, root.pdfjsDisplayWebGL); + root.pdfjsDisplayDOMUtils, root.pdfjsDisplayPatternHelper, + root.pdfjsDisplayWebGL); } -}(this, function (exports, sharedUtil, displayPatternHelper, displayWebGL) { +}(this, function (exports, sharedUtil, displayDOMUtils, displayPatternHelper, + displayWebGL) { var FONT_IDENTITY_MATRIX = sharedUtil.FONT_IDENTITY_MATRIX; var IDENTITY_MATRIX = sharedUtil.IDENTITY_MATRIX; diff --git a/src/display/dom_utils.js b/src/display/dom_utils.js index d67c612487baad..f061b53a3aaa98 100644 --- a/src/display/dom_utils.js +++ b/src/display/dom_utils.js @@ -17,15 +17,21 @@ (function (root, factory) { if (typeof define === 'function' && define.amd) { - define('pdfjs/display/dom_utils', ['exports', 'pdfjs/shared/global'], - factory); + define('pdfjs/display/dom_utils', ['exports', 'pdfjs/shared/util', + 'pdfjs/shared/global'], factory); } else if (typeof exports !== 'undefined') { - factory(exports, require('../shared/global.js')); + factory(exports, require('../shared/util.js'), + require('../shared/global.js')); } else { - factory((root.pdfjsDisplayDOMUtils = {}), root.pdfjsSharedGlobal); + factory((root.pdfjsDisplayDOMUtils = {}), root.pdfjsSharedUtil, + root.pdfjsSharedGlobal); } -}(this, function (exports, sharedGlobal) { +}(this, function (exports, sharedUtil, sharedGlobal) { +var deprecated = sharedUtil.deprecated; +var removeNullCharacters = sharedUtil.removeNullCharacters; +var shadow = sharedUtil.shadow; +var warn = sharedUtil.warn; var PDFJS = sharedGlobal.PDFJS; /** @@ -84,5 +90,106 @@ var CustomStyle = (function CustomStyleClosure() { PDFJS.CustomStyle = CustomStyle; +//#if !(FIREFOX || MOZCENTRAL || CHROME) +//// Lazy test if the userAgent support CanvasTypedArrays +function hasCanvasTypedArrays() { + var canvas = document.createElement('canvas'); + canvas.width = canvas.height = 1; + var ctx = canvas.getContext('2d'); + var imageData = ctx.createImageData(1, 1); + return (typeof imageData.data.buffer !== 'undefined'); +} + +Object.defineProperty(PDFJS, 'hasCanvasTypedArrays', { + configurable: true, + get: function PDFJS_hasCanvasTypedArrays() { + return shadow(PDFJS, 'hasCanvasTypedArrays', hasCanvasTypedArrays()); + } +}); +//#else +//PDFJS.hasCanvasTypedArrays = true; +//#endif + +var LinkTarget = { + NONE: 0, // Default value. + SELF: 1, + BLANK: 2, + PARENT: 3, + TOP: 4, +}; + +PDFJS.LinkTarget = LinkTarget; + +var LinkTargetStringMap = [ + '', + '_self', + '_blank', + '_parent', + '_top' +]; + +function isExternalLinkTargetSet() { +//#if !MOZCENTRAL + if (PDFJS.openExternalLinksInNewWindow) { + deprecated('PDFJS.openExternalLinksInNewWindow, please use ' + + '"PDFJS.externalLinkTarget = PDFJS.LinkTarget.BLANK" instead.'); + if (PDFJS.externalLinkTarget === LinkTarget.NONE) { + PDFJS.externalLinkTarget = LinkTarget.BLANK; + } + // Reset the deprecated parameter, to suppress further warnings. + PDFJS.openExternalLinksInNewWindow = false; + } +//#endif + switch (PDFJS.externalLinkTarget) { + case LinkTarget.NONE: + return false; + case LinkTarget.SELF: + case LinkTarget.BLANK: + case LinkTarget.PARENT: + case LinkTarget.TOP: + return true; + } + warn('PDFJS.externalLinkTarget is invalid: ' + PDFJS.externalLinkTarget); + // Reset the external link target, to suppress further warnings. + PDFJS.externalLinkTarget = LinkTarget.NONE; + return false; +} +PDFJS.isExternalLinkTargetSet = isExternalLinkTargetSet; + +/** + * Adds various attributes (href, title, target, rel) to hyperlinks. + * @param {HTMLLinkElement} link - The link element. + * @param {Object} params - An object with the properties: + * @param {string} params.url - An absolute URL. + */ +function addLinkAttributes(link, params) { + var url = params && params.url; + link.href = link.title = (url ? removeNullCharacters(url) : ''); + + if (url) { + if (isExternalLinkTargetSet()) { + link.target = LinkTargetStringMap[PDFJS.externalLinkTarget]; + } + // Strip referrer from the URL. + link.rel = PDFJS.externalLinkRel; + } +} +PDFJS.addLinkAttributes = addLinkAttributes; + +// Gets the file name from a given URL. +function getFilenameFromUrl(url) { + var anchor = url.indexOf('#'); + var query = url.indexOf('?'); + var end = Math.min( + anchor > 0 ? anchor : url.length, + query > 0 ? query : url.length); + return url.substring(url.lastIndexOf('/', end) + 1, end); +} +PDFJS.getFilenameFromUrl = getFilenameFromUrl; + exports.CustomStyle = CustomStyle; +exports.addLinkAttributes = addLinkAttributes; +exports.isExternalLinkTargetSet = isExternalLinkTargetSet; +exports.getFilenameFromUrl = getFilenameFromUrl; +exports.LinkTarget = LinkTarget; })); diff --git a/src/pdf.js b/src/pdf.js index be677347af3877..49da559b0738d9 100644 --- a/src/pdf.js +++ b/src/pdf.js @@ -43,9 +43,8 @@ }).call(pdfjsLibs); - exports.PDFJS = pdfjsLibs.pdfjsSharedGlobal.PDFJS; - //#if MAIN_FILE + exports.PDFJS = pdfjsLibs.pdfjsSharedGlobal.PDFJS; exports.getDocument = pdfjsLibs.pdfjsDisplayAPI.getDocument; exports.PDFDataRangeTransport = pdfjsLibs.pdfjsDisplayAPI.PDFDataRangeTransport; diff --git a/src/shared/global.js b/src/shared/global.js index 94b8ef9fe054c5..671825252163a6 100644 --- a/src/shared/global.js +++ b/src/shared/global.js @@ -12,23 +12,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* globals global, pdfjsVersion, pdfjsBuild */ +/* globals pdfjsVersion, pdfjsBuild */ 'use strict'; (function (root, factory) { if (typeof define === 'function' && define.amd) { - define('pdfjs/shared/global', ['exports'], factory); + define('pdfjs/shared/global', ['exports', 'pdfjs/shared/util'], factory); } else if (typeof exports !== 'undefined') { - factory(exports); + factory(exports, require('./util.js')); } else { - factory((root.pdfjsSharedGlobal = {})); + factory((root.pdfjsSharedGlobal = {}), root.pdfjsSharedUtil); } -}(this, function (exports) { +}(this, function (exports, sharedUtil) { - var globalScope = (typeof window !== 'undefined') ? window : - (typeof global !== 'undefined') ? global : - (typeof self !== 'undefined') ? self : this; + var globalScope = sharedUtil.globalScope; var isWorker = (typeof window === 'undefined'); @@ -38,15 +36,48 @@ if (!globalScope.PDFJS) { globalScope.PDFJS = {}; } + var PDFJS = globalScope.PDFJS; if (typeof pdfjsVersion !== 'undefined') { - globalScope.PDFJS.version = pdfjsVersion; + PDFJS.version = pdfjsVersion; } if (typeof pdfjsVersion !== 'undefined') { - globalScope.PDFJS.build = pdfjsBuild; + PDFJS.build = pdfjsBuild; } - globalScope.PDFJS.pdfBug = false; + PDFJS.pdfBug = false; + + if (PDFJS.verbosity !== undefined) { + sharedUtil.setVerbosityLevel(PDFJS.verbosity); + } + + PDFJS.VERBOSITY_LEVELS = sharedUtil.VERBOSITY_LEVELS; + PDFJS.OPS = sharedUtil.OPS; + PDFJS.UNSUPPORTED_FEATURES = sharedUtil.UNSUPPORTED_FEATURES; + PDFJS.isValidUrl = sharedUtil.isValidUrl; + PDFJS.shadow = sharedUtil.shadow; + PDFJS.createBlob = sharedUtil.createBlob; + PDFJS.createObjectURL = function PDFJS_createObjectURL(data, contentType) { + return sharedUtil.createObjectURL(data, contentType, + PDFJS.disableCreateObjectURL); + }; + Object.defineProperty(PDFJS, 'isLittleEndian', { + configurable: true, + get: function PDFJS_isLittleEndian() { + var value = sharedUtil.isLittleEndian(); + return sharedUtil.shadow(PDFJS, 'isLittleEndian', value); + } + }); + PDFJS.removeNullCharacters = sharedUtil.removeNullCharacters; + PDFJS.PasswordResponses = sharedUtil.PasswordResponses; + PDFJS.PasswordException = sharedUtil.PasswordException; + PDFJS.UnknownErrorException = sharedUtil.UnknownErrorException; + PDFJS.InvalidPDFException = sharedUtil.InvalidPDFException; + PDFJS.MissingPDFException = sharedUtil.MissingPDFException; + PDFJS.UnexpectedResponseException = sharedUtil.UnexpectedResponseException; + PDFJS.Util = sharedUtil.Util; + PDFJS.PageViewport = sharedUtil.PageViewport; + PDFJS.createPromiseCapability = sharedUtil.createPromiseCapability; exports.globalScope = globalScope; exports.isWorker = isWorker; diff --git a/src/shared/util.js b/src/shared/util.js index 953b3f24de8dc9..5fe38b5446728e 100644 --- a/src/shared/util.js +++ b/src/shared/util.js @@ -12,22 +12,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* globals MozBlobBuilder, URL */ +/* globals MozBlobBuilder, URL, global */ 'use strict'; (function (root, factory) { if (typeof define === 'function' && define.amd) { - define('pdfjs/shared/util', ['exports', 'pdfjs/shared/global'], factory); + define('pdfjs/shared/util', ['exports'], factory); } else if (typeof exports !== 'undefined') { - factory(exports, require('./global.js')); + factory(exports); } else { - factory((root.pdfjsSharedUtil = {}), root.pdfjsSharedGlobal); + factory((root.pdfjsSharedUtil = {})); } -}(this, function (exports, sharedGlobal) { +}(this, function (exports) { -var PDFJS = sharedGlobal.PDFJS; -var globalScope = sharedGlobal.globalScope; +var globalScope = (typeof window !== 'undefined') ? window : + (typeof global !== 'undefined') ? global : + (typeof self !== 'undefined') ? self : this; var FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0]; @@ -127,14 +128,14 @@ var FontType = { MMTYPE1: 10 }; -PDFJS.VERBOSITY_LEVELS = { +var VERBOSITY_LEVELS = { errors: 0, warnings: 1, infos: 5 }; // All the possible operations for an operator list. -var OPS = PDFJS.OPS = { +var OPS = { // Intentionally start from 1 so it is easy to spot bad operators that will be // 0's. dependency: 1, @@ -230,18 +231,28 @@ var OPS = PDFJS.OPS = { constructPath: 91 }; +var verbosity = VERBOSITY_LEVELS.warnings; + +function setVerbosityLevel(level) { + verbosity = level; +} + +function getVerbosityLevel() { + return verbosity; +} + // A notice for devs. These are good for things that are helpful to devs, such // as warning that Workers were disabled, which is important to devs but not // end users. function info(msg) { - if (PDFJS.verbosity >= PDFJS.VERBOSITY_LEVELS.infos) { + if (verbosity >= VERBOSITY_LEVELS.infos) { console.log('Info: ' + msg); } } // Non-fatal warnings. function warn(msg) { - if (PDFJS.verbosity >= PDFJS.VERBOSITY_LEVELS.warnings) { + if (verbosity >= VERBOSITY_LEVELS.warnings) { console.log('Warning: ' + msg); } } @@ -254,7 +265,7 @@ function deprecated(details) { // Fatal errors that should trigger the fallback UI and halt execution by // throwing an exception. function error(msg) { - if (PDFJS.verbosity >= PDFJS.VERBOSITY_LEVELS.errors) { + if (verbosity >= VERBOSITY_LEVELS.errors) { console.log('Error: ' + msg); console.log(backtrace()); } @@ -275,7 +286,7 @@ function assert(cond, msg) { } } -var UNSUPPORTED_FEATURES = PDFJS.UNSUPPORTED_FEATURES = { +var UNSUPPORTED_FEATURES = { unknown: 'unknown', forms: 'forms', javaScript: 'javaScript', @@ -284,17 +295,6 @@ var UNSUPPORTED_FEATURES = PDFJS.UNSUPPORTED_FEATURES = { font: 'font' }; -// Gets the file name from a given URL. -function getFilenameFromUrl(url) { - var anchor = url.indexOf('#'); - var query = url.indexOf('?'); - var end = Math.min( - anchor > 0 ? anchor : url.length, - query > 0 ? query : url.length); - return url.substring(url.lastIndexOf('/', end) + 1, end); -} -PDFJS.getFilenameFromUrl = getFilenameFromUrl; - // Combines two URLs. The baseUrl shall be absolute URL. If the url is an // absolute URL, it will be returned as is. function combineUrl(baseUrl, url) { @@ -342,27 +342,6 @@ function isValidUrl(url, allowRelative) { return false; } } -PDFJS.isValidUrl = isValidUrl; - -/** - * Adds various attributes (href, title, target, rel) to hyperlinks. - * @param {HTMLLinkElement} link - The link element. - * @param {Object} params - An object with the properties: - * @param {string} params.url - An absolute URL. - */ -function addLinkAttributes(link, params) { - var url = params && params.url; - link.href = link.title = (url ? removeNullCharacters(url) : ''); - - if (url) { - if (isExternalLinkTargetSet()) { - link.target = LinkTargetStringMap[PDFJS.externalLinkTarget]; - } - // Strip referrer from the URL. - link.rel = PDFJS.externalLinkRel; - } -} -PDFJS.addLinkAttributes = addLinkAttributes; function shadow(obj, prop, value) { Object.defineProperty(obj, prop, { value: value, @@ -371,7 +350,6 @@ function shadow(obj, prop, value) { writable: false }); return value; } -PDFJS.shadow = shadow; function getLookupTableFactory(initializer) { var lookup; @@ -385,50 +363,7 @@ function getLookupTableFactory(initializer) { }; } -var LinkTarget = PDFJS.LinkTarget = { - NONE: 0, // Default value. - SELF: 1, - BLANK: 2, - PARENT: 3, - TOP: 4, -}; -var LinkTargetStringMap = [ - '', - '_self', - '_blank', - '_parent', - '_top' -]; - -function isExternalLinkTargetSet() { -//#if !MOZCENTRAL - if (PDFJS.openExternalLinksInNewWindow) { - deprecated('PDFJS.openExternalLinksInNewWindow, please use ' + - '"PDFJS.externalLinkTarget = PDFJS.LinkTarget.BLANK" instead.'); - if (PDFJS.externalLinkTarget === LinkTarget.NONE) { - PDFJS.externalLinkTarget = LinkTarget.BLANK; - } - // Reset the deprecated parameter, to suppress further warnings. - PDFJS.openExternalLinksInNewWindow = false; - } -//#endif - switch (PDFJS.externalLinkTarget) { - case LinkTarget.NONE: - return false; - case LinkTarget.SELF: - case LinkTarget.BLANK: - case LinkTarget.PARENT: - case LinkTarget.TOP: - return true; - } - warn('PDFJS.externalLinkTarget is invalid: ' + PDFJS.externalLinkTarget); - // Reset the external link target, to suppress further warnings. - PDFJS.externalLinkTarget = LinkTarget.NONE; - return false; -} -PDFJS.isExternalLinkTargetSet = isExternalLinkTargetSet; - -var PasswordResponses = PDFJS.PasswordResponses = { +var PasswordResponses = { NEED_PASSWORD: 1, INCORRECT_PASSWORD: 2 }; @@ -445,7 +380,6 @@ var PasswordException = (function PasswordExceptionClosure() { return PasswordException; })(); -PDFJS.PasswordException = PasswordException; var UnknownErrorException = (function UnknownErrorExceptionClosure() { function UnknownErrorException(msg, details) { @@ -459,7 +393,6 @@ var UnknownErrorException = (function UnknownErrorExceptionClosure() { return UnknownErrorException; })(); -PDFJS.UnknownErrorException = UnknownErrorException; var InvalidPDFException = (function InvalidPDFExceptionClosure() { function InvalidPDFException(msg) { @@ -472,7 +405,6 @@ var InvalidPDFException = (function InvalidPDFExceptionClosure() { return InvalidPDFException; })(); -PDFJS.InvalidPDFException = InvalidPDFException; var MissingPDFException = (function MissingPDFExceptionClosure() { function MissingPDFException(msg) { @@ -485,7 +417,6 @@ var MissingPDFException = (function MissingPDFExceptionClosure() { return MissingPDFException; })(); -PDFJS.MissingPDFException = MissingPDFException; var UnexpectedResponseException = (function UnexpectedResponseExceptionClosure() { @@ -500,7 +431,6 @@ var UnexpectedResponseException = return UnexpectedResponseException; })(); -PDFJS.UnexpectedResponseException = UnexpectedResponseException; var NotImplementedException = (function NotImplementedExceptionClosure() { function NotImplementedException(msg) { @@ -549,7 +479,6 @@ function removeNullCharacters(str) { } return str.replace(NullCharactersRegExp, ''); } -PDFJS.removeNullCharacters = removeNullCharacters; function bytesToString(bytes) { assert(bytes !== null && typeof bytes === 'object' && @@ -663,30 +592,7 @@ function isLittleEndian() { return (buffer16[0] === 1); } -Object.defineProperty(PDFJS, 'isLittleEndian', { - configurable: true, - get: function PDFJS_isLittleEndian() { - return shadow(PDFJS, 'isLittleEndian', isLittleEndian()); - } -}); - //#if !(FIREFOX || MOZCENTRAL || CHROME) -//// Lazy test if the userAgent support CanvasTypedArrays -function hasCanvasTypedArrays() { - var canvas = document.createElement('canvas'); - canvas.width = canvas.height = 1; - var ctx = canvas.getContext('2d'); - var imageData = ctx.createImageData(1, 1); - return (typeof imageData.data.buffer !== 'undefined'); -} - -Object.defineProperty(PDFJS, 'hasCanvasTypedArrays', { - configurable: true, - get: function PDFJS_hasCanvasTypedArrays() { - return shadow(PDFJS, 'hasCanvasTypedArrays', hasCanvasTypedArrays()); - } -}); - var Uint32ArrayView = (function Uint32ArrayViewClosure() { function Uint32ArrayView(buffer, length) { @@ -728,13 +634,11 @@ var Uint32ArrayView = (function Uint32ArrayViewClosure() { })(); exports.Uint32ArrayView = Uint32ArrayView; -//#else -//PDFJS.hasCanvasTypedArrays = true; //#endif var IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0]; -var Util = PDFJS.Util = (function UtilClosure() { +var Util = (function UtilClosure() { function Util() {} var rgbBuf = ['rgb(', 0, ',', 0, ',', 0, ')']; @@ -987,7 +891,7 @@ var Util = PDFJS.Util = (function UtilClosure() { * @class * @alias PDFJS.PageViewport */ -var PageViewport = PDFJS.PageViewport = (function PageViewportClosure() { +var PageViewport = (function PageViewportClosure() { /** * @constructor * @private @@ -1211,8 +1115,6 @@ function createPromiseCapability() { return capability; } -PDFJS.createPromiseCapability = createPromiseCapability; - /** * Polyfill for Promises: * The following promise implementation tries to generally implement the @@ -1593,7 +1495,7 @@ var StatTimer = (function StatTimerClosure() { return StatTimer; })(); -PDFJS.createBlob = function createBlob(data, contentType) { +var createBlob = function createBlob(data, contentType) { if (typeof Blob !== 'undefined') { return new Blob([data], { type: contentType }); } @@ -1603,15 +1505,15 @@ PDFJS.createBlob = function createBlob(data, contentType) { return bb.getBlob(contentType); }; -PDFJS.createObjectURL = (function createObjectURLClosure() { +var createObjectURL = (function createObjectURLClosure() { // Blob/createObjectURL is not available, falling back to data schema. var digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; - return function createObjectURL(data, contentType) { - if (!PDFJS.disableCreateObjectURL && + return function createObjectURL(data, contentType, forceDataSchema) { + if (!forceDataSchema && typeof URL !== 'undefined' && URL.createObjectURL) { - var blob = PDFJS.createBlob(data, contentType); + var blob = createBlob(data, contentType); return URL.createObjectURL(blob); } @@ -2399,6 +2301,7 @@ function loadJpegStream(id, imageUrl, objs) { exports.FONT_IDENTITY_MATRIX = FONT_IDENTITY_MATRIX; exports.IDENTITY_MATRIX = IDENTITY_MATRIX; exports.OPS = OPS; +exports.VERBOSITY_LEVELS = VERBOSITY_LEVELS; exports.UNSUPPORTED_FEATURES = UNSUPPORTED_FEATURES; exports.AnnotationBorderStyleType = AnnotationBorderStyleType; exports.AnnotationFlag = AnnotationFlag; @@ -2406,12 +2309,11 @@ exports.AnnotationType = AnnotationType; exports.FontType = FontType; exports.ImageKind = ImageKind; exports.InvalidPDFException = InvalidPDFException; -exports.LinkTarget = LinkTarget; -exports.LinkTargetStringMap = LinkTargetStringMap; exports.MessageHandler = MessageHandler; exports.MissingDataException = MissingDataException; exports.MissingPDFException = MissingPDFException; exports.NotImplementedException = NotImplementedException; +exports.PageViewport = PageViewport; exports.PasswordException = PasswordException; exports.PasswordResponses = PasswordResponses; exports.StatTimer = StatTimer; @@ -2426,29 +2328,32 @@ exports.arraysToBytes = arraysToBytes; exports.assert = assert; exports.bytesToString = bytesToString; exports.combineUrl = combineUrl; +exports.createBlob = createBlob; exports.createPromiseCapability = createPromiseCapability; +exports.createObjectURL = createObjectURL; exports.deprecated = deprecated; exports.error = error; -exports.getFilenameFromUrl = getFilenameFromUrl; exports.getLookupTableFactory = getLookupTableFactory; +exports.getVerbosityLevel = getVerbosityLevel; +exports.globalScope = globalScope; exports.info = info; exports.isArray = isArray; exports.isArrayBuffer = isArrayBuffer; exports.isBool = isBool; exports.isEmptyObj = isEmptyObj; -exports.isExternalLinkTargetSet = isExternalLinkTargetSet; exports.isInt = isInt; exports.isNum = isNum; exports.isString = isString; exports.isSameOrigin = isSameOrigin; exports.isValidUrl = isValidUrl; -exports.addLinkAttributes = addLinkAttributes; +exports.isLittleEndian = isLittleEndian; exports.loadJpegStream = loadJpegStream; exports.log2 = log2; exports.readInt8 = readInt8; exports.readUint16 = readUint16; exports.readUint32 = readUint32; exports.removeNullCharacters = removeNullCharacters; +exports.setVerbosityLevel = setVerbosityLevel; exports.shadow = shadow; exports.string32 = string32; exports.stringToBytes = stringToBytes; diff --git a/test/unit/dom_utils_spec.js b/test/unit/dom_utils_spec.js new file mode 100644 index 00000000000000..ae20a706384849 --- /dev/null +++ b/test/unit/dom_utils_spec.js @@ -0,0 +1,50 @@ +/* globals expect, it, describe, PDFJS, isExternalLinkTargetSet, LinkTarget, + getFilenameFromUrl */ + +'use strict'; + +describe('dom_utils', function() { + describe('getFilenameFromUrl', function() { + it('should get the filename from an absolute URL', function() { + var url = 'http://server.org/filename.pdf'; + var result = getFilenameFromUrl(url); + var expected = 'filename.pdf'; + expect(result).toEqual(expected); + }); + + it('should get the filename from a relative URL', function() { + var url = '../../filename.pdf'; + var result = getFilenameFromUrl(url); + var expected = 'filename.pdf'; + expect(result).toEqual(expected); + }); + }); + + describe('isExternalLinkTargetSet', function() { + // Save the current state, to avoid interfering with other tests. + var previousExternalLinkTarget = PDFJS.externalLinkTarget; + + 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); + } + }); + + // Reset the state. + PDFJS.externalLinkTarget = previousExternalLinkTarget; + }); +}); diff --git a/test/unit/unit_test.html b/test/unit/unit_test.html index 3927ab7a43acda..7e2a6c6e923879 100644 --- a/test/unit/unit_test.html +++ b/test/unit/unit_test.html @@ -37,6 +37,7 @@ +