diff --git a/.jshintignore b/.jshintignore index 55fba5294..46b0d7b8c 100644 --- a/.jshintignore +++ b/.jshintignore @@ -9,6 +9,7 @@ external/jpgjs/ external/jasmine/ external/cmapscompress/ external/importL10n/ +external/builder/fixtures_esprima/ shared/ test/tmp/ test/features/ diff --git a/.jshintrc b/.jshintrc index 19c53a416..34b5e6998 100644 --- a/.jshintrc +++ b/.jshintrc @@ -5,6 +5,7 @@ "worker": true, "predef": [ "Promise", + "PDFJSDev", "require", "define", "exports" diff --git a/extensions/firefox/content/PdfJsNetwork.jsm b/extensions/firefox/content/PdfJsNetwork.jsm new file mode 100644 index 000000000..ed5b48760 --- /dev/null +++ b/extensions/firefox/content/PdfJsNetwork.jsm @@ -0,0 +1,256 @@ +/* Copyright 2012 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. + */ +/* globals Components, Services */ + +'use strict'; + +Components.utils.import('resource://gre/modules/Services.jsm'); + +var EXPORTED_SYMBOLS = ['NetworkManager']; + +function log(aMsg) { + var msg = 'network.js: ' + (aMsg.join ? aMsg.join('') : aMsg); + Services.console.logStringMessage(msg); +} + +var NetworkManager = (function NetworkManagerClosure() { + + var OK_RESPONSE = 200; + var PARTIAL_CONTENT_RESPONSE = 206; + + function NetworkManager(url, args) { + this.url = url; + args = args || {}; + this.isHttp = /^https?:/i.test(url); + this.httpHeaders = (this.isHttp && args.httpHeaders) || {}; + this.withCredentials = args.withCredentials || false; + this.getXhr = args.getXhr || + function NetworkManager_getXhr() { + return new XMLHttpRequest(); + }; + + this.currXhrId = 0; + this.pendingRequests = Object.create(null); + this.loadedRequests = Object.create(null); + } + + function getArrayBuffer(xhr) { + var data = xhr.response; + if (typeof data !== 'string') { + return data; + } + var length = data.length; + var array = new Uint8Array(length); + for (var i = 0; i < length; i++) { + array[i] = data.charCodeAt(i) & 0xFF; + } + return array.buffer; + } + + NetworkManager.prototype = { + requestRange: function NetworkManager_requestRange(begin, end, listeners) { + var args = { + begin: begin, + end: end + }; + for (var prop in listeners) { + args[prop] = listeners[prop]; + } + return this.request(args); + }, + + requestFull: function NetworkManager_requestFull(listeners) { + return this.request(listeners); + }, + + request: function NetworkManager_request(args) { + var xhr = this.getXhr(); + var xhrId = this.currXhrId++; + var pendingRequest = this.pendingRequests[xhrId] = { + xhr: xhr + }; + + xhr.open('GET', this.url); + xhr.withCredentials = this.withCredentials; + for (var property in this.httpHeaders) { + var value = this.httpHeaders[property]; + if (typeof value === 'undefined') { + continue; + } + xhr.setRequestHeader(property, value); + } + if (this.isHttp && 'begin' in args && 'end' in args) { + var rangeStr = args.begin + '-' + (args.end - 1); + xhr.setRequestHeader('Range', 'bytes=' + rangeStr); + pendingRequest.expectedStatus = 206; + } else { + pendingRequest.expectedStatus = 200; + } + + var useMozChunkedLoading = !!args.onProgressiveData; + if (useMozChunkedLoading) { + xhr.responseType = 'moz-chunked-arraybuffer'; + pendingRequest.onProgressiveData = args.onProgressiveData; + pendingRequest.mozChunked = true; + } else { + xhr.responseType = 'arraybuffer'; + } + + if (args.onError) { + xhr.onerror = function(evt) { + args.onError(xhr.status); + }; + } + xhr.onreadystatechange = this.onStateChange.bind(this, xhrId); + xhr.onprogress = this.onProgress.bind(this, xhrId); + + pendingRequest.onHeadersReceived = args.onHeadersReceived; + pendingRequest.onDone = args.onDone; + pendingRequest.onError = args.onError; + pendingRequest.onProgress = args.onProgress; + + xhr.send(null); + + return xhrId; + }, + + onProgress: function NetworkManager_onProgress(xhrId, evt) { + var pendingRequest = this.pendingRequests[xhrId]; + if (!pendingRequest) { + // Maybe abortRequest was called... + return; + } + + if (pendingRequest.mozChunked) { + var chunk = getArrayBuffer(pendingRequest.xhr); + pendingRequest.onProgressiveData(chunk); + } + + var onProgress = pendingRequest.onProgress; + if (onProgress) { + onProgress(evt); + } + }, + + onStateChange: function NetworkManager_onStateChange(xhrId, evt) { + var pendingRequest = this.pendingRequests[xhrId]; + if (!pendingRequest) { + // Maybe abortRequest was called... + return; + } + + var xhr = pendingRequest.xhr; + if (xhr.readyState >= 2 && pendingRequest.onHeadersReceived) { + pendingRequest.onHeadersReceived(); + delete pendingRequest.onHeadersReceived; + } + + if (xhr.readyState !== 4) { + return; + } + + if (!(xhrId in this.pendingRequests)) { + // The XHR request might have been aborted in onHeadersReceived() + // callback, in which case we should abort request + return; + } + + delete this.pendingRequests[xhrId]; + + // success status == 0 can be on ftp, file and other protocols + if (xhr.status === 0 && this.isHttp) { + if (pendingRequest.onError) { + pendingRequest.onError(xhr.status); + } + return; + } + var xhrStatus = xhr.status || OK_RESPONSE; + + // From http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.2: + // "A server MAY ignore the Range header". This means it's possible to + // get a 200 rather than a 206 response from a range request. + var ok_response_on_range_request = + xhrStatus === OK_RESPONSE && + pendingRequest.expectedStatus === PARTIAL_CONTENT_RESPONSE; + + if (!ok_response_on_range_request && + xhrStatus !== pendingRequest.expectedStatus) { + if (pendingRequest.onError) { + pendingRequest.onError(xhr.status); + } + return; + } + + this.loadedRequests[xhrId] = true; + + var chunk = getArrayBuffer(xhr); + if (xhrStatus === PARTIAL_CONTENT_RESPONSE) { + var rangeHeader = xhr.getResponseHeader('Content-Range'); + var matches = /bytes (\d+)-(\d+)\/(\d+)/.exec(rangeHeader); + var begin = parseInt(matches[1], 10); + pendingRequest.onDone({ + begin: begin, + chunk: chunk + }); + } else if (pendingRequest.onProgressiveData) { + pendingRequest.onDone(null); + } else if (chunk) { + pendingRequest.onDone({ + begin: 0, + chunk: chunk + }); + } else if (pendingRequest.onError) { + pendingRequest.onError(xhr.status); + } + }, + + hasPendingRequests: function NetworkManager_hasPendingRequests() { + for (var xhrId in this.pendingRequests) { + return true; + } + return false; + }, + + getRequestXhr: function NetworkManager_getXhr(xhrId) { + return this.pendingRequests[xhrId].xhr; + }, + + isStreamingRequest: function NetworkManager_isStreamingRequest(xhrId) { + return !!(this.pendingRequests[xhrId].onProgressiveData); + }, + + isPendingRequest: function NetworkManager_isPendingRequest(xhrId) { + return xhrId in this.pendingRequests; + }, + + isLoadedRequest: function NetworkManager_isLoadedRequest(xhrId) { + return xhrId in this.loadedRequests; + }, + + abortAllRequests: function NetworkManager_abortAllRequests() { + for (var xhrId in this.pendingRequests) { + this.abortRequest(xhrId | 0); + } + }, + + abortRequest: function NetworkManager_abortRequest(xhrId) { + var xhr = this.pendingRequests[xhrId].xhr; + delete this.pendingRequests[xhrId]; + xhr.abort(); + } + }; + + return NetworkManager; +})(); diff --git a/extensions/firefox/content/PdfStreamConverter.jsm b/extensions/firefox/content/PdfStreamConverter.jsm index 9e4b7a9ef..a89cc5e77 100644 --- a/extensions/firefox/content/PdfStreamConverter.jsm +++ b/extensions/firefox/content/PdfStreamConverter.jsm @@ -38,7 +38,7 @@ Cu.import('resource://gre/modules/Services.jsm'); Cu.import('resource://gre/modules/NetUtil.jsm'); XPCOMUtils.defineLazyModuleGetter(this, 'NetworkManager', - 'resource://pdf.js/network.js'); + 'resource://pdf.js/PdfJsNetwork.jsm'); XPCOMUtils.defineLazyModuleGetter(this, 'PrivateBrowsingUtils', 'resource://gre/modules/PrivateBrowsingUtils.jsm'); diff --git a/external/builder/fixtures_esprima/blocks-expected.js b/external/builder/fixtures_esprima/blocks-expected.js new file mode 100644 index 000000000..22e7b7434 --- /dev/null +++ b/external/builder/fixtures_esprima/blocks-expected.js @@ -0,0 +1,10 @@ +function test() { + "test"; + "1"; + "2"; + "3"; + if ("test") { + "5"; + } + "4"; +} diff --git a/external/builder/fixtures_esprima/blocks.js b/external/builder/fixtures_esprima/blocks.js new file mode 100644 index 000000000..a7f3c360d --- /dev/null +++ b/external/builder/fixtures_esprima/blocks.js @@ -0,0 +1,19 @@ +function test() { + {;} + ; + "test"; + { + "1"; + if (true) { + "2"; + } + ; + { + "3"; + if ("test") { + "5"; + } + } + "4"; + } +} diff --git a/external/builder/fixtures_esprima/comments-expected.js b/external/builder/fixtures_esprima/comments-expected.js new file mode 100644 index 000000000..270742445 --- /dev/null +++ b/external/builder/fixtures_esprima/comments-expected.js @@ -0,0 +1,28 @@ +function f1() { + /* head */ + "1"; + /* mid */ + "2"; +} +/* tail */ +function f2() { + // head + "1"; + // mid + "2"; +} +// tail +function f2() { + if ("1") { + // begin block + "1"; + } + "2"; + // trailing + if (/* s */ + "3") + /*e*/ + { + "4"; + } +} diff --git a/external/builder/fixtures_esprima/comments.js b/external/builder/fixtures_esprima/comments.js new file mode 100644 index 000000000..5ab6d4c0d --- /dev/null +++ b/external/builder/fixtures_esprima/comments.js @@ -0,0 +1,26 @@ +/* globals f0 */ +function f1() { + /* head */ + "1"; + /* mid */ + "2"; + /* tail */ +} + +function f2() { + // head + "1"; + // mid + "2"; + // tail +} + +function f2() { + if ("1") { // begin block + "1"; + } + "2"; // trailing + if (/* s */"3"/*e*/) { + "4"; + } +} diff --git a/external/builder/fixtures_esprima/constants-expected.js b/external/builder/fixtures_esprima/constants-expected.js new file mode 100644 index 000000000..4539481e5 --- /dev/null +++ b/external/builder/fixtures_esprima/constants-expected.js @@ -0,0 +1,15 @@ +var a = true; +var b = false; +var c = '1'; +var d = false; +var e = true; +var f = '0'; +var g = '1'; +var h = '0'; +var i = true; +var j = false; +var k = false; +var l = true; +var m = '1' === true; +var n = false; +var o = true; diff --git a/external/builder/fixtures_esprima/constants.js b/external/builder/fixtures_esprima/constants.js new file mode 100644 index 000000000..db2ff6e67 --- /dev/null +++ b/external/builder/fixtures_esprima/constants.js @@ -0,0 +1,15 @@ +var a = true; +var b = false; +var c = true && '1'; +var d = false && '0'; +var e = true || '1'; +var f = false || '0'; +var g = true ? '1' : '0'; +var h = false ? '1' : '0'; +var i = 'test' === 'test'; +var j = 'test' !== 'test'; +var k = 'test' === 'test2'; +var l = 'test' !== 'test2'; +var m = '1' === true; +var n = !true; +var o = !false; diff --git a/external/builder/fixtures_esprima/evals-expected.js b/external/builder/fixtures_esprima/evals-expected.js new file mode 100644 index 000000000..414de051c --- /dev/null +++ b/external/builder/fixtures_esprima/evals-expected.js @@ -0,0 +1,13 @@ +var a = false; +var b = true; +var c = true; +var d = false; +var e = true; +var f = 'text'; +var g = { + "obj": { "i": 1 }, + "j": 2 +}; +var h = { 'test': 'test' }; +var i = '0'; +var j = { "i": 1 }; diff --git a/external/builder/fixtures_esprima/evals.js b/external/builder/fixtures_esprima/evals.js new file mode 100644 index 000000000..c0649ae83 --- /dev/null +++ b/external/builder/fixtures_esprima/evals.js @@ -0,0 +1,10 @@ +var a = typeof PDFJSDev === 'undefined'; +var b = typeof PDFJSDev !== 'undefined'; +var c = PDFJSDev.test('TRUE'); +var d = PDFJSDev.test('FALSE'); +var e = PDFJSDev.eval('TRUE'); +var f = PDFJSDev.eval('TEXT'); +var g = PDFJSDev.eval('OBJ'); +var h = PDFJSDev.json('$ROOT/external/builder/fixtures_esprima/evals.json'); +var i = typeof PDFJSDev === 'undefined' ? PDFJSDev.eval('FALSE') : '0'; +var j = typeof PDFJSDev !== 'undefined' ? PDFJSDev.eval('OBJ.obj') : '0'; diff --git a/external/builder/fixtures_esprima/evals.json b/external/builder/fixtures_esprima/evals.json new file mode 100644 index 000000000..020d36b74 --- /dev/null +++ b/external/builder/fixtures_esprima/evals.json @@ -0,0 +1 @@ +{ 'test': 'test' } \ No newline at end of file diff --git a/external/builder/fixtures_esprima/ifs-expected.js b/external/builder/fixtures_esprima/ifs-expected.js new file mode 100644 index 000000000..12599c619 --- /dev/null +++ b/external/builder/fixtures_esprima/ifs-expected.js @@ -0,0 +1,17 @@ +if ('test') { + "1"; +} +{ + "1"; +} +{ + "1"; +} +; +{ + "2"; +} +; +if ('1') { + "1"; +} diff --git a/external/builder/fixtures_esprima/ifs.js b/external/builder/fixtures_esprima/ifs.js new file mode 100644 index 000000000..a2f3d217f --- /dev/null +++ b/external/builder/fixtures_esprima/ifs.js @@ -0,0 +1,25 @@ +if ('test') { + "1"; +} +if (true) { + "1"; +} +if (true) { + "1"; +} else { + "2"; +} +if (false) { + "1"; +} +if (false) { + "1"; +} else { + "2"; +} +if (true && false) { + "1"; +} +if (true && false || '1') { + "1"; +} diff --git a/external/builder/preprocessor2.js b/external/builder/preprocessor2.js new file mode 100644 index 000000000..02eb689a3 --- /dev/null +++ b/external/builder/preprocessor2.js @@ -0,0 +1,266 @@ +/* jshint node:true */ + +'use strict'; + +var esprima = require('esprima'); +var escodegen = require('escodegen'); +var vm = require('vm'); +var fs = require('fs'); +var path = require('path'); + +var PDFJS_PREPROCESSOR_NAME = 'PDFJSDev'; +var ROOT_PREFIX = '$ROOT/'; + +function isLiteral(obj, value) { + return obj.type === 'Literal' && obj.value === value; +} + +function isPDFJSPreprocessor(obj) { + return obj.type === 'Identifier' && + obj.name === PDFJS_PREPROCESSOR_NAME; +} + +function evalWithDefines(code, defines, loc) { + if (!code || !code.trim()) { + throw new Error('No JavaScript expression given'); + } + return vm.runInNewContext(code, defines, {displayErrors: false}); +} + +function handlePreprocessorAction(ctx, actionName, args, loc) { + try { + var arg; + switch (actionName) { + case 'test': + arg = args[0]; + if (!arg || arg.type !== 'Literal' || + typeof arg.value !== 'string') { + throw new Error('No code for testing is given'); + } + var isTrue = !!evalWithDefines(arg.value, ctx.defines); + return {type: 'Literal', value: isTrue, loc: loc}; + case 'eval': + arg = args[0]; + if (!arg || arg.type !== 'Literal' || + typeof arg.value !== 'string') { + throw new Error('No code for eval is given'); + } + var result = evalWithDefines(arg.value, ctx.defines); + if (typeof result === 'boolean' || typeof result === 'string' || + typeof result === 'number') { + return {type: 'Literal', value: result, loc: loc}; + } + if (typeof result === 'object') { + var parsedObj = esprima.parse('(' + JSON.stringify(result) + ')'); + parsedObj.body[0].expression.loc = loc; + return parsedObj.body[0].expression; + } + break; + case 'json': + arg = args[0]; + if (!arg || arg.type !== 'Literal' || + typeof arg.value !== 'string') { + throw new Error('Path to JSON is not provided'); + } + var jsonPath = arg.value; + if (jsonPath.indexOf(ROOT_PREFIX) === 0) { + jsonPath = path.join(ctx.rootPath, + jsonPath.substring(ROOT_PREFIX.length)); + } + var jsonContent = fs.readFileSync(jsonPath).toString(); + var parsedJSON = esprima.parse('(' +jsonContent + ')'); + parsedJSON.body[0].expression.loc = loc; + return parsedJSON.body[0].expression; + } + throw new Error('Unsupported action'); + } catch (e) { + throw new Error('Could not process ' + PDFJS_PREPROCESSOR_NAME + '.' + + actionName + ' at ' + JSON.stringify(loc) + '\n' + + e.name + ': ' + e.message); + } +} + +function postprocessNode(ctx, node) { + switch (node.type) { + case 'IfStatement': + if (isLiteral(node.test, true)) { + // if (true) stmt1; => stmt1 + return node.consequent; + } else if (isLiteral(node.test, false)) { + // if (false) stmt1; else stmt2; => stmt2 + return node.alternate || {type: 'EmptyStatement', loc: node.loc}; + } + break; + case 'ConditionalExpression': + if (isLiteral(node.test, true)) { + // true ? stmt1 : stmt2 => stmt1 + return node.consequent; + } else if (isLiteral(node.test, false)) { + // false ? stmt1 : stmt2 => stmt2 + return node.alternate; + } + break; + case 'UnaryExpression': + if (node.operator === 'typeof' && + isPDFJSPreprocessor(node.argument)) { + // typeof PDFJSDev => 'object' + return {type: 'Literal', value: 'object', loc: node.loc}; + } + if (node.operator === '!' && + node.argument.type === 'Literal' && + typeof node.argument.value === 'boolean') { + // !true => false, !false => true + return {type: 'Literal', value: !node.argument.value, loc: node.loc}; + } + break; + case 'LogicalExpression': + switch (node.operator) { + case '&&': + if (isLiteral(node.left, true)) { + return node.right; + } + if (isLiteral(node.left, false)) { + return node.left; + } + break; + case '||': + if (isLiteral(node.left, true)) { + return node.left; + } + if (isLiteral(node.left, false)) { + return node.right; + } + break; + } + break; + case 'BinaryExpression': + switch (node.operator) { + case '==': + case '===': + case '!=': + case '!==': + if (node.left.type === 'Literal' && + node.right.type === 'Literal' && + typeof node.left.value === typeof node.right.value) { + // folding two literals == and != check + switch (typeof node.left.value) { + case 'string': + case 'boolean': + case 'number': + var equal = node.left.value === node.right.value; + return { + type: 'Literal', + value: (node.operator[0] === '=') === equal, + loc: node.loc + }; + } + } + break; + } + break; + case 'CallExpression': + if (node.callee.type === 'MemberExpression' && + isPDFJSPreprocessor(node.callee.object) && + node.callee.property.type === 'Identifier') { + // PDFJSDev.xxxx(arg1, arg2, ...) => tranform + var action = node.callee.property.name; + return handlePreprocessorAction(ctx, action, + node.arguments, node.loc); + } + break; + case 'BlockStatement': + var subExpressionIndex = 0; + while (subExpressionIndex < node.body.length) { + if (node.body[subExpressionIndex].type === 'EmptyStatement') { + // Removing empty statements from the blocks. + node.body.splice(subExpressionIndex, 1); + continue; + } + if (node.body[subExpressionIndex].type === 'BlockStatement') { + // Block statements inside a block are moved to the parent one. + var subChildren = node.body[subExpressionIndex].body; + Array.prototype.splice.apply(node.body, + [subExpressionIndex, 1].concat(subChildren)); + subExpressionIndex += subChildren.length; + continue; + } + subExpressionIndex++; + } + break; + } + return node; +} + +function fixComments(ctx, node) { + if (!ctx.saveComments) { + return; + } + // Fixes double comments in the escodegen output. + delete node.trailingComments; + // Removes jshint and other service comments. + if (node.leadingComments) { + var i = 0; + while (i < node.leadingComments.length) { + var type = node.leadingComments[i].type; + var value = node.leadingComments[i].value; + if (type === 'Block' && + /^\s*(globals|jshint|falls through|umdutils)\b/.test(value)) { + node.leadingComments.splice(i, 1); + continue; + } + i++; + } + } +} + +function traverseTree(ctx, node) { + // generic node processing + for (var i in node) { + var child = node[i]; + if (typeof child === 'object' && child !== null && child.type) { + var result = traverseTree(ctx, child); + if (result !== child) { + node[i] = result; + } + } else if (Array.isArray(child)) { + child.forEach(function (childItem, index) { + if (typeof childItem === 'object' && childItem !== null && + childItem.type) { + var result = traverseTree(ctx, childItem); + if (result !== childItem) { + child[index] = result; + } + } + }); + } + } + + node = postprocessNode(ctx, node) || node; + + fixComments(ctx, node); + return node; +} + +function preprocessPDFJSCode(ctx, code) { + var saveComments = !!ctx.saveComments; + var format = ctx.format || { + indent: { + style: ' ', + adjustMultilineComment: saveComments, + } + }; + var parseComment = { + loc: true, + attachComment: saveComments + }; + var codegenOptions = { + format: format, + comment: saveComments, + parse: esprima.parse + }; + var syntax = esprima.parse(code, parseComment); + traverseTree(ctx, syntax); + return escodegen.generate(syntax, codegenOptions); +} + +exports.preprocessPDFJSCode = preprocessPDFJSCode; diff --git a/external/builder/test2.js b/external/builder/test2.js new file mode 100644 index 000000000..f29b434e5 --- /dev/null +++ b/external/builder/test2.js @@ -0,0 +1,54 @@ +/* jshint node:true */ +/* globals cat, cd, echo, ls */ +'use strict'; + +require('shelljs/make'); + +var p2 = require('./preprocessor2.js'); +var fs = require('fs'); + +var errors = 0; + +cd(__dirname); +cd('fixtures_esprima'); +ls('*-expected.*').forEach(function(expectationFilename) { + var inFilename = expectationFilename.replace('-expected', ''); + var expectation = cat(expectationFilename).trim() + .replace(/__filename/g, fs.realpathSync(inFilename)); + var input = fs.readFileSync(inFilename).toString(); + + var defines = { + TRUE: true, + FALSE: false, + OBJ: {obj: {i: 1}, j: 2}, + TEXT: 'text' + }; + var ctx = { + defines: defines, + rootPath: __dirname + '/../..', + saveComments: true + }; + var out; + try { + out = p2.preprocessPDFJSCode(ctx, input); + } catch (e) { + out = ('Error: ' + e.message).replace(/^/gm, '//'); + } + if (out !== expectation) { + echo('Assertion failed for ' + inFilename); + echo('--------------------------------------------------'); + echo('EXPECTED:'); + echo(expectation); + echo('--------------------------------------------------'); + echo('ACTUAL'); + echo(out); + echo('--------------------------------------------------'); + echo(); + } +}); + +if (errors) { + echo('Found ' + errors + ' expectation failures.'); +} else { + echo('All tests completed without errors.'); +} diff --git a/gulpfile.js b/gulpfile.js index cd874d35b..07cac6655 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -127,25 +127,27 @@ function bundle(filename, outfilename, pathPrefix, initFiles, amdName, defines, return all[1].toUpperCase(); }); - // Avoiding double processing of the bundle file. - var templateContent = fs.readFileSync(filename).toString(); - var tmpFile = outfilename + '.tmp'; - fs.writeFileSync(tmpFile, templateContent.replace( - /\/\/#expand\s+__BUNDLE__\s*\n/, function (all) { return bundleContent; })); - bundleContent = null; - templateContent = null; - - // This just preprocesses the empty pdf.js file, we don't actually want to - // preprocess everything yet since other build targets use this file. - builder.preprocess(tmpFile, outfilename, - builder.merge(defines, { + var p2 = require('./external/builder/preprocessor2.js'); + var ctx = { + rootPath: __dirname, + saveComments: true, + defines: builder.merge(defines, { BUNDLE_VERSION: versionInfo.version, BUNDLE_BUILD: versionInfo.commit, BUNDLE_AMD_NAME: amdName, BUNDLE_JS_NAME: jsName, MAIN_FILE: isMainFile - })); - fs.unlinkSync(tmpFile); + }) + }; + + var templateContent = fs.readFileSync(filename).toString(); + templateContent = templateContent.replace( + /\/\/#expand\s+__BUNDLE__\s*\n/, function (all) { return bundleContent; }); + bundleContent = null; + + templateContent = p2.preprocessPDFJSCode(ctx, templateContent); + fs.writeFileSync(outfilename, templateContent); + templateContent = null; } function createBundle(defines) { diff --git a/make.js b/make.js index e86cfc28a..c14eba0a4 100644 --- a/make.js +++ b/make.js @@ -102,6 +102,7 @@ var COMMON_WEB_FILES = ['web/viewer.html'], COMMON_FIREFOX_FILES_PREPROCESS = [FIREFOX_CONTENT_DIR + 'PdfStreamConverter.jsm', + FIREFOX_CONTENT_DIR + 'PdfJsNetwork.jsm', FIREFOX_CONTENT_DIR + 'PdfjsContentUtils.jsm', FIREFOX_CONTENT_DIR + 'PdfjsChromeUtils.jsm']; // diff --git a/package.json b/package.json index bea67b9f1..458713d52 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,8 @@ "name": "pdf.js", "version": "0.8.0", "devDependencies": { + "escodegen": "^1.8.0", + "esprima": "^2.7.2", "gulp": "^3.9.1", "gulp-util": "^3.0.7", "gulp-zip": "^3.2.0", diff --git a/src/core/murmurhash3.js b/src/core/murmurhash3.js index 32d607059..14fd875e1 100644 --- a/src/core/murmurhash3.js +++ b/src/core/murmurhash3.js @@ -44,14 +44,15 @@ var MurmurHash3_64 = (function MurmurHash3_64Closure (seed) { } var alwaysUseUint32ArrayView = false; -//#if !(FIREFOX || MOZCENTRAL || CHROME) - // old webkits have issues with non-aligned arrays - try { - new Uint32Array(new Uint8Array(5).buffer, 0, 1); - } catch (e) { - alwaysUseUint32ArrayView = true; + if (typeof PDFJSDev === 'undefined' || + !PDFJSDev.test('FIREFOX || MOZCENTRAL || CHROME')) { + // old webkits have issues with non-aligned arrays + try { + new Uint32Array(new Uint8Array(5).buffer, 0, 1); + } catch (e) { + alwaysUseUint32ArrayView = true; + } } -//#endif MurmurHash3_64.prototype = { update: function MurmurHash3_64_update(input) { diff --git a/src/core/network.js b/src/core/network.js index f84026d41..d59e8c2e7 100644 --- a/src/core/network.js +++ b/src/core/network.js @@ -18,24 +18,21 @@ 'use strict'; - -//#if (FIREFOX || MOZCENTRAL) -// -//Components.utils.import('resource://gre/modules/Services.jsm'); -// -//var EXPORTED_SYMBOLS = ['NetworkManager']; -// -//var console = { -// log: function console_log(aMsg) { -// var msg = 'network.js: ' + (aMsg.join ? aMsg.join('') : aMsg); -// Services.console.logStringMessage(msg); -// // TODO(mack): dump() doesn't seem to work here... -// dump(msg + '\n'); -// } -//} -//#endif - -var NetworkManager = (function NetworkManagerClosure() { +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + define('pdfjs/core/network', ['exports', 'pdfjs/shared/util', + 'pdfjs/core/worker'], factory); + } else if (typeof exports !== 'undefined') { + factory(exports, require('../shared/util.js'), require('./worker.js')); + } else { + factory((root.pdfjsCoreNetwork = {}), root.pdfjsSharedUtil, + root.pdfjsCoreWorker); + } +}(this, function (exports, sharedUtil, coreWorker) { +if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('FIREFOX || MOZCENTRAL')) { + throw new Error('Module "pdfjs/core/network" shall not ' + + 'be used with FIREFOX or MOZCENTRAL build.'); +} var OK_RESPONSE = 200; var PARTIAL_CONTENT_RESPONSE = 206; @@ -69,8 +66,9 @@ var NetworkManager = (function NetworkManagerClosure() { return array.buffer; } -//#if !(CHROME || FIREFOX || MOZCENTRAL) - var supportsMozChunked = (function supportsMozChunkedClosure() { + var supportsMozChunked = + typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME') ? false : + (function supportsMozChunkedClosure() { try { var x = new XMLHttpRequest(); // Firefox 37- required .open() to be called before setting responseType. @@ -86,7 +84,6 @@ var NetworkManager = (function NetworkManagerClosure() { return false; } })(); -//#endif NetworkManager.prototype = { requestRange: function NetworkManager_requestRange(begin, end, listeners) { @@ -128,15 +125,7 @@ var NetworkManager = (function NetworkManagerClosure() { pendingRequest.expectedStatus = 200; } -//#if CHROME -// var useMozChunkedLoading = false; -//#endif -//#if (FIREFOX || MOZCENTRAL) -// var useMozChunkedLoading = !!args.onProgressiveData; -//#endif -//#if !(CHROME || FIREFOX || MOZCENTRAL) var useMozChunkedLoading = supportsMozChunked && !!args.onProgressiveData; -//#endif if (useMozChunkedLoading) { xhr.responseType = 'moz-chunked-arraybuffer'; pendingRequest.onProgressiveData = args.onProgressiveData; @@ -289,22 +278,6 @@ var NetworkManager = (function NetworkManagerClosure() { } }; - return NetworkManager; -})(); - -//#if !(FIREFOX || MOZCENTRAL) -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define('pdfjs/core/network', ['exports', 'pdfjs/shared/util', - 'pdfjs/core/worker'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports, require('../shared/util.js'), require('./worker.js')); - } else { - factory((root.pdfjsCoreNetwork = {}), root.pdfjsSharedUtil, - root.pdfjsCoreWorker); - } -}(this, function (exports, sharedUtil, coreWorker) { - var assert = sharedUtil.assert; var createPromiseCapability = sharedUtil.createPromiseCapability; var isInt = sharedUtil.isInt; @@ -638,4 +611,3 @@ var NetworkManager = (function NetworkManagerClosure() { exports.PDFNetworkStream = PDFNetworkStream; exports.NetworkManager = NetworkManager; })); -//#endif diff --git a/src/core/worker.js b/src/core/worker.js index 33959e7bd..423bb0862 100644 --- a/src/core/worker.js +++ b/src/core/worker.js @@ -82,7 +82,8 @@ var WorkerTask = (function WorkerTaskClosure() { return WorkerTask; })(); -//#if !PRODUCTION +if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) { +/*jshint -W082 */ /** * Interface that represents PDF data transport. If possible, it allows * progressively load entire or fragment of the PDF binary data. @@ -210,7 +211,7 @@ IPDFStreamRangeReader.prototype = { */ onProgress: null, }; -//#endif +} /** @implements {IPDFStream} */ var PDFWorkerStream = (function PDFWorkerStreamClosure() { @@ -952,8 +953,8 @@ var WorkerMessageHandler = { }; function initializeWorker() { -//#if !MOZCENTRAL - if (!('console' in globalScope)) { + if ((typeof PDFJSDev === 'undefined' || !PDFJSDev.test('MOZCENTRAL')) && + !('console' in globalScope)) { var consoleTimer = {}; var workerConsole = { @@ -991,7 +992,6 @@ function initializeWorker() { globalScope.console = workerConsole; } -//#endif var handler = new MessageHandler('worker', 'main', self); WorkerMessageHandler.setup(handler, self); diff --git a/src/display/api.js b/src/display/api.js index 6ac9e8da5..5a2e07591 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -12,7 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* globals pdfjsFilePath, pdfjsVersion, pdfjsBuild, WeakMap */ +/* globals pdfjsFilePath, pdfjsVersion, pdfjsBuild, requirejs, pdfjsLibs, + WeakMap */ 'use strict'; @@ -70,13 +71,39 @@ var isWorkerDisabled = false; var workerSrc; var isPostMessageTransfersDisabled = false; -//#if PRODUCTION && !SINGLE_FILE -//#if GENERIC -//#include $ROOT/src/frameworks.js -//#else -//var fakeWorkerFilesLoader = null; -//#endif -//#endif +var fakeWorkerFilesLoader = null; +var useRequireEnsure = false; +if (typeof PDFJSDev !== 'undefined' && + PDFJSDev.test('GENERIC && !SINGLE_FILE')) { + // For GENERIC build we need add support of different fake file loaders + // for different frameworks. + if (typeof window === 'undefined') { + // node.js - disable worker and set require.ensure. + isWorkerDisabled = true; + if (typeof require.ensure === 'undefined') { + require.ensure = require('node-ensure'); + } + useRequireEnsure = true; + } + if (typeof __webpack_require__ !== 'undefined') { + useRequireEnsure = true; + } + if (typeof requirejs !== 'undefined' && requirejs.toUrl) { + workerSrc = requirejs.toUrl('pdfjs-dist/build/pdf.worker.js'); + } + var dynamicLoaderSupported = + typeof requirejs !== 'undefined' && requirejs.load; + fakeWorkerFilesLoader = useRequireEnsure ? (function (callback) { + require.ensure([], function () { + var worker = require('./pdf.worker.js'); + callback(worker.WorkerMessageHandler); + }); + }) : dynamicLoaderSupported ? (function (callback) { + requirejs(['pdfjs-dist/build/pdf.worker'], function (worker) { + callback(worker.WorkerMessageHandler); + }); + }) : null; +} /** * Document initialization / loading parameters object. @@ -1033,11 +1060,11 @@ var PDFWorker = (function PDFWorkerClosure() { if (getDefaultSetting('workerSrc')) { return getDefaultSetting('workerSrc'); } -//#if PRODUCTION && !(MOZCENTRAL || FIREFOX) -// if (pdfjsFilePath) { -// return pdfjsFilePath.replace(/\.js$/i, '.worker.js'); -// } -//#endif + if (typeof PDFJSDev !== 'undefined' && + PDFJSDev.test('PRODUCTION && !(MOZCENTRAL || FIREFOX)') && + pdfjsFilePath) { + return pdfjsFilePath.replace(/\.js$/i, '.worker.js'); + } error('No PDFJS.workerSrc specified'); } @@ -1046,12 +1073,14 @@ var PDFWorker = (function PDFWorkerClosure() { // Loads worker code into main thread. function setupFakeWorkerGlobal() { var WorkerMessageHandler; - if (!fakeWorkerFilesLoadedCapability) { - fakeWorkerFilesLoadedCapability = createPromiseCapability(); - // In the developer build load worker_loader which in turn loads all the - // other files and resolves the promise. In production only the - // pdf.worker.js file is needed. -//#if !PRODUCTION + if (fakeWorkerFilesLoadedCapability) { + return fakeWorkerFilesLoadedCapability.promise; + } + fakeWorkerFilesLoadedCapability = createPromiseCapability(); + // In the developer build load worker_loader which in turn loads all the + // other files and resolves the promise. In production only the + // pdf.worker.js file is needed. + if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) { if (typeof amdRequire === 'function') { amdRequire(['pdfjs/core/network', 'pdfjs/core/worker'], function (network, worker) { @@ -1065,19 +1094,16 @@ var PDFWorker = (function PDFWorkerClosure() { } else { throw new Error('AMD or CommonJS must be used to load fake worker.'); } -//#endif -//#if PRODUCTION && SINGLE_FILE -// WorkerMessageHandler = pdfjsLibs.pdfjsCoreWorker.WorkerMessageHandler; -// fakeWorkerFilesLoadedCapability.resolve(WorkerMessageHandler); -//#endif -//#if PRODUCTION && !SINGLE_FILE -// var loader = fakeWorkerFilesLoader || function (callback) { -// Util.loadScript(getWorkerSrc(), function () { -// callback(window.pdfjsDistBuildPdfWorker.WorkerMessageHandler); -// }); -// }; -// loader(fakeWorkerFilesLoadedCapability.resolve); -//#endif + } else if (PDFJSDev.test('SINGLE_FILE')) { + WorkerMessageHandler = pdfjsLibs.pdfjsCoreWorker.WorkerMessageHandler; + fakeWorkerFilesLoadedCapability.resolve(WorkerMessageHandler); + } else { + var loader = fakeWorkerFilesLoader || function (callback) { + Util.loadScript(getWorkerSrc(), function () { + callback(window.pdfjsDistBuildPdfWorker.WorkerMessageHandler); + }); + }; + loader(fakeWorkerFilesLoadedCapability.resolve); } return fakeWorkerFilesLoadedCapability.promise; } @@ -1198,20 +1224,20 @@ var PDFWorker = (function PDFWorkerClosure() { // all requirements to run parts of pdf.js in a web worker. // Right now, the requirement is, that an Uint8Array is still an // Uint8Array as it arrives on the worker. (Chrome added this with v.15.) -//#if !SINGLE_FILE - if (!isWorkerDisabled && !getDefaultSetting('disableWorker') && + if ((typeof PDFJSDev === 'undefined' || !PDFJSDev.test('SINGLE_FILE')) && + !isWorkerDisabled && !getDefaultSetting('disableWorker') && typeof Worker !== 'undefined') { var workerSrc = getWorkerSrc(); try { -//#if GENERIC -// // Wraps workerSrc path into blob URL, if the former does not belong -// // to the same origin. -// if (!isSameOrigin(window.location.href, workerSrc)) { -// workerSrc = createCDNWrapper( -// new URL(workerSrc, window.location).href); -// } -//#endif + // Wraps workerSrc path into blob URL, if the former does not belong + // to the same origin. + if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('GENERIC') && + !isSameOrigin(window.location.href, workerSrc)) { + workerSrc = createCDNWrapper( + new URL(workerSrc, window.location).href); + } + // Some versions of FF can't create a worker on localhost, see: // https://bugzilla.mozilla.org/show_bug.cgi?id=683280 var worker = new Worker(workerSrc); @@ -1311,7 +1337,6 @@ var PDFWorker = (function PDFWorkerClosure() { info('The worker has been disabled.'); } } -//#endif // Either workers are disabled, not supported or have thrown an exception. // Thus, we fallback to a faked worker. this._setupFakeWorker(); diff --git a/src/display/dom_utils.js b/src/display/dom_utils.js index efa2124ec..a41eda2f8 100644 --- a/src/display/dom_utils.js +++ b/src/display/dom_utils.js @@ -83,17 +83,19 @@ var CustomStyle = (function CustomStyleClosure() { return CustomStyle; })(); -//#if !(FIREFOX || MOZCENTRAL || CHROME) -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'); +var hasCanvasTypedArrays; +if (typeof PDFJSDev === 'undefined' || + !PDFJSDev.test('FIREFOX || MOZCENTRAL || CHROME')) { + hasCanvasTypedArrays = 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'); + }; +} else { + hasCanvasTypedArrays = function () { return true; }; } -//#else -//function hasCanvasTypedArrays() { return true; } -//#endif var LinkTarget = { NONE: 0, // Default value. diff --git a/src/display/font_loader.js b/src/display/font_loader.js index 7fb31579f..6362c38ed 100644 --- a/src/display/font_loader.js +++ b/src/display/font_loader.js @@ -36,14 +36,14 @@ var warn = sharedUtil.warn; function FontLoader(docId) { this.docId = docId; this.styleElement = null; -//#if !(MOZCENTRAL) - this.nativeFontFaces = []; - this.loadTestFontId = 0; - this.loadingContext = { - requests: [], - nextRequestId: 0 - }; -//#endif + if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('MOZCENTRAL')) { + this.nativeFontFaces = []; + this.loadTestFontId = 0; + this.loadingContext = { + requests: [], + nextRequestId: 0 + }; + } } FontLoader.prototype = { insertRule: function fontLoaderInsertRule(rule) { @@ -65,18 +65,20 @@ FontLoader.prototype = { styleElement.parentNode.removeChild(styleElement); styleElement = this.styleElement = null; } -//#if !(MOZCENTRAL) - this.nativeFontFaces.forEach(function(nativeFontFace) { - document.fonts.delete(nativeFontFace); - }); - this.nativeFontFaces.length = 0; -//#endif - }, -//#if !(MOZCENTRAL) - get loadTestFont() { + if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('MOZCENTRAL')) { + this.nativeFontFaces.forEach(function(nativeFontFace) { + document.fonts.delete(nativeFontFace); + }); + this.nativeFontFaces.length = 0; + } + } +}; + +if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('MOZCENTRAL')) { + var getLoadTestFont = function () { // This is a CFF font with 1 glyph for '.' that fills its entire width and // height. - return shadow(this, 'loadTestFont', atob( + return atob( 'T1RUTwALAIAAAwAwQ0ZGIDHtZg4AAAOYAAAAgUZGVE1lkzZwAAAEHAAAABxHREVGABQAFQ' + 'AABDgAAAAeT1MvMlYNYwkAAAEgAAAAYGNtYXABDQLUAAACNAAAAUJoZWFk/xVFDQAAALwA' + 'AAA2aGhlYQdkA+oAAAD0AAAAJGhtdHgD6AAAAAAEWAAAAAZtYXhwAAJQAAAAARgAAAAGbm' + @@ -98,16 +100,22 @@ FontLoader.prototype = { 'A/gXBIwMAYuL+nz5tQXkD5j3CBLnEQACAQEBIVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWF' + 'hYWFhYWFhYAAABAQAADwACAQEEE/t3Dov6fAH6fAT+fPp8+nwHDosMCvm1Cvm1DAz6fBQA' + 'AAAAAAABAAAAAMmJbzEAAAAAzgTjFQAAAADOBOQpAAEAAAAAAAAADAAUAAQAAAABAAAAAg' + - 'ABAAAAAAAAAAAD6AAAAAAAAA==' - )); - }, + 'ABAAAAAAAAAAAD6AAAAAAAAA=='); + }; + Object.defineProperty(FontLoader.prototype, 'loadTestFont', { + get: function () { + return shadow(this, 'loadTestFont', getLoadTestFont()); + }, + configurable: true + }); - addNativeFontFace: function fontLoader_addNativeFontFace(nativeFontFace) { + FontLoader.prototype.addNativeFontFace = + function fontLoader_addNativeFontFace(nativeFontFace) { this.nativeFontFaces.push(nativeFontFace); document.fonts.add(nativeFontFace); - }, + }; - bind: function fontLoaderBind(fonts, callback) { + FontLoader.prototype.bind = function fontLoaderBind(fonts, callback) { var rules = []; var fontsToLoad = []; var fontLoadPromises = []; @@ -158,9 +166,10 @@ FontLoader.prototype = { } else { request.complete(); } - }, + }; - queueLoadingCallback: function FontLoader_queueLoadingCallback(callback) { + FontLoader.prototype.queueLoadingCallback = + function FontLoader_queueLoadingCallback(callback) { function LoadLoader_completeRequest() { assert(!request.end, 'completeRequest() cannot be called twice'); request.end = Date.now(); @@ -182,11 +191,10 @@ FontLoader.prototype = { }; context.requests.push(request); return request; - }, + }; - prepareFontLoadEvent: function fontLoaderPrepareFontLoadEvent(rules, - fonts, - request) { + FontLoader.prototype.prepareFontLoadEvent = + function fontLoaderPrepareFontLoadEvent(rules, fonts, request) { /** Hack begin */ // There's currently no event when a font has finished downloading so the // following code is a dirty hack to 'guess' when a font is @@ -285,36 +293,34 @@ FontLoader.prototype = { request.complete(); }); /** Hack end */ - } -//#else -//bind: function fontLoaderBind(fonts, callback) { -// for (var i = 0, ii = fonts.length; i < ii; i++) { -// var font = fonts[i]; -// if (font.attached) { -// continue; -// } -// -// font.attached = true; -// var rule = font.createFontFaceRule(); -// if (rule) { -// this.insertRule(rule); -// } -// } -// -// setTimeout(callback); -//} -//#endif -}; -//#if !(MOZCENTRAL) -FontLoader.isFontLoadingAPISupported = typeof document !== 'undefined' && - !!document.fonts; -//#endif -//#if !(MOZCENTRAL || CHROME) -Object.defineProperty(FontLoader, 'isSyncFontLoadingSupported', { - get: function () { + }; +} else { + FontLoader.prototype.bind = function fontLoaderBind(fonts, callback) { + for (var i = 0, ii = fonts.length; i < ii; i++) { + var font = fonts[i]; + if (font.attached) { + continue; + } + + font.attached = true; + var rule = font.createFontFaceRule(); + if (rule) { + this.insertRule(rule); + } + } + + setTimeout(callback); + }; +} +if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('MOZCENTRAL')) { + FontLoader.isFontLoadingAPISupported = typeof document !== 'undefined' && + !!document.fonts; +} +if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('MOZCENTRAL || CHROME')) { + var isSyncFontLoadingSupported = function isSyncFontLoadingSupported() { if (typeof navigator === 'undefined') { // node.js - we can pretend sync font loading is supported. - return shadow(FontLoader, 'isSyncFontLoadingSupported', true); + return true; } var supported = false; @@ -326,12 +332,17 @@ Object.defineProperty(FontLoader, 'isSyncFontLoadingSupported', { supported = true; } // TODO other browsers - return shadow(FontLoader, 'isSyncFontLoadingSupported', supported); - }, - enumerable: true, - configurable: true -}); -//#endif + return supported; + }; + Object.defineProperty(FontLoader, 'isSyncFontLoadingSupported', { + get: function () { + return shadow(FontLoader, 'isSyncFontLoadingSupported', + isSyncFontLoadingSupported()); + }, + enumerable: true, + configurable: true + }); +} var IsEvalSupportedCached = { get value() { @@ -349,25 +360,27 @@ var FontFaceObject = (function FontFaceObjectClosure() { this.options = options; } FontFaceObject.prototype = { -//#if !(MOZCENTRAL) createNativeFontFace: function FontFaceObject_createNativeFontFace() { - if (!this.data) { - return null; - } + if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('MOZCENTRAL')) { + if (!this.data) { + return null; + } - if (this.options.disableFontFace) { - this.disableFontFace = true; - return null; - } + if (this.options.disableFontFace) { + this.disableFontFace = true; + return null; + } - var nativeFontFace = new FontFace(this.loadedName, this.data, {}); + var nativeFontFace = new FontFace(this.loadedName, this.data, {}); - if (this.options.fontRegistry) { - this.options.fontRegistry.registerFont(this); + if (this.options.fontRegistry) { + this.options.fontRegistry.registerFont(this); + } + return nativeFontFace; + } else { + throw new Error('Not implemented: createNativeFontFace'); } - return nativeFontFace; }, -//#endif createFontFaceRule: function FontFaceObject_createFontFaceRule() { if (!this.data) { @@ -434,6 +447,7 @@ var FontFaceObject = (function FontFaceObjectClosure() { return this.compiledGlyphs[character]; } }; + return FontFaceObject; })(); diff --git a/src/display/global.js b/src/display/global.js index 70def4c7c..04c451ab4 100644 --- a/src/display/global.js +++ b/src/display/global.js @@ -243,39 +243,39 @@ PDFJS.isEvalSupported = (PDFJS.isEvalSupported === undefined ? true : PDFJS.isEvalSupported); -//#if !MOZCENTRAL - var savedOpenExternalLinksInNewWindow = PDFJS.openExternalLinksInNewWindow; - delete PDFJS.openExternalLinksInNewWindow; - Object.defineProperty(PDFJS, 'openExternalLinksInNewWindow', { - get: function () { - return PDFJS.externalLinkTarget === LinkTarget.BLANK; - }, - set: function (value) { - if (value) { - deprecated('PDFJS.openExternalLinksInNewWindow, please use ' + - '"PDFJS.externalLinkTarget = PDFJS.LinkTarget.BLANK" instead.'); - } - if (PDFJS.externalLinkTarget !== LinkTarget.NONE) { - warn('PDFJS.externalLinkTarget is already initialized'); - return; - } - PDFJS.externalLinkTarget = value ? LinkTarget.BLANK : LinkTarget.NONE; - }, - enumerable: true, - configurable: true - }); - if (savedOpenExternalLinksInNewWindow) { - /** - * (Deprecated) Opens external links in a new window if enabled. - * The default behavior opens external links in the PDF.js window. - * - * NOTE: This property has been deprecated, please use - * `PDFJS.externalLinkTarget = PDFJS.LinkTarget.BLANK` instead. - * @var {boolean} - */ - PDFJS.openExternalLinksInNewWindow = savedOpenExternalLinksInNewWindow; + if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('MOZCENTRAL')) { + var savedOpenExternalLinksInNewWindow = PDFJS.openExternalLinksInNewWindow; + delete PDFJS.openExternalLinksInNewWindow; + Object.defineProperty(PDFJS, 'openExternalLinksInNewWindow', { + get: function () { + return PDFJS.externalLinkTarget === LinkTarget.BLANK; + }, + set: function (value) { + if (value) { + deprecated('PDFJS.openExternalLinksInNewWindow, please use ' + + '"PDFJS.externalLinkTarget = PDFJS.LinkTarget.BLANK" instead.'); + } + if (PDFJS.externalLinkTarget !== LinkTarget.NONE) { + warn('PDFJS.externalLinkTarget is already initialized'); + return; + } + PDFJS.externalLinkTarget = value ? LinkTarget.BLANK : LinkTarget.NONE; + }, + enumerable: true, + configurable: true + }); + if (savedOpenExternalLinksInNewWindow) { + /** + * (Deprecated) Opens external links in a new window if enabled. + * The default behavior opens external links in the PDF.js window. + * + * NOTE: This property has been deprecated, please use + * `PDFJS.externalLinkTarget = PDFJS.LinkTarget.BLANK` instead. + * @var {boolean} + */ + PDFJS.openExternalLinksInNewWindow = savedOpenExternalLinksInNewWindow; + } } -//#endif PDFJS.getDocument = displayAPI.getDocument; PDFJS.PDFDataRangeTransport = displayAPI.PDFDataRangeTransport; diff --git a/src/display/svg.js b/src/display/svg.js index 2d210f9fc..8d9f5e7f5 100644 --- a/src/display/svg.js +++ b/src/display/svg.js @@ -24,7 +24,8 @@ factory((root.pdfjsDisplaySVG = {}), root.pdfjsSharedUtil); } }(this, function (exports, sharedUtil) { -//#if (GENERIC || SINGLE_FILE) +if (typeof PDFJSDev === 'undefined' || + PDFJSDev.test('GENERIC || SINGLE_FILE')) { var FONT_IDENTITY_MATRIX = sharedUtil.FONT_IDENTITY_MATRIX; var IDENTITY_MATRIX = sharedUtil.IDENTITY_MATRIX; var ImageKind = sharedUtil.ImageKind; @@ -1208,5 +1209,5 @@ var SVGGraphics = (function SVGGraphicsClosure() { })(); exports.SVGGraphics = SVGGraphics; -//#endif +} })); diff --git a/src/display/text_layer.js b/src/display/text_layer.js index 893c6ea7d..19e5748f8 100644 --- a/src/display/text_layer.js +++ b/src/display/text_layer.js @@ -188,9 +188,10 @@ var renderTextLayer = (function renderTextLayerClosure() { } var canvas = document.createElement('canvas'); -//#if MOZCENTRAL || FIREFOX || GENERIC - canvas.mozOpaque = true; -//#endif + if (typeof PDFJSDev === 'undefined' || + PDFJSDev.test('FIREFOX || MOZCENTRAL || GENERIC')) { + canvas.mozOpaque = true; + } var ctx = canvas.getContext('2d', {alpha: false}); var lastFontSize; diff --git a/src/frameworks.js b/src/frameworks.js deleted file mode 100644 index 2f6968b7e..000000000 --- a/src/frameworks.js +++ /dev/null @@ -1,47 +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. - */ -/* globals require, module, requirejs, - workerSrc: true, isWorkerDisabled: true */ - -// included from api.js for GENERIC build - -'use strict'; - -var useRequireEnsure = false; -if (typeof window === 'undefined') { - // node.js - disable worker and set require.ensure. - isWorkerDisabled = true; - if (typeof require.ensure === 'undefined') { - require.ensure = require('node-ensure'); - } - useRequireEnsure = true; -} -if (typeof __webpack_require__ !== 'undefined') { - useRequireEnsure = true; -} -if (typeof requirejs !== 'undefined' && requirejs.toUrl) { - workerSrc = requirejs.toUrl('pdfjs-dist/build/pdf.worker.js'); -} -var dynamicLoaderSupported = typeof requirejs !== 'undefined' && requirejs.load; -var fakeWorkerFilesLoader = useRequireEnsure ? (function (callback) { - require.ensure([], function () { - var worker = require('./pdf.worker.js'); - callback(worker.WorkerMessageHandler); - }); -}) : dynamicLoaderSupported ? (function (callback) { - requirejs(['pdfjs-dist/build/pdf.worker'], function (worker) { - callback(worker.WorkerMessageHandler); - }); -}) : null; diff --git a/src/pdf.js b/src/pdf.js index 61dea39ea..941920320 100644 --- a/src/pdf.js +++ b/src/pdf.js @@ -18,18 +18,18 @@ (function (root, factory) { 'use strict'; if (typeof define === 'function' && define.amd) { -//#expand define('__BUNDLE_AMD_NAME__', ['exports'], factory); + define(PDFJSDev.eval('BUNDLE_AMD_NAME'), ['exports'], factory); } else if (typeof exports !== 'undefined') { factory(exports); } else { -//#expand factory((root.__BUNDLE_JS_NAME__ = {})); + factory((root[PDFJSDev.eval('BUNDLE_JS_NAME')] = {})); } }(this, function (exports) { // Use strict in our context only - users might not want it 'use strict'; -//#expand var pdfjsVersion = '__BUNDLE_VERSION__'; -//#expand var pdfjsBuild = '__BUNDLE_BUILD__'; + var pdfjsVersion = PDFJSDev.eval('BUNDLE_VERSION'); + var pdfjsBuild = PDFJSDev.eval('BUNDLE_BUILD'); var pdfjsFilePath = typeof document !== 'undefined' && document.currentScript ? @@ -43,35 +43,39 @@ }).call(pdfjsLibs); -//#if MAIN_FILE - exports.PDFJS = pdfjsLibs.pdfjsDisplayGlobal.PDFJS; - exports.build = pdfjsLibs.pdfjsDisplayAPI.build; - exports.version = pdfjsLibs.pdfjsDisplayAPI.version; - exports.getDocument = pdfjsLibs.pdfjsDisplayAPI.getDocument; - exports.PDFDataRangeTransport = - pdfjsLibs.pdfjsDisplayAPI.PDFDataRangeTransport; - exports.PDFWorker = pdfjsLibs.pdfjsDisplayAPI.PDFWorker; - exports.renderTextLayer = pdfjsLibs.pdfjsDisplayTextLayer.renderTextLayer; - exports.AnnotationLayer = - pdfjsLibs.pdfjsDisplayAnnotationLayer.AnnotationLayer; - exports.CustomStyle = pdfjsLibs.pdfjsDisplayDOMUtils.CustomStyle; - exports.PasswordResponses = pdfjsLibs.pdfjsSharedUtil.PasswordResponses; - exports.InvalidPDFException = pdfjsLibs.pdfjsSharedUtil.InvalidPDFException; - exports.MissingPDFException = pdfjsLibs.pdfjsSharedUtil.MissingPDFException; - exports.SVGGraphics = pdfjsLibs.pdfjsDisplaySVG.SVGGraphics; - exports.UnexpectedResponseException = - pdfjsLibs.pdfjsSharedUtil.UnexpectedResponseException; - exports.OPS = pdfjsLibs.pdfjsSharedUtil.OPS; - exports.UNSUPPORTED_FEATURES = pdfjsLibs.pdfjsSharedUtil.UNSUPPORTED_FEATURES; - exports.isValidUrl = pdfjsLibs.pdfjsSharedUtil.isValidUrl; - exports.createObjectURL = pdfjsLibs.pdfjsSharedUtil.createObjectURL; - exports.removeNullCharacters = pdfjsLibs.pdfjsSharedUtil.removeNullCharacters; - exports.shadow = pdfjsLibs.pdfjsSharedUtil.shadow; - exports.createBlob = pdfjsLibs.pdfjsSharedUtil.createBlob; - exports.getFilenameFromUrl = - pdfjsLibs.pdfjsDisplayDOMUtils.getFilenameFromUrl; - exports.addLinkAttributes = pdfjsLibs.pdfjsDisplayDOMUtils.addLinkAttributes; -//#else - exports.WorkerMessageHandler = pdfjsLibs.pdfjsCoreWorker.WorkerMessageHandler; -//#endif + if (PDFJSDev.test('MAIN_FILE')) { + exports.PDFJS = pdfjsLibs.pdfjsDisplayGlobal.PDFJS; + exports.build = pdfjsLibs.pdfjsDisplayAPI.build; + exports.version = pdfjsLibs.pdfjsDisplayAPI.version; + exports.getDocument = pdfjsLibs.pdfjsDisplayAPI.getDocument; + exports.PDFDataRangeTransport = + pdfjsLibs.pdfjsDisplayAPI.PDFDataRangeTransport; + exports.PDFWorker = pdfjsLibs.pdfjsDisplayAPI.PDFWorker; + exports.renderTextLayer = pdfjsLibs.pdfjsDisplayTextLayer.renderTextLayer; + exports.AnnotationLayer = + pdfjsLibs.pdfjsDisplayAnnotationLayer.AnnotationLayer; + exports.CustomStyle = pdfjsLibs.pdfjsDisplayDOMUtils.CustomStyle; + exports.PasswordResponses = pdfjsLibs.pdfjsSharedUtil.PasswordResponses; + exports.InvalidPDFException = pdfjsLibs.pdfjsSharedUtil.InvalidPDFException; + exports.MissingPDFException = pdfjsLibs.pdfjsSharedUtil.MissingPDFException; + exports.SVGGraphics = pdfjsLibs.pdfjsDisplaySVG.SVGGraphics; + exports.UnexpectedResponseException = + pdfjsLibs.pdfjsSharedUtil.UnexpectedResponseException; + exports.OPS = pdfjsLibs.pdfjsSharedUtil.OPS; + exports.UNSUPPORTED_FEATURES = + pdfjsLibs.pdfjsSharedUtil.UNSUPPORTED_FEATURES; + exports.isValidUrl = pdfjsLibs.pdfjsSharedUtil.isValidUrl; + exports.createObjectURL = pdfjsLibs.pdfjsSharedUtil.createObjectURL; + exports.removeNullCharacters = + pdfjsLibs.pdfjsSharedUtil.removeNullCharacters; + exports.shadow = pdfjsLibs.pdfjsSharedUtil.shadow; + exports.createBlob = pdfjsLibs.pdfjsSharedUtil.createBlob; + exports.getFilenameFromUrl = + pdfjsLibs.pdfjsDisplayDOMUtils.getFilenameFromUrl; + exports.addLinkAttributes = + pdfjsLibs.pdfjsDisplayDOMUtils.addLinkAttributes; + } else { + exports.WorkerMessageHandler = + pdfjsLibs.pdfjsCoreWorker.WorkerMessageHandler; + } })); diff --git a/src/shared/util.js b/src/shared/util.js index fe829729a..a9554fca7 100644 --- a/src/shared/util.js +++ b/src/shared/util.js @@ -616,49 +616,49 @@ function isEvalSupported() { } } -//#if !(FIREFOX || MOZCENTRAL || CHROME) -var Uint32ArrayView = (function Uint32ArrayViewClosure() { - - function Uint32ArrayView(buffer, length) { - this.buffer = buffer; - this.byteLength = buffer.length; - this.length = length === undefined ? (this.byteLength >> 2) : length; - ensureUint32ArrayViewProps(this.length); - } - Uint32ArrayView.prototype = Object.create(null); - - var uint32ArrayViewSetters = 0; - function createUint32ArrayProp(index) { - return { - get: function () { - var buffer = this.buffer, offset = index << 2; - return (buffer[offset] | (buffer[offset + 1] << 8) | - (buffer[offset + 2] << 16) | (buffer[offset + 3] << 24)) >>> 0; - }, - set: function (value) { - var buffer = this.buffer, offset = index << 2; - buffer[offset] = value & 255; - buffer[offset + 1] = (value >> 8) & 255; - buffer[offset + 2] = (value >> 16) & 255; - buffer[offset + 3] = (value >>> 24) & 255; - } - }; - } - - function ensureUint32ArrayViewProps(length) { - while (uint32ArrayViewSetters < length) { - Object.defineProperty(Uint32ArrayView.prototype, - uint32ArrayViewSetters, - createUint32ArrayProp(uint32ArrayViewSetters)); - uint32ArrayViewSetters++; +if (typeof PDFJSDev === 'undefined' || + !PDFJSDev.test('FIREFOX || MOZCENTRAL || CHROME')) { + var Uint32ArrayView = (function Uint32ArrayViewClosure() { + function Uint32ArrayView(buffer, length) { + this.buffer = buffer; + this.byteLength = buffer.length; + this.length = length === undefined ? (this.byteLength >> 2) : length; + ensureUint32ArrayViewProps(this.length); } - } + Uint32ArrayView.prototype = Object.create(null); - return Uint32ArrayView; -})(); + var uint32ArrayViewSetters = 0; + function createUint32ArrayProp(index) { + return { + get: function () { + var buffer = this.buffer, offset = index << 2; + return (buffer[offset] | (buffer[offset + 1] << 8) | + (buffer[offset + 2] << 16) | (buffer[offset + 3] << 24)) >>> 0; + }, + set: function (value) { + var buffer = this.buffer, offset = index << 2; + buffer[offset] = value & 255; + buffer[offset + 1] = (value >> 8) & 255; + buffer[offset + 2] = (value >> 16) & 255; + buffer[offset + 3] = (value >>> 24) & 255; + } + }; + } -exports.Uint32ArrayView = Uint32ArrayView; -//#endif + function ensureUint32ArrayViewProps(length) { + while (uint32ArrayViewSetters < length) { + Object.defineProperty(Uint32ArrayView.prototype, + uint32ArrayViewSetters, + createUint32ArrayProp(uint32ArrayViewSetters)); + uint32ArrayViewSetters++; + } + } + + return Uint32ArrayView; + })(); + + exports.Uint32ArrayView = Uint32ArrayView; +} var IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0]; @@ -1199,7 +1199,8 @@ function createPromiseCapability() { } return; } -//#if !MOZCENTRAL + +if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('MOZCENTRAL')) { var STATUS_PENDING = 0; var STATUS_RESOLVED = 1; var STATUS_REJECTED = 2; @@ -1317,7 +1318,7 @@ function createPromiseCapability() { } }; - function Promise(resolver) { + var Promise = function Promise(resolver) { this._status = STATUS_PENDING; this._handlers = []; try { @@ -1325,7 +1326,8 @@ function createPromiseCapability() { } catch (e) { this._reject(e); } - } + }; + /** * Builds a promise that is resolved when all the passed in promises are * resolved. @@ -1459,43 +1461,44 @@ function createPromiseCapability() { }; globalScope.Promise = Promise; -//#else -//throw new Error('DOM Promise is not present'); -//#endif +} else { + throw new Error('DOM Promise is not present'); +} + })(); -//#if !MOZCENTRAL -(function WeakMapClosure() { - if (globalScope.WeakMap) { - return; - } - - var id = 0; - function WeakMap() { - this.id = '$weakmap' + (id++); - } - WeakMap.prototype = { - has: function(obj) { - return !!Object.getOwnPropertyDescriptor(obj, this.id); - }, - get: function(obj, defaultValue) { - return this.has(obj) ? obj[this.id] : defaultValue; - }, - set: function(obj, value) { - Object.defineProperty(obj, this.id, { - value: value, - enumerable: false, - configurable: true - }); - }, - delete: function(obj) { - delete obj[this.id]; +if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('MOZCENTRAL')) { + (function WeakMapClosure() { + if (globalScope.WeakMap) { + return; } - }; - globalScope.WeakMap = WeakMap; -})(); -//#endif + var id = 0; + function WeakMap() { + this.id = '$weakmap' + (id++); + } + WeakMap.prototype = { + has: function(obj) { + return !!Object.getOwnPropertyDescriptor(obj, this.id); + }, + get: function(obj, defaultValue) { + return this.has(obj) ? obj[this.id] : defaultValue; + }, + set: function(obj, value) { + Object.defineProperty(obj, this.id, { + value: value, + enumerable: false, + configurable: true + }); + }, + delete: function(obj) { + delete obj[this.id]; + } + }; + + globalScope.WeakMap = WeakMap; + })(); +} var StatTimer = (function StatTimerClosure() { function rpad(str, pad, length) { @@ -1736,8 +1739,8 @@ function loadJpegStream(id, imageUrl, objs) { img.src = imageUrl; } -//#if !(MOZCENTRAL) -//// Polyfill from https://github.com/Polymer/URL +if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('MOZCENTRAL')) { +// Polyfill from https://github.com/Polymer/URL /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ (function checkURLConstructor(scope) { @@ -2378,7 +2381,7 @@ function loadJpegStream(id, imageUrl, objs) { scope.URL = JURL; })(globalScope); -//#endif +} exports.FONT_IDENTITY_MATRIX = FONT_IDENTITY_MATRIX; exports.IDENTITY_MATRIX = IDENTITY_MATRIX; diff --git a/src/worker_loader.js b/src/worker_loader.js index 5c3af1a38..05a5c3685 100644 --- a/src/worker_loader.js +++ b/src/worker_loader.js @@ -15,16 +15,16 @@ 'use strict'; -//#if !PRODUCTION -//// Patch importScripts to work around a bug in WebKit and Chrome 48-. -//// See https://crbug.com/572225 and https://webkit.org/b/153317. -self.importScripts = (function (importScripts) { - return function() { - setTimeout(function () {}, 0); - return importScripts.apply(this, arguments); - }; -})(importScripts); -//#endif +if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) { + // Patch importScripts to work around a bug in WebKit and Chrome 48-. + // See https://crbug.com/572225 and https://webkit.org/b/153317. + self.importScripts = (function (importScripts) { + return function() { + setTimeout(function () {}, 0); + return importScripts.apply(this, arguments); + }; + })(importScripts); +} importScripts('../node_modules/requirejs/require.js'); diff --git a/web/app.js b/web/app.js index e173c1ded..eb3cbe202 100644 --- a/web/app.js +++ b/web/app.js @@ -105,17 +105,18 @@ var DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT = 5000; function configure(PDFJS) { PDFJS.imageResourcesPath = './images/'; -//#if (FIREFOX || MOZCENTRAL || GENERIC || CHROME) -//PDFJS.workerSrc = '../build/pdf.worker.js'; -//#endif -//#if !PRODUCTION - PDFJS.cMapUrl = '../external/bcmaps/'; - PDFJS.cMapPacked = true; - PDFJS.workerSrc = '../src/worker_loader.js'; -//#else -//PDFJS.cMapUrl = '../web/cmaps/'; -//PDFJS.cMapPacked = true; -//#endif + if (typeof PDFJSDev !== 'undefined' && + PDFJSDev.test('FIREFOX || MOZCENTRAL || GENERIC || CHROME')) { + PDFJS.workerSrc = '../build/pdf.worker.js'; + } + if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) { + PDFJS.cMapUrl = '../external/bcmaps/'; + PDFJS.cMapPacked = true; + PDFJS.workerSrc = '../src/worker_loader.js'; + } else { + PDFJS.cMapUrl = '../web/cmaps/'; + PDFJS.cMapPacked = true; + } } var DefaultExernalServices = { @@ -437,21 +438,22 @@ var PDFViewerApplication = { }, get supportsFullscreen() { -//#if MOZCENTRAL -// var support = document.fullscreenEnabled === true || -// document.mozFullScreenEnabled === true; -//#else - var doc = document.documentElement; - var support = !!(doc.requestFullscreen || doc.mozRequestFullScreen || - doc.webkitRequestFullScreen || doc.msRequestFullscreen); + var support; + if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('MOZCENTRAL')) { + support = document.fullscreenEnabled === true || + document.mozFullScreenEnabled === true; + } else { + var doc = document.documentElement; + support = !!(doc.requestFullscreen || doc.mozRequestFullScreen || + doc.webkitRequestFullScreen || doc.msRequestFullscreen); - if (document.fullscreenEnabled === false || - document.mozFullScreenEnabled === false || - document.webkitFullscreenEnabled === false || - document.msFullscreenEnabled === false) { - support = false; + if (document.fullscreenEnabled === false || + document.mozFullScreenEnabled === false || + document.webkitFullscreenEnabled === false || + document.msFullscreenEnabled === false) { + support = false; + } } -//#endif if (support && pdfjsLib.PDFJS.disableFullscreen === true) { support = false; } @@ -481,39 +483,42 @@ var PDFViewerApplication = { return this.externalServices.supportedMouseWheelZoomModifierKeys; }, -//#if (FIREFOX || MOZCENTRAL || CHROME) initPassiveLoading: function pdfViewInitPassiveLoading() { - this.externalServices.initPassiveLoading({ - onOpenWithTransport: function (url, length, transport) { - PDFViewerApplication.open(url, {range: transport}); + if (typeof PDFJSDev !== 'undefined' && + PDFJSDev.test('FIREFOX || MOZCENTRAL || CHROME')) { + this.externalServices.initPassiveLoading({ + onOpenWithTransport: function (url, length, transport) { + PDFViewerApplication.open(url, {range: transport}); - if (length) { - PDFViewerApplication.pdfDocumentProperties.setFileSize(length); + if (length) { + PDFViewerApplication.pdfDocumentProperties.setFileSize(length); + } + }, + onOpenWithData: function (data) { + PDFViewerApplication.open(data); + }, + onOpenWithURL: function (url, length, originalURL) { + var file = url, args = null; + if (length !== undefined) { + args = {length: length}; + } + if (originalURL !== undefined) { + file = {file: url, originalURL: originalURL}; + } + PDFViewerApplication.open(file, args); + }, + onError: function (e) { + PDFViewerApplication.error(mozL10n.get('loading_error', null, + 'An error occurred while loading the PDF.'), e); + }, + onProgress: function (loaded, total) { + PDFViewerApplication.progress(loaded / total); } - }, - onOpenWithData: function (data) { - PDFViewerApplication.open(data); - }, - onOpenWithURL: function (url, length, originalURL) { - var file = url, args = null; - if (length !== undefined) { - args = {length: length}; - } - if (originalURL !== undefined) { - file = {file: url, originalURL: originalURL}; - } - PDFViewerApplication.open(file, args); - }, - onError: function (e) { - PDFViewerApplication.error(mozL10n.get('loading_error', null, - 'An error occurred while loading the PDF.'), e); - }, - onProgress: function (loaded, total) { - PDFViewerApplication.progress(loaded / total); - } - }); + }); + } else { + throw new Error('Not implemented: initPassiveLoading'); + } }, -//#endif setTitleUsingUrl: function pdfViewSetTitleUsingUrl(url) { this.url = url; @@ -584,12 +589,11 @@ var PDFViewerApplication = { * is opened. */ open: function pdfViewOpen(file, args) { -//#if GENERIC - if (arguments.length > 2 || typeof args === 'number') { + if ((typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) && + (arguments.length > 2 || typeof args === 'number')) { return Promise.reject( new Error('Call of open() with obsolete signature.')); } -//#endif if (this.pdfLoadingTask) { // We need to destroy already opened document. return this.close().then(function () { @@ -707,27 +711,23 @@ var PDFViewerApplication = { }, fallback: function pdfViewFallback(featureId) { -//#if !PRODUCTION - if (true) { - return; + if (typeof PDFJSDev !== 'undefined' && + PDFJSDev.test('FIREFOX || MOZCENTRAL')) { + // Only trigger the fallback once so we don't spam the user with messages + // for one PDF. + if (this.fellback) { + return; + } + this.fellback = true; + var url = this.url.split('#')[0]; + this.externalServices.fallback({ featureId: featureId, url: url }, + function response(download) { + if (!download) { + return; + } + PDFViewerApplication.download(); + }); } -//#endif -//#if (FIREFOX || MOZCENTRAL) - // Only trigger the fallback once so we don't spam the user with messages - // for one PDF. - if (this.fellback) { - return; - } - this.fellback = true; - var url = this.url.split('#')[0]; - this.externalServices.fallback({ featureId: featureId, url: url }, - function response(download) { - if (!download) { - return; - } - PDFViewerApplication.download(); - }); -//#endif }, /** @@ -763,43 +763,44 @@ var PDFViewerApplication = { } } -//#if !(FIREFOX || MOZCENTRAL) - var errorWrapperConfig = this.appConfig.errorWrapper; - var errorWrapper = errorWrapperConfig.container; - errorWrapper.removeAttribute('hidden'); + if (typeof PDFJSDev === 'undefined' || + !PDFJSDev.test('FIREFOX || MOZCENTRAL')) { + var errorWrapperConfig = this.appConfig.errorWrapper; + var errorWrapper = errorWrapperConfig.container; + errorWrapper.removeAttribute('hidden'); - var errorMessage = errorWrapperConfig.errorMessage; - errorMessage.textContent = message; + var errorMessage = errorWrapperConfig.errorMessage; + errorMessage.textContent = message; - var closeButton = errorWrapperConfig.closeButton; - closeButton.onclick = function() { - errorWrapper.setAttribute('hidden', 'true'); - }; + var closeButton = errorWrapperConfig.closeButton; + closeButton.onclick = function() { + errorWrapper.setAttribute('hidden', 'true'); + }; - var errorMoreInfo = errorWrapperConfig.errorMoreInfo; - var moreInfoButton = errorWrapperConfig.moreInfoButton; - var lessInfoButton = errorWrapperConfig.lessInfoButton; - moreInfoButton.onclick = function() { - errorMoreInfo.removeAttribute('hidden'); - moreInfoButton.setAttribute('hidden', 'true'); - lessInfoButton.removeAttribute('hidden'); - errorMoreInfo.style.height = errorMoreInfo.scrollHeight + 'px'; - }; - lessInfoButton.onclick = function() { - errorMoreInfo.setAttribute('hidden', 'true'); + var errorMoreInfo = errorWrapperConfig.errorMoreInfo; + var moreInfoButton = errorWrapperConfig.moreInfoButton; + var lessInfoButton = errorWrapperConfig.lessInfoButton; + moreInfoButton.onclick = function() { + errorMoreInfo.removeAttribute('hidden'); + moreInfoButton.setAttribute('hidden', 'true'); + lessInfoButton.removeAttribute('hidden'); + errorMoreInfo.style.height = errorMoreInfo.scrollHeight + 'px'; + }; + lessInfoButton.onclick = function() { + errorMoreInfo.setAttribute('hidden', 'true'); + moreInfoButton.removeAttribute('hidden'); + lessInfoButton.setAttribute('hidden', 'true'); + }; + moreInfoButton.oncontextmenu = noContextMenuHandler; + lessInfoButton.oncontextmenu = noContextMenuHandler; + closeButton.oncontextmenu = noContextMenuHandler; moreInfoButton.removeAttribute('hidden'); lessInfoButton.setAttribute('hidden', 'true'); - }; - moreInfoButton.oncontextmenu = noContextMenuHandler; - lessInfoButton.oncontextmenu = noContextMenuHandler; - closeButton.oncontextmenu = noContextMenuHandler; - moreInfoButton.removeAttribute('hidden'); - lessInfoButton.setAttribute('hidden', 'true'); - errorMoreInfo.value = moreInfoText; -//#else -// console.error(message + '\n' + moreInfoText); -// this.fallback(); -//#endif + errorMoreInfo.value = moreInfoText; + } else { + console.error(message + '\n' + moreInfoText); + this.fallback(); + } }, progress: function pdfViewProgress(level) { @@ -851,15 +852,14 @@ var PDFViewerApplication = { var id = this.documentFingerprint = pdfDocument.fingerprint; var store = this.store = new ViewHistory(id); -//#if GENERIC - var baseDocumentUrl = null; -//#endif -//#if (FIREFOX || MOZCENTRAL) -// var baseDocumentUrl = this.url.split('#')[0]; -//#endif -//#if CHROME -// var baseDocumentUrl = location.href.split('#')[0]; -//#endif + var baseDocumentUrl; + if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) { + baseDocumentUrl = null; + } else if (PDFJSDev.test('FIREFOX || MOZCENTRAL')) { + baseDocumentUrl = this.url.split('#')[0]; + } else if (PDFJSDev.test('CHROME')) { + baseDocumentUrl = location.href.split('#')[0]; + } this.pdfLinkService.setDocument(pdfDocument, baseDocumentUrl); var pdfViewer = this.pdfViewer; @@ -1017,39 +1017,35 @@ var PDFViewerApplication = { self.fallback(pdfjsLib.UNSUPPORTED_FEATURES.forms); } -//#if !PRODUCTION - if (true) { - return; + if (typeof PDFJSDev !== 'undefined' && + PDFJSDev.test('FIREFOX || MOZCENTRAL')) { + var versionId = String(info.PDFFormatVersion).slice(-1) | 0; + var generatorId = 0; + var KNOWN_GENERATORS = [ + 'acrobat distiller', 'acrobat pdfwriter', 'adobe livecycle', + 'adobe pdf library', 'adobe photoshop', 'ghostscript', 'tcpdf', + 'cairo', 'dvipdfm', 'dvips', 'pdftex', 'pdfkit', 'itext', 'prince', + 'quarkxpress', 'mac os x', 'microsoft', 'openoffice', 'oracle', + 'luradocument', 'pdf-xchange', 'antenna house', 'aspose.cells', 'fpdf' + ]; + if (info.Producer) { + KNOWN_GENERATORS.some(function (generator, s, i) { + if (generator.indexOf(s) < 0) { + return false; + } + generatorId = i + 1; + return true; + }.bind(null, info.Producer.toLowerCase())); + } + var formType = !info.IsAcroFormPresent ? null : info.IsXFAPresent ? + 'xfa' : 'acroform'; + self.externalServices.reportTelemetry({ + type: 'documentInfo', + version: versionId, + generator: generatorId, + formType: formType + }); } -//#endif -//#if (FIREFOX || MOZCENTRAL) - var versionId = String(info.PDFFormatVersion).slice(-1) | 0; - var generatorId = 0; - var KNOWN_GENERATORS = [ - 'acrobat distiller', 'acrobat pdfwriter', 'adobe livecycle', - 'adobe pdf library', 'adobe photoshop', 'ghostscript', 'tcpdf', - 'cairo', 'dvipdfm', 'dvips', 'pdftex', 'pdfkit', 'itext', 'prince', - 'quarkxpress', 'mac os x', 'microsoft', 'openoffice', 'oracle', - 'luradocument', 'pdf-xchange', 'antenna house', 'aspose.cells', 'fpdf' - ]; - if (info.Producer) { - KNOWN_GENERATORS.some(function (generator, s, i) { - if (generator.indexOf(s) < 0) { - return false; - } - generatorId = i + 1; - return true; - }.bind(null, info.Producer.toLowerCase())); - } - var formType = !info.IsAcroFormPresent ? null : info.IsXFAPresent ? - 'xfa' : 'acroform'; - self.externalServices.reportTelemetry({ - type: 'documentInfo', - version: versionId, - generator: generatorId, - formType: formType - }); -//#endif }); }, @@ -1132,16 +1128,12 @@ var PDFViewerApplication = { printService.layout(); -//#if !PRODUCTION - if (true) { - return; + if (typeof PDFJSDev !== 'undefined' && + PDFJSDev.test('FIREFOX || MOZCENTRAL')) { + this.externalServices.reportTelemetry({ + type: 'print' + }); } -//#endif -//#if (FIREFOX || MOZCENTRAL) - this.externalServices.reportTelemetry({ - type: 'print' - }); -//#endif }, // Whether all pages of the PDF have the same width and height. @@ -1272,42 +1264,43 @@ var PDFViewerApplication = { eventBus.on('documentproperties', webViewerDocumentProperties); eventBus.on('find', webViewerFind); eventBus.on('findfromurlhash', webViewerFindFromUrlHash); -//#if GENERIC - eventBus.on('fileinputchange', webViewerFileInputChange); -//#endif + if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) { + eventBus.on('fileinputchange', webViewerFileInputChange); + } } }; -//#if GENERIC -var HOSTED_VIEWER_ORIGINS = ['null', - 'http://mozilla.github.io', 'https://mozilla.github.io']; -function validateFileURL(file) { - try { - var viewerOrigin = new URL(window.location.href).origin || 'null'; - if (HOSTED_VIEWER_ORIGINS.indexOf(viewerOrigin) >= 0) { - // Hosted or local viewer, allow for any file locations - return; - } - var fileOrigin = new URL(file, window.location.href).origin; - // Removing of the following line will not guarantee that the viewer will - // start accepting URLs from foreign origin -- CORS headers on the remote - // server must be properly configured. - if (fileOrigin !== viewerOrigin) { - throw new Error('file origin does not match viewer\'s'); - } - } catch (e) { - var message = e && e.message; - var loadingErrorMessage = mozL10n.get('loading_error', null, - 'An error occurred while loading the PDF.'); +var validateFileURL; +if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) { + var HOSTED_VIEWER_ORIGINS = ['null', + 'http://mozilla.github.io', 'https://mozilla.github.io']; + validateFileURL = function validateFileURL(file) { + try { + var viewerOrigin = new URL(window.location.href).origin || 'null'; + if (HOSTED_VIEWER_ORIGINS.indexOf(viewerOrigin) >= 0) { + // Hosted or local viewer, allow for any file locations + return; + } + var fileOrigin = new URL(file, window.location.href).origin; + // Removing of the following line will not guarantee that the viewer will + // start accepting URLs from foreign origin -- CORS headers on the remote + // server must be properly configured. + if (fileOrigin !== viewerOrigin) { + throw new Error('file origin does not match viewer\'s'); + } + } catch (e) { + var message = e && e.message; + var loadingErrorMessage = mozL10n.get('loading_error', null, + 'An error occurred while loading the PDF.'); - var moreInfo = { - message: message - }; - PDFViewerApplication.error(loadingErrorMessage, moreInfo); - throw e; - } + var moreInfo = { + message: message + }; + PDFViewerApplication.error(loadingErrorMessage, moreInfo); + throw e; + } + }; } -//#endif function loadAndEnablePDFBug(enabledTabs) { return new Promise(function (resolve, reject) { @@ -1328,48 +1321,44 @@ function loadAndEnablePDFBug(enabledTabs) { } function webViewerInitialized() { -//#if GENERIC - var queryString = document.location.search.substring(1); - var params = parseQueryString(queryString); - var file = 'file' in params ? params.file : DEFAULT_URL; - validateFileURL(file); -//#endif -//#if (FIREFOX || MOZCENTRAL) -//var file = window.location.href.split('#')[0]; -//#endif -//#if CHROME -//var file = DEFAULT_URL; -//#endif + var file; + if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) { + var queryString = document.location.search.substring(1); + var params = parseQueryString(queryString); + file = 'file' in params ? params.file : DEFAULT_URL; + validateFileURL(file); + } else if (PDFJSDev.test('FIREFOX || MOZCENTRAL')) { + file = window.location.href.split('#')[0]; + } else if (PDFJSDev.test('CHROME')) { + file = DEFAULT_URL; + } var waitForBeforeOpening = []; var appConfig = PDFViewerApplication.appConfig; -//#if GENERIC - var fileInput = document.createElement('input'); - fileInput.id = appConfig.openFileInputName; - fileInput.className = 'fileInput'; - fileInput.setAttribute('type', 'file'); - fileInput.oncontextmenu = noContextMenuHandler; - document.body.appendChild(fileInput); + if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) { + var fileInput = document.createElement('input'); + fileInput.id = appConfig.openFileInputName; + fileInput.className = 'fileInput'; + fileInput.setAttribute('type', 'file'); + fileInput.oncontextmenu = noContextMenuHandler; + document.body.appendChild(fileInput); - if (!window.File || !window.FileReader || !window.FileList || !window.Blob) { + if (!window.File || !window.FileReader || + !window.FileList || !window.Blob) { + appConfig.toolbar.openFile.setAttribute('hidden', 'true'); + appConfig.secondaryToolbar.openFileButton.setAttribute('hidden', 'true'); + } else { + fileInput.value = null; + } + } else { appConfig.toolbar.openFile.setAttribute('hidden', 'true'); appConfig.secondaryToolbar.openFileButton.setAttribute('hidden', 'true'); - } else { - fileInput.value = null; } -//#else -//appConfig.toolbar.openFile.setAttribute('hidden', 'true'); -//appConfig.secondaryToolbar.openFileButton.setAttribute('hidden', 'true'); -//#endif - var PDFJS = pdfjsLib.PDFJS; -//#if !PRODUCTION - if (true) { -//#else -//if (PDFViewerApplication.preferencePdfBugEnabled) { -//#endif + if ((typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) || + PDFViewerApplication.preferencePdfBugEnabled) { // Special debugging flags in the hash section of the URL. var hash = document.location.hash.substring(1); var hashParams = parseQueryString(hash); @@ -1405,17 +1394,18 @@ function webViewerInitialized() { PDFJS.ignoreCurrentPositionOnZoom = (hashParams['ignorecurrentpositiononzoom'] === 'true'); } -//#if !PRODUCTION - if ('disablebcmaps' in hashParams && hashParams['disablebcmaps']) { - PDFJS.cMapUrl = '../external/cmaps/'; - PDFJS.cMapPacked = false; + if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) { + if ('disablebcmaps' in hashParams && hashParams['disablebcmaps']) { + PDFJS.cMapUrl = '../external/cmaps/'; + PDFJS.cMapPacked = false; + } } -//#endif -//#if !(FIREFOX || MOZCENTRAL) - if ('locale' in hashParams) { - PDFJS.locale = hashParams['locale']; + if (typeof PDFJSDev === 'undefined' || + !PDFJSDev.test('FIREFOX || MOZCENTRAL')) { + if ('locale' in hashParams) { + PDFJS.locale = hashParams['locale']; + } } -//#endif if ('textlayer' in hashParams) { switch (hashParams['textlayer']) { case 'off': @@ -1437,16 +1427,16 @@ function webViewerInitialized() { } } -//#if !(FIREFOX || MOZCENTRAL) - mozL10n.setLanguage(PDFJS.locale); -//#endif -//#if (FIREFOX || MOZCENTRAL) - if (!PDFViewerApplication.supportsDocumentFonts) { - PDFJS.disableFontFace = true; - console.warn(mozL10n.get('web_fonts_disabled', null, - 'Web fonts are disabled: unable to use embedded PDF fonts.')); + if (typeof PDFJSDev === 'undefined' || + !PDFJSDev.test('FIREFOX || MOZCENTRAL')) { + mozL10n.setLanguage(PDFJS.locale); + } else { + if (!PDFViewerApplication.supportsDocumentFonts) { + PDFJS.disableFontFace = true; + console.warn(mozL10n.get('web_fonts_disabled', null, + 'Web fonts are disabled: unable to use embedded PDF fonts.')); + } } -//#endif if (!PDFViewerApplication.supportsPrinting) { appConfig.toolbar.print.classList.add('hidden'); @@ -1539,44 +1529,45 @@ function webViewerInitialized() { }); } -//#if GENERIC -function webViewerOpenFileViaURL(file) { - if (file && file.lastIndexOf('file:', 0) === 0) { - // file:-scheme. Load the contents in the main thread because QtWebKit - // cannot load file:-URLs in a Web Worker. file:-URLs are usually loaded - // very quickly, so there is no need to set up progress event listeners. - PDFViewerApplication.setTitleUsingUrl(file); - var xhr = new XMLHttpRequest(); - xhr.onload = function() { - PDFViewerApplication.open(new Uint8Array(xhr.response)); - }; - try { - xhr.open('GET', file); - xhr.responseType = 'arraybuffer'; - xhr.send(); - } catch (e) { - PDFViewerApplication.error(mozL10n.get('loading_error', null, - 'An error occurred while loading the PDF.'), e); +var webViewerOpenFileViaURL; +if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) { + webViewerOpenFileViaURL = function webViewerOpenFileViaURL(file) { + if (file && file.lastIndexOf('file:', 0) === 0) { + // file:-scheme. Load the contents in the main thread because QtWebKit + // cannot load file:-URLs in a Web Worker. file:-URLs are usually loaded + // very quickly, so there is no need to set up progress event listeners. + PDFViewerApplication.setTitleUsingUrl(file); + var xhr = new XMLHttpRequest(); + xhr.onload = function() { + PDFViewerApplication.open(new Uint8Array(xhr.response)); + }; + try { + xhr.open('GET', file); + xhr.responseType = 'arraybuffer'; + xhr.send(); + } catch (e) { + PDFViewerApplication.error(mozL10n.get('loading_error', null, + 'An error occurred while loading the PDF.'), e); + } + return; } - return; - } - if (file) { - PDFViewerApplication.open(file); - } + if (file) { + PDFViewerApplication.open(file); + } + }; +} else if (PDFJSDev.test('FIREFOX || MOZCENTRAL || CHROME')) { + webViewerOpenFileViaURL = function webViewerOpenFileViaURL(file) { + PDFViewerApplication.setTitleUsingUrl(file); + PDFViewerApplication.initPassiveLoading(); + }; +} else { + webViewerOpenFileViaURL = function webViewerOpenFileURL(file) { + if (file) { + throw new Error('Not implemented: webViewerOpenFileURL'); + } + }; } -//#elif (FIREFOX || MOZCENTRAL || CHROME) -//function webViewerOpenFileViaURL(file) { -// PDFViewerApplication.setTitleUsingUrl(file); -// PDFViewerApplication.initPassiveLoading(); -//} -//#else -//function webViewerOpenFileURL(file) { -// if (file) { -// throw new Error('Not implemented: webViewerOpenFileURL'); -// } -//} -//#endif function webViewerPageRendered(e) { var pageNumber = e.pageNumber; @@ -1612,40 +1603,31 @@ function webViewerPageRendered(e) { 'An error occurred while rendering the page.'), pageView.error); } -//#if !PRODUCTION - if (true) { - return; - } -//#endif -//#if (FIREFOX || MOZCENTRAL) - PDFViewerApplication.externalServices.reportTelemetry({ - type: 'pageInfo' - }); - // It is a good time to report stream and font types. - PDFViewerApplication.pdfDocument.getStats().then(function (stats) { + if (typeof PDFJSDev !== 'undefined' && + PDFJSDev.test('FIREFOX || MOZCENTRAL')) { PDFViewerApplication.externalServices.reportTelemetry({ - type: 'documentStats', - stats: stats + type: 'pageInfo' }); - }); -//#endif + // It is a good time to report stream and font types. + PDFViewerApplication.pdfDocument.getStats().then(function (stats) { + PDFViewerApplication.externalServices.reportTelemetry({ + type: 'documentStats', + stats: stats + }); + }); + } } function webViewerTextLayerRendered(e) { -//#if !PRODUCTION - if (true) { - return; - } -//#endif -//#if (FIREFOX || MOZCENTRAL) - if (e.numTextDivs > 0 && !PDFViewerApplication.supportsDocumentColors) { + if (typeof PDFJSDev !== 'undefined' && + PDFJSDev.test('FIREFOX || MOZCENTRAL') && + e.numTextDivs > 0 && !PDFViewerApplication.supportsDocumentColors) { console.error(mozL10n.get('document_colors_not_allowed', null, 'PDF documents are not allowed to use their own colors: ' + '\'Allow pages to choose their own colors\' ' + 'is deactivated in the browser.')); PDFViewerApplication.fallback(); } -//#endif } function webViewerPageMode(e) { @@ -1803,43 +1785,45 @@ function webViewerHashchange(e) { } } -//#if GENERIC -window.addEventListener('change', function webViewerChange(evt) { - var files = evt.target.files; - if (!files || files.length === 0) { - return; - } - PDFViewerApplication.eventBus.dispatch('fileinputchange', - {fileInput: evt.target}); -}, true); +var webViewerFileInputChange; +if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) { + window.addEventListener('change', function webViewerChange(evt) { + var files = evt.target.files; + if (!files || files.length === 0) { + return; + } + PDFViewerApplication.eventBus.dispatch('fileinputchange', + {fileInput: evt.target}); + }, true); -function webViewerFileInputChange(e) { - var file = e.fileInput.files[0]; + webViewerFileInputChange = function webViewerFileInputChange(e) { + var file = e.fileInput.files[0]; - if (!pdfjsLib.PDFJS.disableCreateObjectURL && - typeof URL !== 'undefined' && URL.createObjectURL) { - PDFViewerApplication.open(URL.createObjectURL(file)); - } else { - // Read the local file into a Uint8Array. - var fileReader = new FileReader(); - fileReader.onload = function webViewerChangeFileReaderOnload(evt) { - var buffer = evt.target.result; - var uint8Array = new Uint8Array(buffer); - PDFViewerApplication.open(uint8Array); - }; - fileReader.readAsArrayBuffer(file); - } + if (!pdfjsLib.PDFJS.disableCreateObjectURL && + typeof URL !== 'undefined' && URL.createObjectURL) { + PDFViewerApplication.open(URL.createObjectURL(file)); + } else { + // Read the local file into a Uint8Array. + var fileReader = new FileReader(); + fileReader.onload = function webViewerChangeFileReaderOnload(evt) { + var buffer = evt.target.result; + var uint8Array = new Uint8Array(buffer); + PDFViewerApplication.open(uint8Array); + }; + fileReader.readAsArrayBuffer(file); + } - PDFViewerApplication.setTitleUsingUrl(file.name); + PDFViewerApplication.setTitleUsingUrl(file.name); - // URL does not reflect proper document location - hiding some icons. - var appConfig = PDFViewerApplication.appConfig; - appConfig.toolbar.viewBookmark.setAttribute('hidden', 'true'); - appConfig.secondaryToolbar.viewBookmarkButton.setAttribute('hidden', 'true'); - appConfig.toolbar.download.setAttribute('hidden', 'true'); - appConfig.secondaryToolbar.downloadButton.setAttribute('hidden', 'true'); + // URL does not reflect proper document location - hiding some icons. + var appConfig = PDFViewerApplication.appConfig; + appConfig.toolbar.viewBookmark.setAttribute('hidden', 'true'); + appConfig.secondaryToolbar.viewBookmarkButton.setAttribute('hidden', + 'true'); + appConfig.toolbar.download.setAttribute('hidden', 'true'); + appConfig.secondaryToolbar.downloadButton.setAttribute('hidden', 'true'); + }; } -//#endif window.addEventListener('localized', function localized(evt) { PDFViewerApplication.eventBus.dispatch('localized'); @@ -2091,17 +2075,18 @@ window.addEventListener('keydown', function keydown(evt) { } } -//#if !(FIREFOX || MOZCENTRAL) - // CTRL or META without shift - if (cmd === 1 || cmd === 8) { - switch (evt.keyCode) { - case 83: // s - PDFViewerApplication.download(); - handled = true; - break; + if (typeof PDFJSDev === 'undefined' || + !PDFJSDev.test('FIREFOX || MOZCENTRAL')) { + // CTRL or META without shift + if (cmd === 1 || cmd === 8) { + switch (evt.keyCode) { + case 83: // s + PDFViewerApplication.download(); + handled = true; + break; + } } } -//#endif // CTRL+ALT or Option+Command if (cmd === 3 || cmd === 10) { diff --git a/web/chromecom.js b/web/chromecom.js index 998042976..899948036 100644 --- a/web/chromecom.js +++ b/web/chromecom.js @@ -30,7 +30,11 @@ root.pdfjsWebPDFJS); } }(this, function (exports, app, overlayManager, preferences, pdfjsLib) { -//#if CHROME + if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('CHROME')) { + throw new Error('Module "pdfjs-web/chromecom" shall not be used outside ' + + 'CHROME build.'); + } + var PDFViewerApplication = app.PDFViewerApplication; var DefaultExernalServices = app.DefaultExernalServices; var OverlayManager = overlayManager.OverlayManager; @@ -198,7 +202,7 @@ // because the shown string should match the UI at chrome://extensions. // These strings are from chrome/app/resources/generated_resources_*.xtb. var i18nFileAccessLabel = -//#include $ROOT/web/chrome-i18n-allow-access-to-file-urls.json + PDFJSDev.json('$ROOT/web/chrome-i18n-allow-access-to-file-urls.json') [chrome.i18n.getUILanguage && chrome.i18n.getUILanguage()]; if (i18nFileAccessLabel) { @@ -352,5 +356,4 @@ PDFViewerApplication.externalServices = ChromeExternalServices; exports.ChromeCom = ChromeCom; -//#endif })); diff --git a/web/download_manager.js b/web/download_manager.js index 748176473..e58f046c1 100644 --- a/web/download_manager.js +++ b/web/download_manager.js @@ -25,7 +25,8 @@ factory((root.pdfjsWebDownloadManager = {}), root.pdfjsWebPDFJS); } }(this, function (exports, pdfjsLib) { -//#if GENERIC || CHROME +if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC || CHROME')) { + /* jshint -W082 */ function download(blobUrl, filename) { var a = document.createElement('a'); if (a.click) { @@ -106,5 +107,5 @@ }; exports.DownloadManager = DownloadManager; -//#endif +} })); diff --git a/web/firefoxcom.js b/web/firefoxcom.js index 42bf997f2..05377113f 100644 --- a/web/firefoxcom.js +++ b/web/firefoxcom.js @@ -27,7 +27,12 @@ root.pdfjsWebApp, root.pdfjsWebPDFJS); } }(this, function (exports, preferences, app, pdfjsLib) { -//#if FIREFOX || MOZCENTRAL +if (typeof PDFJSDev === 'undefined' || + !PDFJSDev.test('FIREFOX || MOZCENTRAL')) { + throw new Error('Module "pdfjs-web/firefoxcom" shall not be used outside ' + + 'FIREFOX and MOZCENTRAL builds.'); +} + var Preferences = preferences.Preferences; var PDFViewerApplication = app.PDFViewerApplication; @@ -288,5 +293,4 @@ document.mozL10n.setExternalLocalizerServices({ exports.DownloadManager = DownloadManager; exports.FirefoxCom = FirefoxCom; -//#endif })); diff --git a/web/pdf_history.js b/web/pdf_history.js index 6770d326d..9f732c708 100644 --- a/web/pdf_history.js +++ b/web/pdf_history.js @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/* globals chrome */ 'use strict'; @@ -191,30 +192,30 @@ _pushOrReplaceState: function pdfHistory_pushOrReplaceState(stateObj, replace) { -//#if CHROME // history.state.chromecomState is managed by chromecom.js. - if (window.history.state && 'chromecomState' in window.history.state) { + if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME') && + window.history.state && 'chromecomState' in window.history.state) { stateObj = stateObj || {}; stateObj.chromecomState = window.history.state.chromecomState; } -//#endif if (replace) { -//#if (GENERIC || CHROME) - window.history.replaceState(stateObj, '', document.URL); -//#else -// window.history.replaceState(stateObj, ''); -//#endif + if (typeof PDFJSDev === 'undefined' || + PDFJSDev.test('GENERIC || CHROME')) { + window.history.replaceState(stateObj, '', document.URL); + } else { + window.history.replaceState(stateObj, ''); + } } else { -//#if (GENERIC || CHROME) - window.history.pushState(stateObj, '', document.URL); -//#else -// window.history.pushState(stateObj, ''); -//#endif -//#if CHROME -// if (top === window) { -// chrome.runtime.sendMessage('showPageAction'); -// } -//#endif + if (typeof PDFJSDev === 'undefined' || + PDFJSDev.test('GENERIC || CHROME')) { + window.history.pushState(stateObj, '', document.URL); + } else { + window.history.pushState(stateObj, ''); + } + if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME') && + top === window) { + chrome.runtime.sendMessage('showPageAction'); + } } }, diff --git a/web/pdf_page_view.js b/web/pdf_page_view.js index 4d1be7233..8e8d2b274 100644 --- a/web/pdf_page_view.js +++ b/web/pdf_page_view.js @@ -362,9 +362,11 @@ var PDFPageView = (function PDFPageViewClosure() { } this.canvas = canvas; -//#if MOZCENTRAL || FIREFOX || GENERIC - canvas.mozOpaque = true; -//#endif + if (typeof PDFJSDev === 'undefined' || + PDFJSDev.test('MOZCENTRAL || FIREFOX || GENERIC')) { + canvas.mozOpaque = true; + } + var ctx = canvas.getContext('2d', {alpha: false}); var outputScale = getOutputScale(ctx); this.outputScale = outputScale; diff --git a/web/pdf_presentation_mode.js b/web/pdf_presentation_mode.js index 87e26f4fa..036408aa4 100644 --- a/web/pdf_presentation_mode.js +++ b/web/pdf_presentation_mode.js @@ -485,11 +485,13 @@ var PDFPresentationMode = (function PDFPresentationModeClosure() { window.addEventListener('fullscreenchange', this.fullscreenChangeBind); window.addEventListener('mozfullscreenchange', this.fullscreenChangeBind); -//#if !(FIREFOX || MOZCENTRAL) - window.addEventListener('webkitfullscreenchange', - this.fullscreenChangeBind); - window.addEventListener('MSFullscreenChange', this.fullscreenChangeBind); -//#endif + if (typeof PDFJSDev === 'undefined' || + !PDFJSDev.test('FIREFOX || MOZCENTRAL')) { + window.addEventListener('webkitfullscreenchange', + this.fullscreenChangeBind); + window.addEventListener('MSFullscreenChange', + this.fullscreenChangeBind); + } }, /** @@ -500,12 +502,13 @@ var PDFPresentationMode = (function PDFPresentationModeClosure() { window.removeEventListener('fullscreenchange', this.fullscreenChangeBind); window.removeEventListener('mozfullscreenchange', this.fullscreenChangeBind); -//#if !(FIREFOX || MOZCENTRAL) - window.removeEventListener('webkitfullscreenchange', - this.fullscreenChangeBind); - window.removeEventListener('MSFullscreenChange', - this.fullscreenChangeBind); -//#endif + if (typeof PDFJSDev === 'undefined' || + !PDFJSDev.test('FIREFOX || MOZCENTRAL')) { + window.removeEventListener('webkitfullscreenchange', + this.fullscreenChangeBind); + window.removeEventListener('MSFullscreenChange', + this.fullscreenChangeBind); + } delete this.fullscreenChangeBind; } diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js index c91b9830b..52db26928 100644 --- a/web/pdf_thumbnail_view.js +++ b/web/pdf_thumbnail_view.js @@ -63,9 +63,11 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() { // Since this is a temporary canvas, we need to fill the canvas with a white // background ourselves. `_getPageDrawContext` uses CSS rules for this. -//#if MOZCENTRAL || FIREFOX || GENERIC - tempCanvas.mozOpaque = true; -//#endif + if (typeof PDFJSDev === 'undefined' || + PDFJSDev.test('MOZCENTRAL || FIREFOX || GENERIC')) { + tempCanvas.mozOpaque = true; + } + var ctx = tempCanvas.getContext('2d', {alpha: false}); ctx.save(); ctx.fillStyle = 'rgb(255, 255, 255)'; @@ -215,9 +217,10 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() { // until rendering/image conversion is complete, to avoid display issues. this.canvas = canvas; -//#if MOZCENTRAL || FIREFOX || GENERIC - canvas.mozOpaque = true; -//#endif + if (typeof PDFJSDev === 'undefined' || + PDFJSDev.test('MOZCENTRAL || FIREFOX || GENERIC')) { + canvas.mozOpaque = true; + } var ctx = canvas.getContext('2d', {alpha: false}); var outputScale = getOutputScale(ctx); diff --git a/web/pdf_viewer.js b/web/pdf_viewer.js index c6abb724f..d1273d2d2 100644 --- a/web/pdf_viewer.js +++ b/web/pdf_viewer.js @@ -567,8 +567,8 @@ var PDFViewer = (function pdfViewer() { if (!this.pdfDocument) { return; } -//#if GENERIC - if (arguments.length > 1 || typeof params === 'number') { + if ((typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) && + (arguments.length > 1 || typeof params === 'number')) { console.warn('Call of scrollPageIntoView() with obsolete signature.'); var paramObj = {}; if (typeof params === 'number') { @@ -579,7 +579,6 @@ var PDFViewer = (function pdfViewer() { } params = paramObj; } -//#endif var pageNumber = params.pageNumber || 0; var dest = params.destArray || null; var allowNegativeOffset = params.allowNegativeOffset || false; diff --git a/web/preferences.js b/web/preferences.js index b5fad7518..478a0a87d 100644 --- a/web/preferences.js +++ b/web/preferences.js @@ -26,12 +26,12 @@ } }(this, function (exports) { -//#if PRODUCTION -//var defaultPreferences = Promise.resolve( -//#include $ROOT/web/default_preferences.json -//); -//#else - var defaultPreferences = new Promise(function (resolve) { +var defaultPreferences; +if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('PRODUCTION')) { + defaultPreferences = Promise.resolve( + PDFJSDev.json('$ROOT/web/default_preferences.json')); +} else { + defaultPreferences = new Promise(function (resolve) { if (DEFAULT_PREFERENCES) { resolve(DEFAULT_PREFERENCES); return; @@ -41,7 +41,7 @@ document.removeEventListener('defaultpreferencesloaded', loaded); }); }); -//#endif +} function cloneObj(obj) { var result = {}; @@ -197,21 +197,22 @@ var Preferences = { } }; -//#if !(FIREFOX || MOZCENTRAL || CHROME) -Preferences._writeToStorage = function (prefObj) { - return new Promise(function (resolve) { - localStorage.setItem('pdfjs.preferences', JSON.stringify(prefObj)); - resolve(); - }); -}; +if (typeof PDFJSDev === 'undefined' || + !PDFJSDev.test('FIREFOX || MOZCENTRAL || CHROME')) { + Preferences._writeToStorage = function (prefObj) { + return new Promise(function (resolve) { + localStorage.setItem('pdfjs.preferences', JSON.stringify(prefObj)); + resolve(); + }); + }; -Preferences._readFromStorage = function (prefObj) { - return new Promise(function (resolve) { - var readPrefs = JSON.parse(localStorage.getItem('pdfjs.preferences')); - resolve(readPrefs); - }); -}; -//#endif + Preferences._readFromStorage = function (prefObj) { + return new Promise(function (resolve) { + var readPrefs = JSON.parse(localStorage.getItem('pdfjs.preferences')); + resolve(readPrefs); + }); + }; +} exports.Preferences = Preferences; })); diff --git a/web/text_layer_builder.js b/web/text_layer_builder.js index 34791d05a..110f75b12 100644 --- a/web/text_layer_builder.js +++ b/web/text_layer_builder.js @@ -333,58 +333,61 @@ var TextLayerBuilder = (function TextLayerBuilderClosure() { div.addEventListener('mousedown', function (e) { if (self.enhanceTextSelection && self.textLayerRenderTask) { self.textLayerRenderTask.expandTextDivs(true); -//#if !(MOZCENTRAL || FIREFOX) - if (expandDivsTimer) { + if ((typeof PDFJSDev === 'undefined' || + !PDFJSDev.test('FIREFOX || MOZCENTRAL')) && + expandDivsTimer) { clearTimeout(expandDivsTimer); expandDivsTimer = null; } -//#endif return; } var end = div.querySelector('.endOfContent'); if (!end) { return; } -//#if !(MOZCENTRAL || FIREFOX) + if (typeof PDFJSDev === 'undefined' || + !PDFJSDev.test('FIREFOX || MOZCENTRAL')) { // On non-Firefox browsers, the selection will feel better if the height // of the endOfContent div will be adjusted to start at mouse click // location -- this will avoid flickering when selections moves up. // However it does not work when selection started on empty space. var adjustTop = e.target !== div; -//#if GENERIC - adjustTop = adjustTop && window.getComputedStyle(end). - getPropertyValue('-moz-user-select') !== 'none'; -//#endif + if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) { + adjustTop = adjustTop && window.getComputedStyle(end). + getPropertyValue('-moz-user-select') !== 'none'; + } if (adjustTop) { var divBounds = div.getBoundingClientRect(); var r = Math.max(0, (e.pageY - divBounds.top) / divBounds.height); end.style.top = (r * 100).toFixed(2) + '%'; } -//#endif + } end.classList.add('active'); }); div.addEventListener('mouseup', function (e) { if (self.enhanceTextSelection && self.textLayerRenderTask) { -//#if !(MOZCENTRAL || FIREFOX) - expandDivsTimer = setTimeout(function() { - if (self.textLayerRenderTask) { - self.textLayerRenderTask.expandTextDivs(false); - } - expandDivsTimer = null; - }, EXPAND_DIVS_TIMEOUT); -//#else -// self.textLayerRenderTask.expandTextDivs(false); -//#endif + if (typeof PDFJSDev === 'undefined' || + !PDFJSDev.test('FIREFOX || MOZCENTRAL')) { + expandDivsTimer = setTimeout(function() { + if (self.textLayerRenderTask) { + self.textLayerRenderTask.expandTextDivs(false); + } + expandDivsTimer = null; + }, EXPAND_DIVS_TIMEOUT); + } else { + self.textLayerRenderTask.expandTextDivs(false); + } return; } var end = div.querySelector('.endOfContent'); if (!end) { return; } -//#if !(MOZCENTRAL || FIREFOX) - end.style.top = ''; -//#endif + if (typeof PDFJSDev === 'undefined' || + !PDFJSDev.test('FIREFOX || MOZCENTRAL')) { + end.style.top = ''; + } end.classList.remove('active'); }); }, diff --git a/web/ui_utils.js b/web/ui_utils.js index 52357d5cf..4cf5c3076 100644 --- a/web/ui_utils.js +++ b/web/ui_utils.js @@ -80,13 +80,15 @@ PDFJS.disableTextLayer = (PDFJS.disableTextLayer === undefined ? PDFJS.ignoreCurrentPositionOnZoom = (PDFJS.ignoreCurrentPositionOnZoom === undefined ? false : PDFJS.ignoreCurrentPositionOnZoom); -//#if !(FIREFOX || MOZCENTRAL) -/** - * Interface locale settings. - * @var {string} - */ -PDFJS.locale = (PDFJS.locale === undefined ? navigator.language : PDFJS.locale); -//#endif +if (typeof PDFJSDev === 'undefined' || + !PDFJSDev.test('FIREFOX || MOZCENTRAL')) { + /** + * Interface locale settings. + * @var {string} + */ + PDFJS.locale = (PDFJS.locale === undefined ? navigator.language : + PDFJS.locale); +} /** * Returns scale factor for the canvas. It makes sense for the HiDPI displays. diff --git a/web/view_history.js b/web/view_history.js index 8f1852025..fc611f11b 100644 --- a/web/view_history.js +++ b/web/view_history.js @@ -73,27 +73,24 @@ var ViewHistory = (function ViewHistoryClosure() { return new Promise(function (resolve) { var databaseStr = JSON.stringify(this.database); -//#if FIREFOX || MOZCENTRAL -// sessionStorage.setItem('pdfjsHistory', databaseStr); -// resolve(); -//#endif - -//#if !(FIREFOX || MOZCENTRAL) - localStorage.setItem('database', databaseStr); + if (typeof PDFJSDev !== 'undefined' && + PDFJSDev.test('FIREFOX || MOZCENTRAL')) { + sessionStorage.setItem('pdfjsHistory', databaseStr); + } else { + localStorage.setItem('database', databaseStr); + } resolve(); -//#endif }.bind(this)); }, _readFromStorage: function ViewHistory_readFromStorage() { return new Promise(function (resolve) { -//#if FIREFOX || MOZCENTRAL -// resolve(sessionStorage.getItem('pdfjsHistory')); -//#endif - -//#if !(FIREFOX || MOZCENTRAL) - resolve(localStorage.getItem('database')); -//#endif + if (typeof PDFJSDev !== 'undefined' && + PDFJSDev.test('FIREFOX || MOZCENTRAL')) { + resolve(sessionStorage.getItem('pdfjsHistory')); + } else { + resolve(localStorage.getItem('database')); + } }); }, diff --git a/web/viewer.js b/web/viewer.js index 5782914c9..ab620a295 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -18,37 +18,37 @@ var DEFAULT_URL = 'compressed.tracemonkey-pldi-09.pdf'; -//#if CHROME -//(function rewriteUrlClosure() { -// // Run this code outside DOMContentLoaded to make sure that the URL -// // is rewritten as soon as possible. -// var queryString = document.location.search.slice(1); -// var m = /(^|&)file=([^&]*)/.exec(queryString); -// DEFAULT_URL = m ? decodeURIComponent(m[2]) : ''; -// -// // Example: chrome-extension://.../http://example.com/file.pdf -// var humanReadableUrl = '/' + DEFAULT_URL + location.hash; -// history.replaceState(history.state, '', humanReadableUrl); -// if (top === window) { -// chrome.runtime.sendMessage('showPageAction'); -// } -//})(); -//#endif +if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME')) { + (function rewriteUrlClosure() { + // Run this code outside DOMContentLoaded to make sure that the URL + // is rewritten as soon as possible. + var queryString = document.location.search.slice(1); + var m = /(^|&)file=([^&]*)/.exec(queryString); + DEFAULT_URL = m ? decodeURIComponent(m[2]) : ''; -//#if PRODUCTION -//var pdfjsWebLibs = { -// pdfjsWebPDFJS: window.pdfjsDistBuildPdf -//}; -// -//(function () { + // Example: chrome-extension://.../http://example.com/file.pdf + var humanReadableUrl = '/' + DEFAULT_URL + location.hash; + history.replaceState(history.state, '', humanReadableUrl); + if (top === window) { + chrome.runtime.sendMessage('showPageAction'); + } + })(); +} + +var pdfjsWebLibs; +if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('PRODUCTION')) { + pdfjsWebLibs = { + pdfjsWebPDFJS: window.pdfjsDistBuildPdf + }; + (function () { //#expand __BUNDLE__ -//}).call(pdfjsWebLibs); -//#endif + }).call(pdfjsWebLibs); +} -//#if FIREFOX || MOZCENTRAL -//// FIXME the l10n.js file in the Firefox extension needs global FirefoxCom. -//window.FirefoxCom = pdfjsWebLibs.pdfjsWebFirefoxCom.FirefoxCom; -//#endif +if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('FIREFOX || MOZCENTRAL')) { + // FIXME the l10n.js file in the Firefox extension needs global FirefoxCom. + window.FirefoxCom = pdfjsWebLibs.pdfjsWebFirefoxCom.FirefoxCom; +} function getViewerConfiguration() { return { @@ -169,21 +169,22 @@ function getViewerConfiguration() { function webViewerLoad() { var config = getViewerConfiguration(); -//#if !PRODUCTION - require.config({paths: {'pdfjs': '../src', 'pdfjs-web': '.'}}); - require(['pdfjs-web/pdfjs'], function () { - // Ensure that src/main_loader.js has loaded all the necessary dependencies - // *before* the viewer loads, to prevent issues in browsers relying on e.g. - // the Promise/URL polyfill in src/shared/util.js (fixes issue 7448). - require(['pdfjs-web/app', 'pdfjs-web/pdf_print_service'], function (web) { - window.PDFViewerApplication = web.PDFViewerApplication; - web.PDFViewerApplication.run(config); + if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) { + require.config({paths: {'pdfjs': '../src', 'pdfjs-web': '.'}}); + require(['pdfjs-web/pdfjs'], function () { + // Ensure that src/main_loader.js has loaded all the necessary + // dependencies *before* the viewer loads, to prevent issues in browsers + // relying on e.g. the Promise/URL polyfill in src/shared/util.js (fixes + // issue 7448). + require(['pdfjs-web/app', 'pdfjs-web/pdf_print_service'], function (web) { + window.PDFViewerApplication = web.PDFViewerApplication; + web.PDFViewerApplication.run(config); + }); }); - }); -//#else -//window.PDFViewerApplication = pdfjsWebLibs.pdfjsWebApp.PDFViewerApplication; -//pdfjsWebLibs.pdfjsWebApp.PDFViewerApplication.run(config); -//#endif + } else { + window.PDFViewerApplication = pdfjsWebLibs.pdfjsWebApp.PDFViewerApplication; + pdfjsWebLibs.pdfjsWebApp.PDFViewerApplication.run(config); + } } document.addEventListener('DOMContentLoaded', webViewerLoad, true);