Merge pull request #3936 from brendandahl/initial-data
Leave initial request open until the viewer is ready to switch to range requests.
This commit is contained in:
		
						commit
						124eb30e8d
					
				@ -507,9 +507,12 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
 | 
				
			|||||||
   * This is for range requests
 | 
					   * This is for range requests
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  function RangedChromeActions(
 | 
					  function RangedChromeActions(
 | 
				
			||||||
              domWindow, contentDispositionFilename, originalRequest) {
 | 
					              domWindow, contentDispositionFilename, originalRequest,
 | 
				
			||||||
 | 
					              dataListener) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ChromeActions.call(this, domWindow, contentDispositionFilename);
 | 
					    ChromeActions.call(this, domWindow, contentDispositionFilename);
 | 
				
			||||||
 | 
					    this.dataListener = dataListener;
 | 
				
			||||||
 | 
					    this.originalRequest = originalRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.pdfUrl = originalRequest.URI.spec;
 | 
					    this.pdfUrl = originalRequest.URI.spec;
 | 
				
			||||||
    this.contentLength = originalRequest.contentLength;
 | 
					    this.contentLength = originalRequest.contentLength;
 | 
				
			||||||
@ -555,11 +558,15 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
 | 
				
			|||||||
  proto.constructor = RangedChromeActions;
 | 
					  proto.constructor = RangedChromeActions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  proto.initPassiveLoading = function RangedChromeActions_initPassiveLoading() {
 | 
					  proto.initPassiveLoading = function RangedChromeActions_initPassiveLoading() {
 | 
				
			||||||
 | 
					    this.originalRequest.cancel(Cr.NS_BINDING_ABORTED);
 | 
				
			||||||
 | 
					    this.originalRequest = null;
 | 
				
			||||||
    this.domWindow.postMessage({
 | 
					    this.domWindow.postMessage({
 | 
				
			||||||
      pdfjsLoadAction: 'supportsRangedLoading',
 | 
					      pdfjsLoadAction: 'supportsRangedLoading',
 | 
				
			||||||
      pdfUrl: this.pdfUrl,
 | 
					      pdfUrl: this.pdfUrl,
 | 
				
			||||||
      length: this.contentLength
 | 
					      length: this.contentLength,
 | 
				
			||||||
 | 
					      data: this.dataListener.getData()
 | 
				
			||||||
    }, '*');
 | 
					    }, '*');
 | 
				
			||||||
 | 
					    this.dataListener = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
@ -760,8 +767,8 @@ PdfStreamConverter.prototype = {
 | 
				
			|||||||
   * 1. asyncConvertData stores the listener
 | 
					   * 1. asyncConvertData stores the listener
 | 
				
			||||||
   * 2. onStartRequest creates a new channel, streams the viewer
 | 
					   * 2. onStartRequest creates a new channel, streams the viewer
 | 
				
			||||||
   * 3. If range requests are supported:
 | 
					   * 3. If range requests are supported:
 | 
				
			||||||
   *      3.1. Suspends and cancels the request so we can issue range
 | 
					   *      3.1. Leave the request open until the viewer is ready to switch to
 | 
				
			||||||
   *          requests instead.
 | 
					   *           range requests.
 | 
				
			||||||
   *
 | 
					   *
 | 
				
			||||||
   *    If range rquests are not supported:
 | 
					   *    If range rquests are not supported:
 | 
				
			||||||
   *      3.1. Read the stream as it's loaded in onDataAvailable to send
 | 
					   *      3.1. Read the stream as it's loaded in onDataAvailable to send
 | 
				
			||||||
@ -847,18 +854,12 @@ PdfStreamConverter.prototype = {
 | 
				
			|||||||
    PdfJsTelemetry.onViewerIsUsed();
 | 
					    PdfJsTelemetry.onViewerIsUsed();
 | 
				
			||||||
    PdfJsTelemetry.onDocumentSize(aRequest.contentLength);
 | 
					    PdfJsTelemetry.onDocumentSize(aRequest.contentLength);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!rangeRequest) {
 | 
					
 | 
				
			||||||
    // Creating storage for PDF data
 | 
					    // Creating storage for PDF data
 | 
				
			||||||
    var contentLength = aRequest.contentLength;
 | 
					    var contentLength = aRequest.contentLength;
 | 
				
			||||||
    this.dataListener = new PdfDataListener(contentLength);
 | 
					    this.dataListener = new PdfDataListener(contentLength);
 | 
				
			||||||
    this.binaryStream = Cc['@mozilla.org/binaryinputstream;1']
 | 
					    this.binaryStream = Cc['@mozilla.org/binaryinputstream;1']
 | 
				
			||||||
                        .createInstance(Ci.nsIBinaryInputStream);
 | 
					                        .createInstance(Ci.nsIBinaryInputStream);
 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      // Suspend the request so we're not consuming any of the stream,
 | 
					 | 
				
			||||||
      // but we can't cancel the request yet. Otherwise, the original
 | 
					 | 
				
			||||||
      // listener will think we do not want to go the new PDF url
 | 
					 | 
				
			||||||
      aRequest.suspend();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Create a new channel that is viewer loaded as a resource.
 | 
					    // Create a new channel that is viewer loaded as a resource.
 | 
				
			||||||
    var ioService = Services.io;
 | 
					    var ioService = Services.io;
 | 
				
			||||||
@ -884,12 +885,8 @@ PdfStreamConverter.prototype = {
 | 
				
			|||||||
        var domWindow = getDOMWindow(channel);
 | 
					        var domWindow = getDOMWindow(channel);
 | 
				
			||||||
        var actions;
 | 
					        var actions;
 | 
				
			||||||
        if (rangeRequest) {
 | 
					        if (rangeRequest) {
 | 
				
			||||||
          // We are going to be issuing range requests, so cancel the
 | 
					          actions = new RangedChromeActions(
 | 
				
			||||||
          // original request
 | 
					              domWindow, contentDispositionFilename, aRequest, dataListener);
 | 
				
			||||||
          aRequest.resume();
 | 
					 | 
				
			||||||
          aRequest.cancel(Cr.NS_BINDING_ABORTED);
 | 
					 | 
				
			||||||
          actions = new RangedChromeActions(domWindow,
 | 
					 | 
				
			||||||
              contentDispositionFilename, aRequest);
 | 
					 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          actions = new StandardChromeActions(
 | 
					          actions = new StandardChromeActions(
 | 
				
			||||||
              domWindow, contentDispositionFilename, dataListener);
 | 
					              domWindow, contentDispositionFilename, dataListener);
 | 
				
			||||||
 | 
				
			|||||||
@ -30,6 +30,7 @@ var ChunkedStream = (function ChunkedStreamClosure() {
 | 
				
			|||||||
    this.numChunksLoaded = 0;
 | 
					    this.numChunksLoaded = 0;
 | 
				
			||||||
    this.numChunks = Math.ceil(length / chunkSize);
 | 
					    this.numChunks = Math.ceil(length / chunkSize);
 | 
				
			||||||
    this.manager = manager;
 | 
					    this.manager = manager;
 | 
				
			||||||
 | 
					    this.initialDataLength = 0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // required methods for a stream. if a particular stream does not
 | 
					  // required methods for a stream. if a particular stream does not
 | 
				
			||||||
@ -77,11 +78,26 @@ var ChunkedStream = (function ChunkedStreamClosure() {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    onReceiveInitialData: function (data) {
 | 
				
			||||||
 | 
					      this.bytes.set(data);
 | 
				
			||||||
 | 
					      this.initialDataLength = data.length;
 | 
				
			||||||
 | 
					      var endChunk = this.end === data.length ?
 | 
				
			||||||
 | 
					                     this.numChunks : Math.floor(data.length / this.chunkSize);
 | 
				
			||||||
 | 
					      for (var i = 0; i < endChunk; i++) {
 | 
				
			||||||
 | 
					        this.loadedChunks[i] = true;
 | 
				
			||||||
 | 
					        ++this.numChunksLoaded;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ensureRange: function ChunkedStream_ensureRange(begin, end) {
 | 
					    ensureRange: function ChunkedStream_ensureRange(begin, end) {
 | 
				
			||||||
      if (begin >= end) {
 | 
					      if (begin >= end) {
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (end <= this.initialDataLength) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      var chunkSize = this.chunkSize;
 | 
					      var chunkSize = this.chunkSize;
 | 
				
			||||||
      var beginChunk = Math.floor(begin / chunkSize);
 | 
					      var beginChunk = Math.floor(begin / chunkSize);
 | 
				
			||||||
      var endChunk = Math.floor((end - 1) / chunkSize) + 1;
 | 
					      var endChunk = Math.floor((end - 1) / chunkSize) + 1;
 | 
				
			||||||
@ -243,10 +259,25 @@ var ChunkedStreamManager = (function ChunkedStreamManagerClosure() {
 | 
				
			|||||||
    this.callbacksByRequest = {};
 | 
					    this.callbacksByRequest = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.loadedStream = new Promise();
 | 
					    this.loadedStream = new Promise();
 | 
				
			||||||
 | 
					    if (args.initialData) {
 | 
				
			||||||
 | 
					      this.setInitialData(args.initialData);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ChunkedStreamManager.prototype = {
 | 
					  ChunkedStreamManager.prototype = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    setInitialData: function ChunkedStreamManager_setInitialData(data) {
 | 
				
			||||||
 | 
					      this.stream.onReceiveInitialData(data);
 | 
				
			||||||
 | 
					      if (this.stream.allChunksLoaded()) {
 | 
				
			||||||
 | 
					        this.loadedStream.resolve(this.stream);
 | 
				
			||||||
 | 
					      } else if (this.msgHandler) {
 | 
				
			||||||
 | 
					        this.msgHandler.send('DocProgress', {
 | 
				
			||||||
 | 
					          loaded: data.length,
 | 
				
			||||||
 | 
					          total: this.length
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    onLoadedStream: function ChunkedStreamManager_getLoadedStream() {
 | 
					    onLoadedStream: function ChunkedStreamManager_getLoadedStream() {
 | 
				
			||||||
      return this.loadedStream;
 | 
					      return this.loadedStream;
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
				
			|||||||
@ -143,7 +143,8 @@ var NetworkPdfManager = (function NetworkPdfManagerClosure() {
 | 
				
			|||||||
      msgHandler: msgHandler,
 | 
					      msgHandler: msgHandler,
 | 
				
			||||||
      httpHeaders: args.httpHeaders,
 | 
					      httpHeaders: args.httpHeaders,
 | 
				
			||||||
      chunkedViewerLoading: args.chunkedViewerLoading,
 | 
					      chunkedViewerLoading: args.chunkedViewerLoading,
 | 
				
			||||||
      disableAutoFetch: args.disableAutoFetch
 | 
					      disableAutoFetch: args.disableAutoFetch,
 | 
				
			||||||
 | 
					      initialData: args.initialData
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    this.streamManager = new ChunkedStreamManager(args.length, CHUNK_SIZE,
 | 
					    this.streamManager = new ChunkedStreamManager(args.length, CHUNK_SIZE,
 | 
				
			||||||
                                                  args.url, params);
 | 
					                                                  args.url, params);
 | 
				
			||||||
 | 
				
			|||||||
@ -106,6 +106,9 @@ PDFJS.postMessageTransfers = PDFJS.postMessageTransfers === undefined ?
 | 
				
			|||||||
 *  - data  - A typed array with PDF data.
 | 
					 *  - data  - A typed array with PDF data.
 | 
				
			||||||
 *  - httpHeaders - Basic authentication headers.
 | 
					 *  - httpHeaders - Basic authentication headers.
 | 
				
			||||||
 *  - password - For decrypting password-protected PDFs.
 | 
					 *  - password - For decrypting password-protected PDFs.
 | 
				
			||||||
 | 
					 *  - initialData - A typed array with the first portion or all of the pdf data.
 | 
				
			||||||
 | 
					 *                  Used by the extension since some data is already loaded
 | 
				
			||||||
 | 
					 *                  before the switch to range requests. 
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @param {object} pdfDataRangeTransport is optional. It is used if you want
 | 
					 * @param {object} pdfDataRangeTransport is optional. It is used if you want
 | 
				
			||||||
 * to manually serve range requests for data in the PDF. See viewer.js for
 | 
					 * to manually serve range requests for data in the PDF. See viewer.js for
 | 
				
			||||||
 | 
				
			|||||||
@ -452,7 +452,8 @@ var PDFView = {
 | 
				
			|||||||
      switch (args.pdfjsLoadAction) {
 | 
					      switch (args.pdfjsLoadAction) {
 | 
				
			||||||
        case 'supportsRangedLoading':
 | 
					        case 'supportsRangedLoading':
 | 
				
			||||||
          PDFView.open(args.pdfUrl, 0, undefined, pdfDataRangeTransport, {
 | 
					          PDFView.open(args.pdfUrl, 0, undefined, pdfDataRangeTransport, {
 | 
				
			||||||
            length: args.length
 | 
					            length: args.length,
 | 
				
			||||||
 | 
					            initialData: args.data
 | 
				
			||||||
          });
 | 
					          });
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        case 'range':
 | 
					        case 'range':
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user