}
ChromeActions.prototype = {
- download: function(data) {
+ download: function(data, sendResponse) {
+ var originalUrl = data.originalUrl;
+ // The data may not be downloaded so we need just retry getting the pdf with
+ // the original url.
+ var blobUrl = data.blobUrl || originalUrl;
+
+ var originalUri = NetUtil.newURI(originalUrl);
+ var blobUri = NetUtil.newURI(blobUrl);
+
let mimeService = Cc['@mozilla.org/mime;1'].getService(Ci.nsIMIMEService);
var handlerInfo = mimeService.
getFromTypeAndExtension('application/pdf', 'pdf');
- var uri = NetUtil.newURI(data);
var extHelperAppSvc =
Cc['@mozilla.org/uriloader/external-helper-app-service;1'].
var frontWindow = Cc['@mozilla.org/embedcomp/window-watcher;1'].
getService(Ci.nsIWindowWatcher).activeWindow;
var ioService = Services.io;
- var channel = ioService.newChannel(data, null, null);
- var listener = {
- extListener: null,
- onStartRequest: function(aRequest, aContext) {
- this.extListener = extHelperAppSvc.doContent('application/pdf',
- aRequest, frontWindow, false);
- this.extListener.onStartRequest(aRequest, aContext);
- },
- onStopRequest: function(aRequest, aContext, aStatusCode) {
- if (this.extListener)
- this.extListener.onStopRequest(aRequest, aContext, aStatusCode);
- },
- onDataAvailable: function(aRequest, aContext, aInputStream, aOffset,
- aCount) {
- this.extListener.onDataAvailable(aRequest, aContext, aInputStream,
- aOffset, aCount);
+ var channel = ioService.newChannel(originalUrl, null, null);
+
+
+ NetUtil.asyncFetch(blobUri, function(aInputStream, aResult) {
+ if (!Components.isSuccessCode(aResult)) {
+ if (sendResponse)
+ sendResponse(true);
+ return;
}
- };
+ // Create a nsIInputStreamChannel so we can set the url on the channel
+ // so the filename will be correct.
+ let channel = Cc['@mozilla.org/network/input-stream-channel;1'].
+ createInstance(Ci.nsIInputStreamChannel);
+ channel.setURI(originalUri);
+ channel.contentStream = aInputStream;
+ channel.QueryInterface(Ci.nsIChannel);
+
+ var listener = {
+ extListener: null,
+ onStartRequest: function(aRequest, aContext) {
+ this.extListener = extHelperAppSvc.doContent('application/pdf',
+ aRequest, frontWindow, false);
+ this.extListener.onStartRequest(aRequest, aContext);
+ },
+ onStopRequest: function(aRequest, aContext, aStatusCode) {
+ if (this.extListener)
+ this.extListener.onStopRequest(aRequest, aContext, aStatusCode);
+ // Notify the content code we're done downloading.
+ if (sendResponse)
+ sendResponse(false);
+ },
+ onDataAvailable: function(aRequest, aContext, aInputStream, aOffset,
+ aCount) {
+ this.extListener.onDataAvailable(aRequest, aContext, aInputStream,
+ aOffset, aCount);
+ }
+ };
- channel.asyncOpen(listener, null);
+ channel.asyncOpen(listener, null);
+ });
},
setDatabase: function(data) {
if (inPrivateBrowsing)
function RequestListener(actions) {
this.actions = actions;
}
-// Receive an event and synchronously responds.
+// Receive an event and synchronously or asynchronously responds.
RequestListener.prototype.receive = function(event) {
var message = event.target;
+ var doc = message.ownerDocument;
var action = message.getUserData('action');
var data = message.getUserData('data');
+ var sync = message.getUserData('sync');
var actions = this.actions;
if (!(action in actions)) {
log('Unknown action: ' + action);
return;
}
- var response = actions[action].call(this.actions, data);
- message.setUserData('response', response, null);
+ if (sync) {
+ var response = actions[action].call(this.actions, data);
+ message.setUserData('response', response, null);
+ } else {
+ var response;
+ if (!message.getUserData('callback')) {
+ doc.documentElement.removeChild(message);
+ response = null;
+ } else {
+ response = function sendResponse(response) {
+ message.setUserData('response', response, null);
+
+ var listener = doc.createEvent('HTMLEvents');
+ listener.initEvent('pdf.js.response', true, false);
+ return message.dispatchEvent(listener);
+ }
+ }
+ actions[action].call(this.actions, data, response);
+ }
};
-
function PdfStreamConverter() {
}
// fetch an l10n objects
function getL10nData(key) {
- var response = FirefoxCom.request('getStrings', key);
+ var response = FirefoxCom.requestSync('getStrings', key);
var data = JSON.parse(response);
if (!data)
console.warn('[l10n] #' + key + ' missing for [' + gLanguage + ']');
}
window.addEventListener('DOMContentLoaded', function() {
- gLanguage = FirefoxCom.request('getLocale', null);
+ gLanguage = FirefoxCom.requestSync('getLocale', null);
translateFragment();
promise.resolve(this.pdfInfo.encrypted);
return promise;
},
+ /**
+ * @return {Promise} A promise that is resolved with a TypedArray that has
+ * the raw data from the PDF.
+ */
+ getData: function PDFDocumentProxy_getData() {
+ var promise = new PDFJS.Promise();
+ this.transport.getData(promise);
+ return promise;
+ },
destroy: function PDFDocumentProxy_destroy() {
this.transport.destroy();
}
this.messageHandler.send('GetDocRequest', {data: data, params: params});
},
+ getData: function WorkerTransport_sendData(promise) {
+ this.messageHandler.send('GetData', null, function(data) {
+ promise.resolve(data);
+ });
+ },
+
getPage: function WorkerTransport_getPage(pageNumber, promise) {
var pageIndex = pageNumber - 1;
if (pageIndex in this.pagePromises)
handler.send('GetPage', {pageInfo: page});
});
+ handler.on('GetData', function wphSetupGetData(data, promise) {
+ promise.resolve(pdfModel.stream.bytes);
+ });
+
handler.on('GetAnnotationsRequest', function wphSetupGetAnnotations(data) {
var pdfPage = pdfModel.getPage(data.pageIndex + 1);
handler.send('GetAnnotations', {
var FirefoxCom = (function FirefoxComClosure() {
return {
/**
- * Creates an event that hopefully the extension is listening for and will
+ * Creates an event that the extension is listening for and will
* synchronously respond to.
+ * NOTE: It is reccomended to use request() instead since one day we may not
+ * be able to synchronously reply.
* @param {String} action The action to trigger.
* @param {String} data Optional data to send.
* @return {*} The response.
*/
- request: function(action, data) {
+ requestSync: function(action, data) {
var request = document.createTextNode('');
request.setUserData('action', action, null);
request.setUserData('data', data, null);
+ request.setUserData('sync', true, null);
document.documentElement.appendChild(request);
var sender = document.createEvent('Events');
var response = request.getUserData('response');
document.documentElement.removeChild(request);
return response;
+ },
+ /**
+ * Creates an event that the extension is listening for and will
+ * asynchronously respond by calling the callback.
+ * @param {String} action The action to trigger.
+ * @param {String} data Optional data to send.
+ * @param {Function} callback Optional response callback that will be called
+ * with one data argument.
+ */
+ request: function(action, data, callback) {
+ var request = document.createTextNode('');
+ request.setUserData('action', action, null);
+ request.setUserData('data', data, null);
+ request.setUserData('sync', false, null);
+ if (callback) {
+ request.setUserData('callback', callback, null);
+
+ document.addEventListener('pdf.js.response', function listener(event) {
+ var node = event.target,
+ callback = node.getUserData('callback'),
+ response = node.getUserData('response');
+
+ document.documentElement.removeChild(node);
+
+ document.removeEventListener('pdf.js.response', listener, false);
+ return callback(response);
+ }, false);
+ }
+ document.documentElement.appendChild(request);
+
+ var sender = document.createEvent('HTMLEvents');
+ sender.initEvent('pdf.js.message', true, false);
+ return request.dispatchEvent(sender);
}
};
})();
var database = null;
var index;
if (isFirefoxExtension)
- database = FirefoxCom.request('getDatabase', null) || '{}';
+ database = FirefoxCom.requestSync('getDatabase', null) || '{}';
else if (isLocalStorageEnabled)
database = localStorage.getItem('database') || '{}';
else
file[name] = val;
var database = JSON.stringify(this.database);
if (isFirefoxExtension)
- FirefoxCom.request('setDatabase', database);
+ FirefoxCom.requestSync('setDatabase', database);
else if (isLocalStorageEnabled)
localStorage.setItem('database', database);
},
container: null,
initialized: false,
fellback: false,
+ pdfDocument: null,
// called once when the document is loaded
initialize: function pdfViewInitialize() {
this.container = document.getElementById('viewerContainer');
PDFView.loadingBar = new ProgressBar('#loadingBar', {});
}
+ this.pdfDocument = null;
var self = this;
self.loading = true;
PDFJS.getDocument(parameters).then(
},
download: function pdfViewDownload() {
+ function noData() {
+ FirefoxCom.request('download', { originalUrl: url });
+ }
+
var url = this.url.split('#')[0];
if (PDFJS.isFirefoxExtension) {
- FirefoxCom.request('download', url);
+ // Document isn't ready just try to download with the url.
+ if (!this.pdfDocument) {
+ noData();
+ return;
+ }
+ this.pdfDocument.getData().then(
+ function getDataSuccess(data) {
+ var bb = new MozBlobBuilder();
+ bb.append(data.buffer);
+ var blobUrl = window.URL.createObjectURL(
+ bb.getBlob('application/pdf'));
+
+ FirefoxCom.request('download', { blobUrl: blobUrl, originalUrl: url },
+ function response(err) {
+ if (err) {
+ // This error won't really be helpful because it's likely the
+ // fallback won't work either (or is already open).
+ PDFView.error('PDF failed to download.');
+ }
+ window.URL.revokeObjectURL(blobUrl);
+ }
+ );
+ },
+ noData // Error ocurred try downloading with just the url.
+ );
} else {
url += '#pdfjs.action=download', '_parent';
window.open(url, '_parent');
};
}
+ this.pdfDocument = pdfDocument;
+
var errorWrapper = document.getElementById('errorWrapper');
errorWrapper.setAttribute('hidden', 'true');
PDFJS.disableTextLayer = (hashParams['disableTextLayer'] === 'true');
if ('pdfBug' in hashParams &&
- (!PDFJS.isFirefoxExtension || FirefoxCom.request('pdfBugEnabled'))) {
+ (!PDFJS.isFirefoxExtension || FirefoxCom.requestSync('pdfBugEnabled'))) {
PDFJS.pdfBug = true;
var pdfBug = hashParams['pdfBug'];
var enabled = pdfBug.split(',');
}
if (!PDFJS.isFirefoxExtension ||
- (PDFJS.isFirefoxExtension && FirefoxCom.request('searchEnabled'))) {
+ (PDFJS.isFirefoxExtension && FirefoxCom.requestSync('searchEnabled'))) {
document.querySelector('#viewSearch').classList.remove('hidden');
}