diff --git a/src/core/chunked_stream.js b/src/core/chunked_stream.js index fcbdd599d..bc61dc580 100644 --- a/src/core/chunked_stream.js +++ b/src/core/chunked_stream.js @@ -15,7 +15,7 @@ * limitations under the License. */ /* globals assert, MissingDataException, isInt, NetworkManager, Promise, - isEmptyObj */ + isEmptyObj, LegacyPromise */ 'use strict'; @@ -258,7 +258,7 @@ var ChunkedStreamManager = (function ChunkedStreamManagerClosure() { this.requestsByChunk = {}; this.callbacksByRequest = {}; - this.loadedStream = new Promise(); + this.loadedStream = new LegacyPromise(); if (args.initialData) { this.setInitialData(args.initialData); } diff --git a/src/core/core.js b/src/core/core.js index 94340f7c8..689078433 100644 --- a/src/core/core.js +++ b/src/core/core.js @@ -15,8 +15,8 @@ * limitations under the License. */ /* globals assertWellFormed, calculateMD5, Catalog, error, info, isArray, - isArrayBuffer, isName, isStream, isString, Lexer, - Linearization, NullStream, PartialEvaluator, shadow, Stream, + isArrayBuffer, isName, isStream, isString, LegacyPromise, + Linearization, NullStream, PartialEvaluator, shadow, Stream, Lexer, StreamsSequenceStream, stringToPDFString, stringToBytes, Util, XRef, MissingDataException, Promise, Annotation, ObjectLoader, OperatorList */ @@ -123,7 +123,7 @@ var Page = (function PageClosure() { // TODO: add async inheritPageProp and remove this. this.resourcesPromise = this.pdfManager.ensure(this, 'resources'); } - var promise = new Promise(); + var promise = new LegacyPromise(); this.resourcesPromise.then(function resourceSuccess() { var objectLoader = new ObjectLoader(this.resources.map, keys, @@ -136,13 +136,13 @@ var Page = (function PageClosure() { }, getOperatorList: function Page_getOperatorList(handler) { var self = this; - var promise = new Promise(); + var promise = new LegacyPromise(); function reject(e) { promise.reject(e); } - var pageListPromise = new Promise(); + var pageListPromise = new LegacyPromise(); var pdfManager = this.pdfManager; var contentStreamPromise = pdfManager.ensure(this, 'getContentStream', @@ -208,7 +208,7 @@ var Page = (function PageClosure() { var self = this; - var textContentPromise = new Promise(); + var textContentPromise = new LegacyPromise(); var pdfManager = this.pdfManager; var contentStreamPromise = pdfManager.ensure(this, 'getContentStream', diff --git a/src/core/evaluator.js b/src/core/evaluator.js index c5e589824..8c26e9f5a 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -19,9 +19,9 @@ info, isArray, isCmd, isDict, isEOF, isName, isNum, isStream, isString, JpegStream, Lexer, Metrics, Name, Parser, Pattern, PDFImage, PDFJS, serifFonts, stdFontMap, symbolsFonts, - TilingPattern, warn, Util, Promise, UnsupportedManager, + TilingPattern, warn, Util, Promise, LegacyPromise, RefSetCache, isRef, TextRenderingMode, CMapFactory, OPS, - UNSUPPORTED_FEATURES */ + UNSUPPORTED_FEATURES, UnsupportedManager */ 'use strict'; @@ -548,7 +548,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { // dictionary var parser = new Parser(new Lexer(stream, OP_MAP), false, xref); - var promise = new Promise(); + var promise = new LegacyPromise(); var args = []; while (true) { diff --git a/src/core/image.js b/src/core/image.js index ca50f8dde..e7baf4fb2 100644 --- a/src/core/image.js +++ b/src/core/image.js @@ -15,7 +15,7 @@ * limitations under the License. */ /* globals ColorSpace, error, isArray, isStream, JpegStream, Name, Promise, - Stream, warn */ + Stream, warn, LegacyPromise */ 'use strict'; @@ -129,9 +129,9 @@ var PDFImage = (function PDFImageClosure() { */ PDFImage.buildImage = function PDFImage_buildImage(callback, handler, xref, res, image, inline) { - var imageDataPromise = new Promise(); - var smaskPromise = new Promise(); - var maskPromise = new Promise(); + var imageDataPromise = new LegacyPromise(); + var smaskPromise = new LegacyPromise(); + var maskPromise = new LegacyPromise(); // The image data and smask data may not be ready yet, wait till both are // resolved. Promise.all([imageDataPromise, smaskPromise, maskPromise]).then( diff --git a/src/core/obj.js b/src/core/obj.js index 10c2e98cc..b8014d258 100644 --- a/src/core/obj.js +++ b/src/core/obj.js @@ -19,7 +19,7 @@ isStream, Lexer, log, Page, Parser, Promise, shadow, stringToPDFString, stringToUTF8String, warn, isString, assert, Promise, MissingDataException, XRefParseException, Stream, - ChunkedStream */ + ChunkedStream, LegacyPromise */ 'use strict'; @@ -97,7 +97,7 @@ var Dict = (function DictClosure() { if (xref) { return xref.fetchIfRefAsync(value); } - promise = new Promise(); + promise = new LegacyPromise(); promise.resolve(value); return promise; } @@ -106,7 +106,7 @@ var Dict = (function DictClosure() { if (xref) { return xref.fetchIfRefAsync(value); } - promise = new Promise(); + promise = new LegacyPromise(); promise.resolve(value); return promise; } @@ -114,7 +114,7 @@ var Dict = (function DictClosure() { if (xref) { return xref.fetchIfRefAsync(value); } - promise = new Promise(); + promise = new LegacyPromise(); promise.resolve(value); return promise; }, @@ -434,7 +434,7 @@ var Catalog = (function CatalogClosure() { }, getPageDict: function Catalog_getPageDict(pageIndex) { - var promise = new Promise(); + var promise = new LegacyPromise(); var nodesToVisit = [this.catDict.getRaw('Pages')]; var currentPageIndex = 0; var xref = this.xref; @@ -1120,14 +1120,14 @@ var XRef = (function XRefClosure() { }, fetchIfRefAsync: function XRef_fetchIfRefAsync(obj) { if (!isRef(obj)) { - var promise = new Promise(); + var promise = new LegacyPromise(); promise.resolve(obj); return promise; } return this.fetchAsync(obj); }, fetchAsync: function XRef_fetchAsync(ref, suppressEncryption) { - var promise = new Promise(); + var promise = new LegacyPromise(); var tryFetch = function (promise) { try { promise.resolve(this.fetch(ref, suppressEncryption)); @@ -1254,7 +1254,7 @@ var ObjectLoader = (function() { load: function ObjectLoader_load() { var keys = this.keys; - this.promise = new Promise(); + this.promise = new LegacyPromise(); // Don't walk the graph if all the data is already loaded. if (!(this.xref.stream instanceof ChunkedStream) || this.xref.stream.getMissingChunks().length === 0) { diff --git a/src/core/pdf_manager.js b/src/core/pdf_manager.js index c254da0cf..257a4c11d 100644 --- a/src/core/pdf_manager.js +++ b/src/core/pdf_manager.js @@ -15,7 +15,7 @@ * limitations under the License. */ /* globals NotImplementedException, MissingDataException, Promise, Stream, - PDFDocument, ChunkedStreamManager */ + PDFDocument, ChunkedStreamManager, LegacyPromise */ 'use strict'; @@ -81,7 +81,7 @@ var LocalPdfManager = (function LocalPdfManagerClosure() { function LocalPdfManager(data, password) { var stream = new Stream(data); this.pdfModel = new PDFDocument(this, stream, password); - this.loadedStream = new Promise(); + this.loadedStream = new LegacyPromise(); this.loadedStream.resolve(stream); } @@ -90,7 +90,7 @@ var LocalPdfManager = (function LocalPdfManagerClosure() { LocalPdfManager.prototype.ensure = function LocalPdfManager_ensure(obj, prop, args) { - var promise = new Promise(); + var promise = new LegacyPromise(); try { var value = obj[prop]; var result; @@ -109,7 +109,7 @@ var LocalPdfManager = (function LocalPdfManagerClosure() { LocalPdfManager.prototype.requestRange = function LocalPdfManager_requestRange(begin, end) { - var promise = new Promise(); + var promise = new LegacyPromise(); promise.resolve(); return promise; }; @@ -158,7 +158,7 @@ var NetworkPdfManager = (function NetworkPdfManagerClosure() { NetworkPdfManager.prototype.ensure = function NetworkPdfManager_ensure(obj, prop, args) { - var promise = new Promise(); + var promise = new LegacyPromise(); this.ensureHelper(promise, obj, prop, args); return promise; }; @@ -189,7 +189,7 @@ var NetworkPdfManager = (function NetworkPdfManagerClosure() { NetworkPdfManager.prototype.requestRange = function NetworkPdfManager_requestRange(begin, end) { - var promise = new Promise(); + var promise = new LegacyPromise(); this.streamManager.requestRange(begin, end, function() { promise.resolve(); }); diff --git a/src/core/worker.js b/src/core/worker.js index a2b405b69..3be1cb026 100644 --- a/src/core/worker.js +++ b/src/core/worker.js @@ -17,7 +17,7 @@ /* globals error, globalScope, InvalidPDFException, log, MissingPDFException, PasswordException, PDFJS, Promise, UnknownErrorException, NetworkManager, LocalPdfManager, - NetworkPdfManager, XRefParseException, + NetworkPdfManager, XRefParseException, LegacyPromise, isInt, PasswordResponses, MessageHandler, Ref */ 'use strict'; @@ -27,7 +27,7 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = { var pdfManager; function loadDocument(recoveryMode) { - var loadDocumentPromise = new Promise(); + var loadDocumentPromise = new LegacyPromise(); var parseSuccess = function parseSuccess() { var numPagesPromise = pdfManager.ensureModel('numPages'); @@ -71,7 +71,7 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = { } function getPdfManager(data) { - var pdfManagerPromise = new Promise(); + var pdfManagerPromise = new LegacyPromise(); var source = data.source; var disableRange = data.disableRange; @@ -239,7 +239,8 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = { if (ex instanceof PasswordException) { // after password exception prepare to receive a new password // to repeat loading - pdfManager.passwordChangedPromise = new Promise(); + pdfManager.passwordChangedPromise = + new LegacyPromise(); pdfManager.passwordChangedPromise.then(pdfManagerReady); } @@ -276,31 +277,31 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = { }); }); - handler.on('GetPageIndex', function wphSetupGetPageIndex(data, promise) { + handler.on('GetPageIndex', function wphSetupGetPageIndex(data, deferred) { var ref = new Ref(data.ref.num, data.ref.gen); pdfManager.pdfModel.catalog.getPageIndex(ref).then(function (pageIndex) { - promise.resolve(pageIndex); - }, promise.reject.bind(promise)); + deferred.resolve(pageIndex); + }, deferred.reject); }); handler.on('GetDestinations', - function wphSetupGetDestinations(data, promise) { + function wphSetupGetDestinations(data, deferred) { pdfManager.ensureCatalog('destinations').then(function(destinations) { - promise.resolve(destinations); + deferred.resolve(destinations); }); } ); - handler.on('GetData', function wphSetupGetData(data, promise) { + handler.on('GetData', function wphSetupGetData(data, deferred) { pdfManager.requestLoadedStream(); pdfManager.onLoadedStream().then(function(stream) { - promise.resolve(stream.bytes); + deferred.resolve(stream.bytes); }); }); - handler.on('DataLoaded', function wphSetupDataLoaded(data, promise) { + handler.on('DataLoaded', function wphSetupDataLoaded(data, deferred) { pdfManager.onLoadedStream().then(function(stream) { - promise.resolve({ length: stream.bytes.byteLength }); + deferred.resolve({ length: stream.bytes.byteLength }); }); }); @@ -365,29 +366,29 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = { }); }, this); - handler.on('GetTextContent', function wphExtractText(data, promise) { + handler.on('GetTextContent', function wphExtractText(data, deferred) { pdfManager.getPage(data.pageIndex).then(function(page) { var pageNum = data.pageIndex + 1; var start = Date.now(); page.extractTextContent().then(function(textContent) { - promise.resolve(textContent); + deferred.resolve(textContent); log('text indexing: page=%d - time=%dms', pageNum, Date.now() - start); }, function (e) { // Skip errored pages - promise.reject(e); + deferred.reject(e); }); }); }); - handler.on('Cleanup', function wphCleanup(data, promise) { + handler.on('Cleanup', function wphCleanup(data, deferred) { pdfManager.cleanup(); - promise.resolve(true); + deferred.resolve(true); }); - handler.on('Terminate', function wphTerminate(data, promise) { + handler.on('Terminate', function wphTerminate(data, deferred) { pdfManager.terminate(); - promise.resolve(); + deferred.resolve(); }); } }; diff --git a/src/display/api.js b/src/display/api.js index 96b296a3a..5c3e16198 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -17,7 +17,7 @@ /* globals CanvasGraphics, combineUrl, createScratchCanvas, error, FontLoader, globalScope, info, isArrayBuffer, loadJpegStream, MessageHandler, PDFJS, Promise, StatTimer, warn, - PasswordResponses, Util, loadScript, + PasswordResponses, Util, loadScript, LegacyPromise, FontFace */ 'use strict'; @@ -161,8 +161,8 @@ PDFJS.getDocument = function getDocument(source, params[key] = source[key]; } - workerInitializedPromise = new PDFJS.Promise(); - workerReadyPromise = new PDFJS.Promise(); + workerInitializedPromise = new PDFJS.LegacyPromise(); + workerReadyPromise = new PDFJS.LegacyPromise(); transport = new WorkerTransport(workerInitializedPromise, workerReadyPromise, pdfDataRangeTransport, progressCallback); workerInitializedPromise.then(function transportInitialized() { @@ -230,7 +230,7 @@ var PDFDocumentProxy = (function PDFDocumentProxyClosure() { * JavaScript strings in the name tree. */ getJavaScript: function PDFDocumentProxy_getJavaScript() { - var promise = new PDFJS.Promise(); + var promise = new PDFJS.LegacyPromise(); var js = this.pdfInfo.javaScript; promise.resolve(js); return promise; @@ -251,7 +251,7 @@ var PDFDocumentProxy = (function PDFDocumentProxyClosure() { * ]. */ getOutline: function PDFDocumentProxy_getOutline() { - var promise = new PDFJS.Promise(); + var promise = new PDFJS.LegacyPromise(); var outline = this.pdfInfo.outline; promise.resolve(outline); return promise; @@ -263,7 +263,7 @@ var PDFDocumentProxy = (function PDFDocumentProxyClosure() { * {Metadata} object with information from the metadata section of the PDF. */ getMetadata: function PDFDocumentProxy_getMetadata() { - var promise = new PDFJS.Promise(); + var promise = new PDFJS.LegacyPromise(); var info = this.pdfInfo.info; var metadata = this.pdfInfo.metadata; promise.resolve({ @@ -273,7 +273,7 @@ var PDFDocumentProxy = (function PDFDocumentProxyClosure() { return promise; }, isEncrypted: function PDFDocumentProxy_isEncrypted() { - var promise = new PDFJS.Promise(); + var promise = new PDFJS.LegacyPromise(); promise.resolve(this.pdfInfo.encrypted); return promise; }, @@ -282,7 +282,7 @@ var PDFDocumentProxy = (function PDFDocumentProxyClosure() { * the raw data from the PDF. */ getData: function PDFDocumentProxy_getData() { - var promise = new PDFJS.Promise(); + var promise = new PDFJS.LegacyPromise(); this.transport.getData(promise); return promise; }, @@ -363,7 +363,7 @@ var PDFPageProxy = (function PDFPageProxyClosure() { if (this.annotationsPromise) return this.annotationsPromise; - var promise = new PDFJS.Promise(); + var promise = new PDFJS.LegacyPromise(); this.annotationsPromise = promise; this.transport.getAnnotations(this.pageInfo.pageIndex); return promise; @@ -397,7 +397,7 @@ var PDFPageProxy = (function PDFPageProxyClosure() { // requested before. Make the request and create the promise. if (!this.displayReadyPromise) { this.receivingOperatorList = true; - this.displayReadyPromise = new Promise(); + this.displayReadyPromise = new LegacyPromise(); this.operatorList = { fnArray: [], argsArray: [], @@ -444,9 +444,9 @@ var PDFPageProxy = (function PDFPageProxyClosure() { self._tryDestroy(); if (error) { - renderTask.reject(error); + renderTask.promise.reject(error); } else { - renderTask.resolve(); + renderTask.promise.resolve(); } stats.timeEnd('Rendering'); stats.timeEnd('Overall'); @@ -459,7 +459,7 @@ var PDFPageProxy = (function PDFPageProxyClosure() { * content from the page. */ getTextContent: function PDFPageProxy_getTextContent() { - var promise = new PDFJS.Promise(); + var promise = new PDFJS.LegacyPromise(); this.transport.messageHandler.send('GetTextContent', { pageIndex: this.pageNumber - 1 }, @@ -473,7 +473,7 @@ var PDFPageProxy = (function PDFPageProxyClosure() { * Stub for future feature. */ getOperationList: function PDFPageProxy_getOperationList() { - var promise = new PDFJS.Promise(); + var promise = new PDFJS.LegacyPromise(); var operationList = { // not implemented dependencyFontsID: null, operatorList: null @@ -627,7 +627,7 @@ var WorkerTransport = (function WorkerTransportClosure() { loadFakeWorkerFiles: function WorkerTransport_loadFakeWorkerFiles() { if (!PDFJS.fakeWorkerFilesLoadedPromise) { - PDFJS.fakeWorkerFilesLoadedPromise = new Promise(); + PDFJS.fakeWorkerFilesLoadedPromise = new LegacyPromise(); // 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. @@ -840,7 +840,7 @@ var WorkerTransport = (function WorkerTransportClosure() { error(data.error); }, this); - messageHandler.on('JpegDecode', function(data, promise) { + messageHandler.on('JpegDecode', function(data, deferred) { var imageUrl = data[0]; var components = data[1]; if (components != 3 && components != 1) @@ -869,7 +869,7 @@ var WorkerTransport = (function WorkerTransportClosure() { buf[j] = data[i]; } } - promise.resolve({ data: buf, width: width, height: height}); + deferred.resolve({ data: buf, width: width, height: height}); }).bind(this); img.src = imageUrl; }); @@ -894,7 +894,7 @@ var WorkerTransport = (function WorkerTransportClosure() { }, dataLoaded: function WorkerTransport_dataLoaded() { - var promise = new PDFJS.Promise(); + var promise = new PDFJS.LegacyPromise(); this.messageHandler.send('DataLoaded', null, function(args) { promise.resolve(args); }); @@ -905,14 +905,14 @@ var WorkerTransport = (function WorkerTransportClosure() { var pageIndex = pageNumber - 1; if (pageIndex in this.pagePromises) return this.pagePromises[pageIndex]; - var promise = new PDFJS.Promise('Page ' + pageNumber); + var promise = new PDFJS.LegacyPromise(); this.pagePromises[pageIndex] = promise; this.messageHandler.send('GetPageRequest', { pageIndex: pageIndex }); return promise; }, getPageIndex: function WorkerTransport_getPageIndexByRef(ref) { - var promise = new PDFJS.Promise(); + var promise = new PDFJS.LegacyPromise(); this.messageHandler.send('GetPageIndex', { ref: ref }, function (pageIndex) { promise.resolve(pageIndex); @@ -927,7 +927,7 @@ var WorkerTransport = (function WorkerTransportClosure() { }, getDestinations: function WorkerTransport_getDestinations() { - var promise = new PDFJS.Promise(); + var promise = new PDFJS.LegacyPromise(); this.messageHandler.send('GetDestinations', null, function transportDestinations(destinations) { promise.resolve(destinations); @@ -976,7 +976,7 @@ var PDFObjects = (function PDFObjectsClosure() { return this.objs[objId]; var obj = { - promise: new Promise(objId), + promise: new LegacyPromise(), data: null, resolved: false }; @@ -1057,17 +1057,13 @@ var PDFObjects = (function PDFObjectsClosure() { }; return PDFObjects; })(); -/* - * RenderTask is basically a promise but adds a cancel function to terminate it. - */ + var RenderTask = (function RenderTaskClosure() { function RenderTask(internalRenderTask) { this.internalRenderTask = internalRenderTask; - Promise.call(this); + this.promise = new PDFJS.LegacyPromise(); } - RenderTask.prototype = Object.create(Promise.prototype); - /** * Cancel the rendering task. If the task is curently rendering it will not be * cancelled until graphics pauses with a timeout. The promise that this diff --git a/src/display/canvas.js b/src/display/canvas.js index a918b7bb5..f4f04e611 100644 --- a/src/display/canvas.js +++ b/src/display/canvas.js @@ -17,7 +17,7 @@ /* globals ColorSpace, DeviceCmykCS, DeviceGrayCS, DeviceRgbCS, error, FONT_IDENTITY_MATRIX, IDENTITY_MATRIX, ImageData, isArray, isNum, Pattern, TilingPattern, Util, warn, assert, info, - TextRenderingMode, OPS */ + TextRenderingMode, OPS, Promise */ 'use strict'; @@ -508,6 +508,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { var commonObjs = this.commonObjs; var objs = this.objs; var fnId; + var deferred = Promise.resolve(); while (true) { if (stepper && i === stepper.nextBreakPoint) { @@ -549,7 +550,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { // to continue exeution after a short delay. // However, this is only possible if a 'continueCallback' is passed in. if (continueCallback && Date.now() > endTime) { - setTimeout(continueCallback, 0); + deferred.then(continueCallback); return i; } diff --git a/src/shared/annotation.js b/src/shared/annotation.js index eae51c980..234f59b7f 100644 --- a/src/shared/annotation.js +++ b/src/shared/annotation.js @@ -16,7 +16,8 @@ */ /* globals Util, isDict, isName, stringToPDFString, warn, Dict, Stream, stringToBytes, PDFJS, isWorker, assert, NotImplementedException, - Promise, isArray, ObjectLoader, isValidUrl, OperatorList, OPS */ + Promise, isArray, ObjectLoader, isValidUrl, OperatorList, OPS, + LegacyPromise */ 'use strict'; @@ -141,7 +142,7 @@ var Annotation = (function AnnotationClosure() { }, loadResources: function(keys) { - var promise = new Promise(); + var promise = new LegacyPromise(); this.appearance.dict.getAsync('Resources').then(function(resources) { if (!resources) { promise.resolve(); @@ -160,7 +161,7 @@ var Annotation = (function AnnotationClosure() { getOperatorList: function Annotation_getToOperatorList(evaluator) { - var promise = new Promise(); + var promise = new LegacyPromise(); if (!this.appearance) { promise.resolve(new OperatorList()); @@ -277,7 +278,7 @@ var Annotation = (function AnnotationClosure() { annotationsReadyPromise.reject(e); } - var annotationsReadyPromise = new Promise(); + var annotationsReadyPromise = new LegacyPromise(); var annotationPromises = []; for (var i = 0, n = annotations.length; i < n; ++i) { @@ -439,7 +440,7 @@ var TextWidgetAnnotation = (function TextWidgetAnnotationClosure() { return Annotation.prototype.getOperatorList.call(this, evaluator); } - var promise = new Promise(); + var promise = new LegacyPromise(); var opList = new OperatorList(); var data = this.data; @@ -516,7 +517,7 @@ var TextAnnotation = (function TextAnnotationClosure() { Util.inherit(TextAnnotation, Annotation, { getOperatorList: function TextAnnotation_getOperatorList(evaluator) { - var promise = new Promise(); + var promise = new LegacyPromise(); promise.resolve(new OperatorList()); return promise; }, diff --git a/src/shared/util.js b/src/shared/util.js index 00b62a0d2..94a6cac9b 100644 --- a/src/shared/util.js +++ b/src/shared/util.js @@ -14,7 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* globals Cmd, ColorSpace, Dict, MozBlobBuilder, Name, PDFJS, Ref, URL */ +/* globals Cmd, ColorSpace, Dict, MozBlobBuilder, Name, PDFJS, Ref, URL, + Promise */ 'use strict'; @@ -810,6 +811,24 @@ function isPDFFunction(v) { } /** + * Legacy support for PDFJS Promise implementation. + * TODO remove eventually + */ +var LegacyPromise = PDFJS.LegacyPromise = (function LegacyPromiseClosure() { + return function LegacyPromise() { + var resolve, reject; + var promise = new Promise(function (resolve_, reject_) { + resolve = resolve_; + reject = reject_; + }); + promise.resolve = resolve; + promise.reject = reject; + return promise; + }; +})(); + +/** + * Polyfill for Promises: * The following promise implementation tries to generally implment the * Promise/A+ spec. Some notable differences from other promise libaries are: * - There currently isn't a seperate deferred and promise object. @@ -818,7 +837,40 @@ function isPDFFunction(v) { * Based off of the work in: * https://bugzilla.mozilla.org/show_bug.cgi?id=810490 */ -var Promise = PDFJS.Promise = (function PromiseClosure() { +(function PromiseClosure() { + if (globalScope.Promise) { + // Promises existing in the DOM/Worker, checking presence of all/resolve + if (typeof globalScope.Promise.all !== 'function') { + globalScope.Promise.all = function (iterable) { + var count = 0, results = [], resolve, reject; + var promise = new globalScope.Promise(function (resolve_, reject_) { + resolve = resolve_; + reject = reject_; + }); + iterable.forEach(function (p, i) { + count++; + p.then(function (result) { + results[i] = result; + count--; + if (count === 0) { + resolve(results); + } + }, reject); + }); + if (count === 0) { + resolve(results); + } + return promise; + }; + } + if (typeof globalScope.Promise.resolve !== 'function') { + globalScope.Promise.resolve = function (x) { + return new globalScope.Promise(function (resolve) { resolve(x); }); + }; + } + return; + } +//#if !MOZCENTRAL var STATUS_PENDING = 0; var STATUS_RESOLVED = 1; var STATUS_REJECTED = 2; @@ -851,6 +903,8 @@ var Promise = PDFJS.Promise = (function PromiseClosure() { }, runHandlers: function runHandlers() { + var RUN_TIMEOUT = 1; // ms + var timeoutAt = Date.now() + RUN_TIMEOUT; while (this.handlers.length > 0) { var handler = this.handlers.shift(); @@ -876,6 +930,14 @@ var Promise = PDFJS.Promise = (function PromiseClosure() { } handler.nextPromise._updateStatus(nextStatus, nextValue); + if (Date.now() >= timeoutAt) { + break; + } + } + + if (this.handlers.length > 0) { + setTimeout(this.runHandlers.bind(this), 0); + return; } this.running = false; @@ -926,9 +988,10 @@ var Promise = PDFJS.Promise = (function PromiseClosure() { } }; - function Promise() { + function Promise(resolver) { this._status = STATUS_PENDING; this._handlers = []; + resolver.call(this, this._resolve.bind(this), this._reject.bind(this)); } /** * Builds a promise that is resolved when all the passed in promises are @@ -937,11 +1000,15 @@ var Promise = PDFJS.Promise = (function PromiseClosure() { * @return {Promise} New dependant promise. */ Promise.all = function Promise_all(promises) { - var deferred = new Promise(); + var resolveAll, rejectAll; + var deferred = new Promise(function (resolve, reject) { + resolveAll = resolve; + rejectAll = reject; + }); var unresolved = promises.length; var results = []; if (unresolved === 0) { - deferred.resolve(results); + resolveAll(results); return deferred; } function reject(reason) { @@ -949,7 +1016,7 @@ var Promise = PDFJS.Promise = (function PromiseClosure() { return; } results = []; - deferred.reject(reason); + rejectAll(reason); } for (var i = 0, ii = promises.length; i < ii; ++i) { var promise = promises[i]; @@ -961,7 +1028,7 @@ var Promise = PDFJS.Promise = (function PromiseClosure() { results[i] = value; unresolved--; if (unresolved === 0) - deferred.resolve(results); + resolveAll(results); }; })(i); if (Promise.isPromise(promise)) { @@ -980,6 +1047,14 @@ var Promise = PDFJS.Promise = (function PromiseClosure() { Promise.isPromise = function Promise_isPromise(value) { return value && typeof value.then === 'function'; }; + /** + * Creates resolved promise + * @param x resolve value + * @returns {Promise} + */ + Promise.resolve = function Promise_resolve(x) { + return new Promise(function (resolve) { resolve(x); }); + }; Promise.prototype = { _status: null, @@ -1011,24 +1086,19 @@ var Promise = PDFJS.Promise = (function PromiseClosure() { HandlerManager.scheduleHandlers(this); }, - get isResolved() { - return this._status === STATUS_RESOLVED; - }, - - get isRejected() { - return this._status === STATUS_REJECTED; - }, - - resolve: function Promise_resolve(value) { + _resolve: function Promise_resolve(value) { this._updateStatus(STATUS_RESOLVED, value); }, - reject: function Promise_reject(reason) { + _reject: function Promise_reject(reason) { this._updateStatus(STATUS_REJECTED, reason); }, then: function Promise_then(onResolve, onReject) { - var nextPromise = new Promise(); + var nextPromise = new Promise(function (resolve, reject) { + this.resolve = reject; + this.reject = reject; + }); this._handlers.push({ thisPromise: this, onResolve: onResolve, @@ -1040,7 +1110,10 @@ var Promise = PDFJS.Promise = (function PromiseClosure() { } }; - return Promise; + globalScope.Promise = Promise; +//#else +//throw new Error('DOM Promise is not present'); +//#endif })(); var StatTimer = (function StatTimerClosure() { @@ -1172,7 +1245,12 @@ function MessageHandler(name, comObj) { } else if (data.action in ah) { var action = ah[data.action]; if (data.callbackId) { - var promise = new Promise(); + var deferred = {}; + var promise = new Promise(function (resolve, reject) { + deferred.resolve = resolve; + deferred.reject = reject; + }); + deferred.promise = promise; promise.then(function(resolvedData) { comObj.postMessage({ isReply: true, @@ -1180,7 +1258,7 @@ function MessageHandler(name, comObj) { data: resolvedData }); }); - action[0].call(action[1], data.data, promise); + action[0].call(action[1], data.data, deferred); } else { action[0].call(action[1], data.data); } diff --git a/test/driver.js b/test/driver.js index a5849c5da..0e91e1c28 100644 --- a/test/driver.js +++ b/test/driver.js @@ -269,7 +269,10 @@ function nextPage(task, loadError) { clear(ctx); var drawContext, textLayerBuilder; - var initPromise = new Promise(); + var resolveInitPromise; + var initPromise = new Promise(function (resolve) { + resolveInitPromise = resolve; + }); if (task.type == 'text') { // using dummy canvas for pdf context drawing operations if (!dummyCanvas) { @@ -281,12 +284,12 @@ function nextPage(task, loadError) { page.getTextContent().then(function(textContent) { textLayerBuilder.setTextContent(textContent); - initPromise.resolve(); + resolveInitPromise(); }); } else { drawContext = ctx; textLayerBuilder = new NullTextLayerBuilder(); - initPromise.resolve(); + resolveInitPromise(); } var renderContext = { canvasContext: drawContext, @@ -300,7 +303,7 @@ function nextPage(task, loadError) { snapshotCurrentPage(task, error); }); initPromise.then(function () { - page.render(renderContext).then(function() { + page.render(renderContext).promise.then(function() { completeRender(false); }, function(error) { diff --git a/test/unit/api_spec.js b/test/unit/api_spec.js index 1298ddcb3..eee5fcfe7 100644 --- a/test/unit/api_spec.js +++ b/test/unit/api_spec.js @@ -80,10 +80,13 @@ describe('api', function() { }); }); describe('Page', function() { - var promise = new Promise(); + var resolvePromise; + var promise = new Promise(function (resolve) { + resolvePromise = resolve; + }); PDFJS.getDocument(basicApiUrl).then(function(doc) { doc.getPage(1).then(function(data) { - promise.resolve(data); + resolvePromise(data); }); }); var page; diff --git a/web/firefoxcom.js b/web/firefoxcom.js index 6826097f2..1bdceb9d8 100644 --- a/web/firefoxcom.js +++ b/web/firefoxcom.js @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* globals Preferences, PDFJS */ +/* globals Preferences, PDFJS, Promise */ 'use strict'; @@ -109,8 +109,9 @@ Preferences.prototype.writeToStorage = function(prefObj) { }; Preferences.prototype.readFromStorage = function() { - var readFromStoragePromise = new PDFJS.Promise(); - var readPrefs = JSON.parse(FirefoxCom.requestSync('getPreferences')); - readFromStoragePromise.resolve(readPrefs); + var readFromStoragePromise = new Promise(function (resolve) { + var readPrefs = JSON.parse(FirefoxCom.requestSync('getPreferences')); + resolve(readPrefs); + }); return readFromStoragePromise; }; diff --git a/web/page_view.js b/web/page_view.js index be3619c35..d897d21c4 100644 --- a/web/page_view.js +++ b/web/page_view.js @@ -589,7 +589,7 @@ var PageView = function pageView(container, id, scale, }; var renderTask = this.renderTask = this.pdfPage.render(renderContext); - this.renderTask.then( + this.renderTask.promise.then( function pdfPageRenderCallback() { pageViewDrawCallback(null); }, @@ -649,7 +649,7 @@ var PageView = function pageView(container, id, scale, viewport: viewport }; - pdfPage.render(renderContext).then(function() { + pdfPage.render(renderContext).promise.then(function() { // Tell the printEngine that rendering this canvas/page has finished. obj.done(); self.pdfPage.destroy(); diff --git a/web/pdf_find_controller.js b/web/pdf_find_controller.js index 26c953140..99b9849dc 100644 --- a/web/pdf_find_controller.js +++ b/web/pdf_find_controller.js @@ -16,7 +16,7 @@ 'use strict'; -/* globals PDFFindBar, PDFJS, FindStates, FirefoxCom */ +/* globals PDFFindBar, PDFJS, FindStates, FirefoxCom, Promise */ /** * Provides a "search" or "find" functionality for the PDF. @@ -64,8 +64,6 @@ var PDFFindController = { integratedFind: false, - firstPagePromise: new PDFJS.Promise(), - initialize: function(options) { if(typeof PDFFindBar === 'undefined' || PDFFindBar === null) { throw 'PDFFindController cannot be initialized ' + @@ -82,6 +80,9 @@ var PDFFindController = { 'findcasesensitivitychange' ]; + this.firstPagePromise = new Promise(function (resolve) { + this.resolveFirstPage = resolve; + }.bind(this)); this.handleEvent = this.handleEvent.bind(this); for (var i = 0; i < events.length; i++) { @@ -139,8 +140,11 @@ var PDFFindController = { this.startedTextExtraction = true; this.pageContents = []; + var extractTextPromisesResolves = []; for (var i = 0, ii = this.pdfPageSource.pdfDocument.numPages; i < ii; i++) { - this.extractTextPromises.push(new PDFJS.Promise()); + this.extractTextPromises.push(new Promise(function (resolve) { + extractTextPromisesResolves.push(resolve); + })); } var self = this; @@ -158,7 +162,7 @@ var PDFFindController = { // Store the pageContent as a string. self.pageContents.push(str); - self.extractTextPromises[pageIndex].resolve(pageIndex); + extractTextPromisesResolves[pageIndex](pageIndex); if ((pageIndex + 1) < self.pdfPageSource.pages.length) extractPageText(pageIndex + 1); } diff --git a/web/preferences.js b/web/preferences.js index 2e3625e5e..4e81fe245 100644 --- a/web/preferences.js +++ b/web/preferences.js @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* globals DEFAULT_PREFERENCES, PDFJS, isLocalStorageEnabled */ +/* globals DEFAULT_PREFERENCES, PDFJS, isLocalStorageEnabled, Promise */ 'use strict'; @@ -23,7 +23,9 @@ var Preferences = (function PreferencesClosure() { function Preferences() { this.prefs = {}; + this.isInitializedPromiseResolved = false; this.initializedPromise = this.readFromStorage().then(function(prefObj) { + this.isInitializedPromiseResolved = true; if (prefObj) { this.prefs = prefObj; } @@ -36,19 +38,19 @@ var Preferences = (function PreferencesClosure() { }, readFromStorage: function Preferences_readFromStorage() { - var readFromStoragePromise = new PDFJS.Promise(); + var readFromStoragePromise = Promise.resolve(); return readFromStoragePromise; }, reset: function Preferences_reset() { - if (this.initializedPromise.isResolved) { + if (this.isInitializedPromiseResolved) { this.prefs = {}; this.writeToStorage(this.prefs); } }, set: function Preferences_set(name, value) { - if (!this.initializedPromise.isResolved) { + if (!this.isInitializedPromiseResolved) { return; } else if (DEFAULT_PREFERENCES[name] === undefined) { console.error('Preferences_set: \'' + name + '\' is undefined.'); @@ -79,7 +81,7 @@ var Preferences = (function PreferencesClosure() { if (defaultPref === undefined) { console.error('Preferences_get: \'' + name + '\' is undefined.'); return; - } else if (this.initializedPromise.isResolved) { + } else if (this.isInitializedPromiseResolved) { var pref = this.prefs[name]; if (pref !== undefined) { @@ -99,10 +101,11 @@ var Preferences = (function PreferencesClosure() { //}; // //Preferences.prototype.readFromStorage = function() { -// var readFromStoragePromise = new PDFJS.Promise(); -// asyncStorage.getItem('preferences', function(prefString) { -// var readPrefs = JSON.parse(prefString); -// readFromStoragePromise.resolve(readPrefs); +// var readFromStoragePromise = new Promise(function (resolve) { +// asyncStorage.getItem('preferences', function(prefString) { +// var readPrefs = JSON.parse(prefString); +// resolve(readPrefs); +// }); // }); // return readFromStoragePromise; //}; @@ -116,11 +119,12 @@ Preferences.prototype.writeToStorage = function(prefObj) { }; Preferences.prototype.readFromStorage = function() { - var readFromStoragePromise = new PDFJS.Promise(); - if (isLocalStorageEnabled) { - var readPrefs = JSON.parse(localStorage.getItem('preferences')); - readFromStoragePromise.resolve(readPrefs); - } + var readFromStoragePromise = new Promise(function (resolve) { + if (isLocalStorageEnabled) { + var readPrefs = JSON.parse(localStorage.getItem('preferences')); + resolve(readPrefs); + } + }); return readFromStoragePromise; }; //#endif diff --git a/web/thumbnail_view.js b/web/thumbnail_view.js index bfb9cf197..90d4e89f6 100644 --- a/web/thumbnail_view.js +++ b/web/thumbnail_view.js @@ -161,7 +161,7 @@ var ThumbnailView = function thumbnailView(container, id, defaultViewport) { cont(); } }; - this.pdfPage.render(renderContext).then( + this.pdfPage.render(renderContext).promise.then( function pdfPageRenderCallback() { self.renderingState = RenderingStates.FINISHED; callback(); diff --git a/web/view_history.js b/web/view_history.js index 55429b262..da976c22f 100644 --- a/web/view_history.js +++ b/web/view_history.js @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* globals PDFJS, VIEW_HISTORY_MEMORY, isLocalStorageEnabled */ +/* globals PDFJS, VIEW_HISTORY_MEMORY, isLocalStorageEnabled, Promise */ 'use strict'; @@ -31,11 +31,16 @@ var ViewHistory = (function ViewHistoryClosure() { function ViewHistory(fingerprint) { this.fingerprint = fingerprint; - this.initializedPromise = new PDFJS.Promise(); + var initializedPromiseResolve; + this.isInitializedPromiseResolved = false; + this.initializedPromise = new Promise(function (resolve) { + initializedPromiseResolve = resolve; + }); var resolvePromise = (function ViewHistoryResolvePromise(db) { + this.isInitializedPromiseResolved = true; this.initialize(db || '{}'); - this.initializedPromise.resolve(); + initializedPromiseResolve(); }).bind(this); //#if B2G @@ -78,7 +83,7 @@ var ViewHistory = (function ViewHistoryClosure() { }, set: function ViewHistory_set(name, val) { - if (!this.initializedPromise.isResolved) { + if (!this.isInitializedPromiseResolved) { return; } var file = this.file; @@ -101,7 +106,7 @@ var ViewHistory = (function ViewHistoryClosure() { }, get: function ViewHistory_get(name, defaultValue) { - if (!this.initializedPromise.isResolved) { + if (!this.isInitializedPromiseResolved) { return defaultValue; } return this.file[name] || defaultValue; diff --git a/web/viewer.js b/web/viewer.js index f753e3da4..84dd5ea07 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -19,7 +19,7 @@ getFileName, scrollIntoView, getPDFFileNameFromURL, PDFHistory, Preferences, ViewHistory, PageView, ThumbnailView, noContextMenuHandler, SecondaryToolbar, PasswordPrompt, - PresentationMode, HandTool */ + PresentationMode, HandTool, Promise */ 'use strict'; @@ -787,12 +787,17 @@ var PDFView = { load: function pdfViewLoad(pdfDocument, scale) { var self = this; - var onePageRendered = new PDFJS.Promise(); + var isOnePageRenderedResolved = false; + var resolveOnePageRendered = null; + var onePageRendered = new Promise(function (resolve) { + resolveOnePageRendered = resolve; + }); function bindOnAfterDraw(pageView, thumbnailView) { // when page is painted, using the image as thumbnail base pageView.onAfterDraw = function pdfViewLoadOnAfterDraw() { - if (!onePageRendered.isResolved) { - onePageRendered.resolve(); + if (!isOnePageRenderedResolved) { + isOnePageRenderedResolved = true; + resolveOnePageRendered(); } thumbnailView.setImage(pageView.canvas); }; @@ -841,7 +846,11 @@ var PDFView = { var pagesRefMap = this.pagesRefMap = {}; var thumbnails = this.thumbnails = []; - var pagesPromise = this.pagesPromise = new PDFJS.Promise(); + var resolvePagesPromise; + var pagesPromise = new Promise(function (resolve) { + resolvePagesPromise = resolve; + }); + this.pagesPromise = pagesPromise; var firstPagePromise = pdfDocument.getPage(1); @@ -877,13 +886,13 @@ var PDFView = { pagesRefMap[refStr] = pageNum; getPagesLeft--; if (!getPagesLeft) { - pagesPromise.resolve(); + resolvePagesPromise(); } }.bind(null, pageNum)); } } else { // XXX: Printing is semi-broken with auto fetch disabled. - pagesPromise.resolve(); + resolvePagesPromise(); } }); @@ -893,12 +902,12 @@ var PDFView = { PDFView.loadingBar.setWidth(container); - PDFFindController.firstPagePromise.resolve(); + PDFFindController.resolveFirstPage(); }); var prefsPromise = prefs.initializedPromise; var storePromise = store.initializedPromise; - PDFJS.Promise.all([firstPagePromise, prefsPromise, storePromise]). + Promise.all([firstPagePromise, prefsPromise, storePromise]). then(function() { var showPreviousViewOnLoad = prefs.get('showPreviousViewOnLoad'); var defaultZoomValue = prefs.get('defaultZoomValue'); @@ -961,7 +970,7 @@ var PDFView = { // outline depends on destinations and pagesRefMap var promises = [pagesPromise, destinationsPromise, PDFView.animationStartedPromise]; - PDFJS.Promise.all(promises).then(function() { + Promise.all(promises).then(function() { pdfDocument.getOutline().then(function(outline) { self.outline = new DocumentOutlineView(outline); document.getElementById('viewOutline').disabled = !outline; @@ -2212,9 +2221,10 @@ window.addEventListener('afterprint', function afterPrint(evt) { window.oRequestAnimationFrame || window.msRequestAnimationFrame || function startAtOnce(callback) { callback(); }; - PDFView.animationStartedPromise = new PDFJS.Promise(); - requestAnimationFrame(function onAnimationFrame() { - PDFView.animationStartedPromise.resolve(); + PDFView.animationStartedPromise = new Promise(function (resolve) { + requestAnimationFrame(function onAnimationFrame() { + resolve(); + }); }); })();