2011-09-28 04:15:06 +09:00
|
|
|
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
2012-02-08 09:39:07 +09:00
|
|
|
var EXPORTED_SYMBOLS = ['PdfStreamConverter'];
|
|
|
|
|
2011-09-07 07:00:24 +09:00
|
|
|
const Cc = Components.classes;
|
|
|
|
const Ci = Components.interfaces;
|
|
|
|
const Cr = Components.results;
|
|
|
|
const Cu = Components.utils;
|
2012-06-05 01:38:22 +09:00
|
|
|
// True only if this is the version of pdf.js that is included with firefox.
|
2012-06-01 03:16:06 +09:00
|
|
|
const MOZ_CENTRAL = PDFJSSCRIPT_MOZ_CENTRAL;
|
2012-01-28 03:53:07 +09:00
|
|
|
const PDFJS_EVENT_ID = 'pdf.js.message';
|
2011-09-28 04:15:06 +09:00
|
|
|
const PDF_CONTENT_TYPE = 'application/pdf';
|
2012-05-24 07:57:14 +09:00
|
|
|
const PREF_PREFIX = 'PDFJSSCRIPT_PREF_PREFIX';
|
2012-02-08 09:44:03 +09:00
|
|
|
const MAX_DATABASE_LENGTH = 4096;
|
2012-05-12 22:16:53 +09:00
|
|
|
const FIREFOX_ID = '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}';
|
|
|
|
const SEAMONKEY_ID = '{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}';
|
2011-09-07 07:00:24 +09:00
|
|
|
|
2011-09-28 04:15:06 +09:00
|
|
|
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
|
|
|
Cu.import('resource://gre/modules/Services.jsm');
|
2012-05-09 05:05:33 +09:00
|
|
|
Cu.import('resource://gre/modules/NetUtil.jsm');
|
2011-09-07 07:00:24 +09:00
|
|
|
|
2012-06-05 01:38:22 +09:00
|
|
|
|
2012-05-12 22:16:53 +09:00
|
|
|
let appInfo = Cc['@mozilla.org/xre/app-info;1']
|
|
|
|
.getService(Ci.nsIXULAppInfo);
|
|
|
|
let privateBrowsing, inPrivateBrowsing;
|
2012-06-05 01:38:22 +09:00
|
|
|
let Svc = {};
|
|
|
|
XPCOMUtils.defineLazyServiceGetter(Svc, 'mime',
|
|
|
|
'@mozilla.org/mime;1',
|
|
|
|
'nsIMIMEService');
|
2012-05-12 22:16:53 +09:00
|
|
|
|
|
|
|
if (appInfo.ID === FIREFOX_ID) {
|
|
|
|
privateBrowsing = Cc['@mozilla.org/privatebrowsing;1']
|
|
|
|
.getService(Ci.nsIPrivateBrowsingService);
|
|
|
|
inPrivateBrowsing = privateBrowsing.privateBrowsingEnabled;
|
|
|
|
} else if (appInfo.ID === SEAMONKEY_ID) {
|
|
|
|
privateBrowsing = null;
|
|
|
|
inPrivateBrowsing = false;
|
|
|
|
}
|
2012-03-21 01:39:33 +09:00
|
|
|
|
2012-05-11 02:05:24 +09:00
|
|
|
function getBoolPref(pref, def) {
|
2012-05-10 09:04:52 +09:00
|
|
|
try {
|
|
|
|
return Services.prefs.getBoolPref(pref);
|
|
|
|
} catch (ex) {
|
2012-05-11 02:05:24 +09:00
|
|
|
return def;
|
2012-05-10 09:04:52 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function setStringPref(pref, value) {
|
2012-05-11 02:05:24 +09:00
|
|
|
let str = Cc['@mozilla.org/supports-string;1']
|
2012-05-10 09:04:52 +09:00
|
|
|
.createInstance(Ci.nsISupportsString);
|
|
|
|
str.data = value;
|
|
|
|
Services.prefs.setComplexValue(pref, Ci.nsISupportsString, str);
|
|
|
|
}
|
|
|
|
|
2012-05-11 02:05:24 +09:00
|
|
|
function getStringPref(pref, def) {
|
2012-05-10 09:04:52 +09:00
|
|
|
try {
|
|
|
|
return Services.prefs.getComplexValue(pref, Ci.nsISupportsString).data;
|
|
|
|
} catch (ex) {
|
2012-05-11 02:05:24 +09:00
|
|
|
return def;
|
2012-05-10 09:04:52 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-07 07:00:24 +09:00
|
|
|
function log(aMsg) {
|
2012-05-24 07:57:14 +09:00
|
|
|
if (!getBoolPref(PREF_PREFIX + '.pdfBugEnabled', false))
|
2012-03-21 01:39:33 +09:00
|
|
|
return;
|
2012-01-28 04:02:27 +09:00
|
|
|
let msg = 'PdfStreamConverter.js: ' + (aMsg.join ? aMsg.join('') : aMsg);
|
2012-02-04 09:49:44 +09:00
|
|
|
Services.console.logStringMessage(msg);
|
2011-09-28 04:15:06 +09:00
|
|
|
dump(msg + '\n');
|
|
|
|
}
|
2012-03-24 06:28:09 +09:00
|
|
|
|
|
|
|
function getDOMWindow(aChannel) {
|
|
|
|
var requestor = aChannel.notificationCallbacks;
|
|
|
|
var win = requestor.getInterface(Components.interfaces.nsIDOMWindow);
|
|
|
|
return win;
|
2012-02-08 10:54:40 +09:00
|
|
|
}
|
2012-01-28 03:53:07 +09:00
|
|
|
|
2012-06-01 03:16:06 +09:00
|
|
|
function isEnabled() {
|
|
|
|
if (MOZ_CENTRAL) {
|
2012-06-05 01:38:22 +09:00
|
|
|
var disabled = getBoolPref(PREF_PREFIX + '.disabled', false);
|
|
|
|
if (disabled)
|
2012-06-01 03:16:06 +09:00
|
|
|
return false;
|
|
|
|
// To also be considered enabled the "Preview in Firefox" option must be
|
|
|
|
// selected in the Application preferences.
|
2012-06-05 01:38:22 +09:00
|
|
|
var handlerInfo = Svc.mime
|
|
|
|
.getFromTypeAndExtension('application/pdf', 'pdf');
|
|
|
|
return handlerInfo.alwaysAskBeforeHandling == false &&
|
|
|
|
handlerInfo.preferredAction == Ci.nsIHandlerInfo.handleInternally;
|
2012-06-01 03:16:06 +09:00
|
|
|
}
|
|
|
|
// Always returns true for the extension since enabling/disabling is handled
|
|
|
|
// by the add-on manager.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-05-12 04:39:11 +09:00
|
|
|
function getLocalizedStrings(path) {
|
2012-05-12 05:18:46 +09:00
|
|
|
var stringBundle = Cc['@mozilla.org/intl/stringbundle;1'].
|
2012-05-12 04:39:11 +09:00
|
|
|
getService(Ci.nsIStringBundleService).
|
2012-05-12 07:35:43 +09:00
|
|
|
createBundle('chrome://pdf.js/locale/' + path);
|
2012-05-12 04:39:11 +09:00
|
|
|
|
|
|
|
var map = {};
|
|
|
|
var enumerator = stringBundle.getSimpleEnumeration();
|
|
|
|
while (enumerator.hasMoreElements()) {
|
|
|
|
var string = enumerator.getNext().QueryInterface(Ci.nsIPropertyElement);
|
|
|
|
var key = string.key, property = 'textContent';
|
|
|
|
var i = key.lastIndexOf('.');
|
|
|
|
if (i >= 0) {
|
|
|
|
property = key.substring(i + 1);
|
|
|
|
key = key.substring(0, i);
|
|
|
|
}
|
|
|
|
if (!(key in map))
|
|
|
|
map[key] = {};
|
|
|
|
map[key][property] = string.value;
|
|
|
|
}
|
|
|
|
return map;
|
|
|
|
}
|
2012-06-05 01:38:22 +09:00
|
|
|
function getLocalizedString(strings, id, property) {
|
|
|
|
property = property || 'textContent';
|
2012-05-16 02:33:01 +09:00
|
|
|
if (id in strings)
|
2012-06-05 01:38:22 +09:00
|
|
|
return strings[id][property];
|
2012-05-16 02:33:01 +09:00
|
|
|
return id;
|
|
|
|
}
|
2012-05-12 04:39:11 +09:00
|
|
|
|
2012-01-28 03:53:07 +09:00
|
|
|
// All the priviledged actions.
|
2012-05-24 08:54:55 +09:00
|
|
|
function ChromeActions(domWindow) {
|
|
|
|
this.domWindow = domWindow;
|
2012-01-28 03:53:07 +09:00
|
|
|
}
|
2012-05-12 22:16:53 +09:00
|
|
|
|
2012-01-28 03:53:07 +09:00
|
|
|
ChromeActions.prototype = {
|
2012-06-02 06:17:09 +09:00
|
|
|
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.
|
2012-07-14 08:14:37 +09:00
|
|
|
var originalUri = NetUtil.newURI(data.originalUrl);
|
|
|
|
var blobUri = data.blobUrl ? NetUtil.newURI(data.blobUrl) : originalUri;
|
2012-05-09 08:11:50 +09:00
|
|
|
var extHelperAppSvc =
|
|
|
|
Cc['@mozilla.org/uriloader/external-helper-app-service;1'].
|
2012-06-05 03:16:02 +09:00
|
|
|
getService(Ci.nsIExternalHelperAppService);
|
2012-05-09 08:11:50 +09:00
|
|
|
var frontWindow = Cc['@mozilla.org/embedcomp/window-watcher;1'].
|
2012-06-05 03:16:02 +09:00
|
|
|
getService(Ci.nsIWindowWatcher).activeWindow;
|
2012-06-02 06:17:09 +09:00
|
|
|
|
|
|
|
NetUtil.asyncFetch(blobUri, function(aInputStream, aResult) {
|
|
|
|
if (!Components.isSuccessCode(aResult)) {
|
|
|
|
if (sendResponse)
|
|
|
|
sendResponse(true);
|
|
|
|
return;
|
2012-05-09 05:05:33 +09:00
|
|
|
}
|
2012-06-02 06:17:09 +09:00
|
|
|
// 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'].
|
2012-06-05 03:16:02 +09:00
|
|
|
createInstance(Ci.nsIInputStreamChannel);
|
2012-06-02 06:17:09 +09:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
};
|
2012-05-09 08:11:50 +09:00
|
|
|
|
2012-06-02 06:17:09 +09:00
|
|
|
channel.asyncOpen(listener, null);
|
|
|
|
});
|
2012-01-28 03:53:07 +09:00
|
|
|
},
|
2012-02-01 10:53:42 +09:00
|
|
|
setDatabase: function(data) {
|
2012-05-12 22:16:53 +09:00
|
|
|
if (inPrivateBrowsing)
|
2012-01-28 03:53:07 +09:00
|
|
|
return;
|
2012-02-07 14:04:53 +09:00
|
|
|
// Protect against something sending tons of data to setDatabase.
|
2012-02-08 09:44:03 +09:00
|
|
|
if (data.length > MAX_DATABASE_LENGTH)
|
2012-02-07 14:04:53 +09:00
|
|
|
return;
|
2012-05-24 07:57:14 +09:00
|
|
|
setStringPref(PREF_PREFIX + '.database', data);
|
2012-01-28 03:53:07 +09:00
|
|
|
},
|
|
|
|
getDatabase: function() {
|
2012-05-12 22:16:53 +09:00
|
|
|
if (inPrivateBrowsing)
|
2012-01-28 03:53:07 +09:00
|
|
|
return '{}';
|
2012-05-24 07:57:14 +09:00
|
|
|
return getStringPref(PREF_PREFIX + '.database', '{}');
|
2012-03-15 07:34:12 +09:00
|
|
|
},
|
2012-05-02 10:37:03 +09:00
|
|
|
getLocale: function() {
|
2012-05-10 09:04:52 +09:00
|
|
|
return getStringPref('general.useragent.locale', 'en-US');
|
2012-05-02 10:37:03 +09:00
|
|
|
},
|
2012-05-12 04:39:11 +09:00
|
|
|
getStrings: function(data) {
|
|
|
|
try {
|
|
|
|
// Lazy initialization of localizedStrings
|
|
|
|
if (!('localizedStrings' in this))
|
|
|
|
this.localizedStrings = getLocalizedStrings('viewer.properties');
|
|
|
|
|
|
|
|
var result = this.localizedStrings[data];
|
2012-05-12 05:18:46 +09:00
|
|
|
return JSON.stringify(result || null);
|
2012-05-12 04:39:11 +09:00
|
|
|
} catch (e) {
|
|
|
|
log('Unable to retrive localized strings: ' + e);
|
|
|
|
return 'null';
|
|
|
|
}
|
|
|
|
},
|
2012-03-15 07:34:12 +09:00
|
|
|
pdfBugEnabled: function() {
|
2012-05-30 01:14:12 +09:00
|
|
|
return getBoolPref(PREF_PREFIX + '.pdfBugEnabled', false);
|
2012-05-22 00:15:24 +09:00
|
|
|
},
|
|
|
|
searchEnabled: function() {
|
2012-05-30 01:14:12 +09:00
|
|
|
return getBoolPref(PREF_PREFIX + '.searchEnabled', false);
|
2012-05-11 07:54:58 +09:00
|
|
|
},
|
2012-06-05 09:33:27 +09:00
|
|
|
fallback: function(url, sendResponse) {
|
2012-05-11 07:54:58 +09:00
|
|
|
var self = this;
|
2012-05-24 08:54:55 +09:00
|
|
|
var domWindow = this.domWindow;
|
|
|
|
var strings = getLocalizedStrings('chrome.properties');
|
2012-05-16 02:33:01 +09:00
|
|
|
var message = getLocalizedString(strings, 'unsupported_feature');
|
2012-05-24 08:54:55 +09:00
|
|
|
|
2012-05-11 07:54:58 +09:00
|
|
|
var win = Services.wm.getMostRecentWindow('navigator:browser');
|
2012-05-24 08:54:55 +09:00
|
|
|
var browser = win.gBrowser.getBrowserForDocument(domWindow.top.document);
|
|
|
|
var notificationBox = win.gBrowser.getNotificationBox(browser);
|
2012-06-05 09:33:27 +09:00
|
|
|
// Flag so we don't call the response callback twice, since if the user
|
|
|
|
// clicks open with different viewer both the button callback and
|
|
|
|
// eventCallback will be called.
|
|
|
|
var sentResponse = false;
|
2012-05-11 07:54:58 +09:00
|
|
|
var buttons = [{
|
2012-05-24 08:16:48 +09:00
|
|
|
label: getLocalizedString(strings, 'open_with_different_viewer'),
|
2012-06-05 01:38:22 +09:00
|
|
|
accessKey: getLocalizedString(strings, 'open_with_different_viewer',
|
|
|
|
'accessKey'),
|
2012-05-11 07:54:58 +09:00
|
|
|
callback: function() {
|
2012-06-05 09:33:27 +09:00
|
|
|
sentResponse = true;
|
|
|
|
sendResponse(true);
|
2012-05-11 07:54:58 +09:00
|
|
|
}
|
|
|
|
}];
|
|
|
|
notificationBox.appendNotification(message, 'pdfjs-fallback', null,
|
|
|
|
notificationBox.PRIORITY_WARNING_LOW,
|
2012-06-05 09:33:27 +09:00
|
|
|
buttons,
|
|
|
|
function eventsCallback(eventType) {
|
|
|
|
// Currently there is only one event "removed" but if there are any other
|
|
|
|
// added in the future we still only care about removed at the moment.
|
|
|
|
if (eventType !== 'removed')
|
|
|
|
return;
|
|
|
|
// Don't send a response again if we already responded when the button was
|
|
|
|
// clicked.
|
|
|
|
if (!sentResponse)
|
|
|
|
sendResponse(false);
|
|
|
|
});
|
2012-01-28 03:53:07 +09:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Event listener to trigger chrome privedged code.
|
|
|
|
function RequestListener(actions) {
|
|
|
|
this.actions = actions;
|
|
|
|
}
|
2012-06-02 06:17:09 +09:00
|
|
|
// Receive an event and synchronously or asynchronously responds.
|
2012-02-01 10:53:42 +09:00
|
|
|
RequestListener.prototype.receive = function(event) {
|
2012-01-28 03:53:07 +09:00
|
|
|
var message = event.target;
|
2012-06-02 06:17:09 +09:00
|
|
|
var doc = message.ownerDocument;
|
2012-01-28 03:53:07 +09:00
|
|
|
var action = message.getUserData('action');
|
|
|
|
var data = message.getUserData('data');
|
2012-06-02 06:17:09 +09:00
|
|
|
var sync = message.getUserData('sync');
|
2012-01-28 03:53:07 +09:00
|
|
|
var actions = this.actions;
|
|
|
|
if (!(action in actions)) {
|
|
|
|
log('Unknown action: ' + action);
|
|
|
|
return;
|
|
|
|
}
|
2012-06-02 06:17:09 +09:00
|
|
|
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);
|
2011-09-07 07:00:24 +09:00
|
|
|
|
2012-06-02 06:17:09 +09:00
|
|
|
var listener = doc.createEvent('HTMLEvents');
|
|
|
|
listener.initEvent('pdf.js.response', true, false);
|
|
|
|
return message.dispatchEvent(listener);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
actions[action].call(this.actions, data, response);
|
|
|
|
}
|
|
|
|
};
|
2012-01-24 09:50:45 +09:00
|
|
|
|
2012-01-28 04:02:27 +09:00
|
|
|
function PdfStreamConverter() {
|
2012-01-24 10:52:53 +09:00
|
|
|
}
|
2011-09-07 07:00:24 +09:00
|
|
|
|
2012-01-28 04:02:27 +09:00
|
|
|
PdfStreamConverter.prototype = {
|
2011-09-07 07:00:24 +09:00
|
|
|
|
2012-01-24 09:50:45 +09:00
|
|
|
// properties required for XPCOM registration:
|
2012-05-24 07:57:14 +09:00
|
|
|
classID: Components.ID('{PDFJSSCRIPT_STREAM_CONVERTER_ID}'),
|
2012-01-24 09:50:45 +09:00
|
|
|
classDescription: 'pdf.js Component',
|
|
|
|
contractID: '@mozilla.org/streamconv;1?from=application/pdf&to=*/*',
|
2012-01-24 10:52:53 +09:00
|
|
|
|
2012-01-24 09:50:45 +09:00
|
|
|
QueryInterface: XPCOMUtils.generateQI([
|
|
|
|
Ci.nsISupports,
|
|
|
|
Ci.nsIStreamConverter,
|
|
|
|
Ci.nsIStreamListener,
|
|
|
|
Ci.nsIRequestObserver
|
|
|
|
]),
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This component works as such:
|
|
|
|
* 1. asyncConvertData stores the listener
|
|
|
|
* 2. onStartRequest creates a new channel, streams the viewer and cancels
|
|
|
|
* the request so pdf.js can do the request
|
|
|
|
* Since the request is cancelled onDataAvailable should not be called. The
|
|
|
|
* onStopRequest does nothing. The convert function just returns the stream,
|
|
|
|
* it's just the synchronous version of asyncConvertData.
|
|
|
|
*/
|
|
|
|
|
|
|
|
// nsIStreamConverter::convert
|
2012-01-24 10:52:53 +09:00
|
|
|
convert: function(aFromStream, aFromType, aToType, aCtxt) {
|
2012-02-07 06:23:18 +09:00
|
|
|
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
2012-01-24 09:50:45 +09:00
|
|
|
},
|
2011-09-07 07:00:24 +09:00
|
|
|
|
2012-01-24 09:50:45 +09:00
|
|
|
// nsIStreamConverter::asyncConvertData
|
2012-01-24 10:52:53 +09:00
|
|
|
asyncConvertData: function(aFromType, aToType, aListener, aCtxt) {
|
2012-06-01 03:16:06 +09:00
|
|
|
if (!isEnabled())
|
|
|
|
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
2012-02-23 12:52:29 +09:00
|
|
|
// Ignoring HTTP POST requests -- pdf.js has to repeat the request.
|
|
|
|
var skipConversion = false;
|
|
|
|
try {
|
|
|
|
var request = aCtxt;
|
|
|
|
request.QueryInterface(Ci.nsIHttpChannel);
|
2012-03-15 08:43:20 +09:00
|
|
|
skipConversion = (request.requestMethod !== 'GET');
|
2012-02-23 12:52:29 +09:00
|
|
|
} catch (e) {
|
|
|
|
// Non-HTTP request... continue normally.
|
|
|
|
}
|
|
|
|
if (skipConversion)
|
|
|
|
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
|
2012-01-24 09:50:45 +09:00
|
|
|
// Store the listener passed to us
|
|
|
|
this.listener = aListener;
|
|
|
|
},
|
2011-10-19 10:20:50 +09:00
|
|
|
|
2012-01-24 09:50:45 +09:00
|
|
|
// nsIStreamListener::onDataAvailable
|
2012-01-24 10:52:53 +09:00
|
|
|
onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) {
|
2012-01-24 09:50:45 +09:00
|
|
|
// Do nothing since all the data loading is handled by the viewer.
|
2012-01-24 10:52:53 +09:00
|
|
|
log('SANITY CHECK: onDataAvailable SHOULD NOT BE CALLED!');
|
2012-01-24 09:50:45 +09:00
|
|
|
},
|
2011-10-19 10:20:50 +09:00
|
|
|
|
2012-01-24 09:50:45 +09:00
|
|
|
// nsIRequestObserver::onStartRequest
|
2012-01-24 10:52:53 +09:00
|
|
|
onStartRequest: function(aRequest, aContext) {
|
2012-01-28 03:53:07 +09:00
|
|
|
|
2012-01-24 09:50:45 +09:00
|
|
|
// Setup the request so we can use it below.
|
|
|
|
aRequest.QueryInterface(Ci.nsIChannel);
|
2012-01-25 14:33:03 +09:00
|
|
|
// Cancel the request so the viewer can handle it.
|
|
|
|
aRequest.cancel(Cr.NS_BINDING_ABORTED);
|
|
|
|
|
2012-01-24 09:50:45 +09:00
|
|
|
// Create a new channel that is viewer loaded as a resource.
|
2012-02-04 09:49:44 +09:00
|
|
|
var ioService = Services.io;
|
2012-01-24 09:50:45 +09:00
|
|
|
var channel = ioService.newChannel(
|
|
|
|
'resource://pdf.js/web/viewer.html', null, null);
|
2012-01-28 03:53:07 +09:00
|
|
|
|
2012-03-24 06:28:09 +09:00
|
|
|
var listener = this.listener;
|
2012-04-17 06:33:11 +09:00
|
|
|
// Proxy all the request observer calls, when it gets to onStopRequest
|
2012-03-24 06:28:09 +09:00
|
|
|
// we can get the dom window.
|
|
|
|
var proxy = {
|
|
|
|
onStartRequest: function() {
|
|
|
|
listener.onStartRequest.apply(listener, arguments);
|
|
|
|
},
|
|
|
|
onDataAvailable: function() {
|
|
|
|
listener.onDataAvailable.apply(listener, arguments);
|
|
|
|
},
|
|
|
|
onStopRequest: function() {
|
|
|
|
var domWindow = getDOMWindow(channel);
|
2012-03-24 06:48:50 +09:00
|
|
|
// Double check the url is still the correct one.
|
|
|
|
if (domWindow.document.documentURIObject.equals(aRequest.URI)) {
|
2012-05-24 08:54:55 +09:00
|
|
|
let requestListener = new RequestListener(
|
|
|
|
new ChromeActions(domWindow));
|
2012-03-24 06:48:50 +09:00
|
|
|
domWindow.addEventListener(PDFJS_EVENT_ID, function(event) {
|
|
|
|
requestListener.receive(event);
|
|
|
|
}, false, true);
|
|
|
|
}
|
2012-03-24 06:28:09 +09:00
|
|
|
listener.onStopRequest.apply(listener, arguments);
|
2012-01-28 03:53:07 +09:00
|
|
|
}
|
2012-03-24 06:28:09 +09:00
|
|
|
};
|
|
|
|
|
|
|
|
// Keep the URL the same so the browser sees it as the same.
|
|
|
|
channel.originalURI = aRequest.URI;
|
|
|
|
channel.asyncOpen(proxy, aContext);
|
2011-09-07 07:00:24 +09:00
|
|
|
},
|
|
|
|
|
2012-01-24 09:50:45 +09:00
|
|
|
// nsIRequestObserver::onStopRequest
|
2012-01-24 10:52:53 +09:00
|
|
|
onStopRequest: function(aRequest, aContext, aStatusCode) {
|
2012-01-24 09:50:45 +09:00
|
|
|
// Do nothing.
|
|
|
|
}
|
2011-09-07 07:00:24 +09:00
|
|
|
};
|
|
|
|
|
2012-01-28 04:02:27 +09:00
|
|
|
var NSGetFactory = XPCOMUtils.generateNSGetFactory([PdfStreamConverter]);
|