Switch to stream converter for extension.
This commit is contained in:
parent
edc632e469
commit
178b89342a
14
Makefile
14
Makefile
@ -211,6 +211,7 @@ EXTENSION_WEB_FILES = \
|
||||
web/images \
|
||||
web/viewer.css \
|
||||
web/viewer.js \
|
||||
web/viewer.html \
|
||||
web/viewer-production.html \
|
||||
$(NULL)
|
||||
|
||||
@ -249,7 +250,18 @@ extension: | production
|
||||
# Copy a standalone version of pdf.js inside the content directory
|
||||
@cp $(BUILD_TARGET) $(FIREFOX_BUILD_CONTENT)/$(BUILD_DIR)/
|
||||
@cp -r $(EXTENSION_WEB_FILES) $(FIREFOX_BUILD_CONTENT)/web/
|
||||
@mv -f $(FIREFOX_BUILD_CONTENT)/web/viewer-production.html $(FIREFOX_BUILD_CONTENT)/web/viewer.html
|
||||
@rm $(FIREFOX_BUILD_CONTENT)/web/viewer-production.html
|
||||
# Copy over the firefox extension snippet so we can inline pdf.js in it
|
||||
cp web/viewer-snippet-firefox-extension.html $(FIREFOX_BUILD_CONTENT)/web/
|
||||
# Modify the viewer so it does all the extension only stuff.
|
||||
cd $(FIREFOX_BUILD_CONTENT)/web; \
|
||||
sed -i.bak '/PDFJSSCRIPT_INCLUDE_BUNDLE/ r ../build/pdf.js' viewer-snippet-firefox-extension.html; \
|
||||
sed -i.bak '/PDFJSSCRIPT_REMOVE/d' viewer.html; \
|
||||
sed -i.bak '/PDFJSSCRIPT_REMOVE_FIREFOX_EXTENSION/d' viewer.html; \
|
||||
sed -i.bak '/PDFJSSCRIPT_INCLUDE_FIREFOX_EXTENSION/ r viewer-snippet-firefox-extension.html' viewer.html; \
|
||||
rm -f *.bak;
|
||||
# We don't need pdf.js anymore since its inlined
|
||||
rm -Rf $(FIREFOX_BUILD_CONTENT)/$(BUILD_DIR)/;
|
||||
# Update the build version number
|
||||
@sed -i.bak "s/PDFJSSCRIPT_BUILD/$(BUILD_NUMBER)/" $(FIREFOX_BUILD_DIR)/install.rdf
|
||||
@sed -i.bak "s/PDFJSSCRIPT_BUILD/$(BUILD_NUMBER)/" $(FIREFOX_BUILD_DIR)/update.rdf
|
||||
|
3
extensions/firefox/bootstrap.js
vendored
3
extensions/firefox/bootstrap.js
vendored
@ -34,13 +34,10 @@ function shutdown(aData, aReason) {
|
||||
}
|
||||
|
||||
function install(aData, aReason) {
|
||||
let url = 'chrome://pdf.js/content/web/viewer.html?file=%s';
|
||||
Services.prefs.setCharPref('extensions.pdf.js.url', url);
|
||||
Services.prefs.setBoolPref('extensions.pdf.js.active', false);
|
||||
}
|
||||
|
||||
function uninstall(aData, aReason) {
|
||||
Services.prefs.clearUserPref('extensions.pdf.js.url');
|
||||
Services.prefs.clearUserPref('extensions.pdf.js.active');
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
content pdf.js content/
|
||||
resource pdf.js content/
|
||||
|
||||
component {2278dfd0-b75c-11e0-8257-1ba3d93c9f1a} components/pdfContentHandler.js
|
||||
contract @mozilla.org/uriloader/content-handler;1?type=application/pdf {2278dfd0-b75c-11e0-8257-1ba3d93c9f1a}
|
||||
contract @mozilla.org/streamconv;1?from=application/pdf&to=*/* {2278dfd0-b75c-11e0-8257-1ba3d93c9f1a}
|
||||
|
||||
|
@ -21,47 +21,74 @@ function log(aMsg) {
|
||||
}
|
||||
|
||||
const NS_ERROR_WONT_HANDLE_CONTENT = 0x805d0001;
|
||||
|
||||
function pdfContentHandler() {
|
||||
}
|
||||
};
|
||||
|
||||
pdfContentHandler.prototype = {
|
||||
handleContent: function handleContent(aMimetype, aContext, aRequest) {
|
||||
if (aMimetype != PDF_CONTENT_TYPE)
|
||||
throw NS_ERROR_WONT_HANDLE_CONTENT;
|
||||
|
||||
if (!(aRequest instanceof Ci.nsIChannel))
|
||||
throw NS_ERROR_WONT_HANDLE_CONTENT;
|
||||
// properties required for XPCOM registration:
|
||||
classID: Components.ID('{2278dfd0-b75c-11e0-8257-1ba3d93c9f1a}'),
|
||||
classDescription: 'pdf.js Component',
|
||||
contractID: '@mozilla.org/streamconv;1?from=application/pdf&to=*/*',
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsISupports,
|
||||
Ci.nsIStreamConverter,
|
||||
Ci.nsIStreamListener,
|
||||
Ci.nsIRequestObserver
|
||||
]),
|
||||
|
||||
if (!Services.prefs.getBoolPref('extensions.pdf.js.active'))
|
||||
throw NS_ERROR_WONT_HANDLE_CONTENT;
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
let window = null;
|
||||
let callbacks = aRequest.notificationCallbacks ||
|
||||
aRequest.loadGroup.notificationCallbacks;
|
||||
if (!callbacks)
|
||||
return;
|
||||
|
||||
window = callbacks.getInterface(Ci.nsIDOMWindow);
|
||||
|
||||
let url = null;
|
||||
try {
|
||||
url = Services.prefs.getCharPref('extensions.pdf.js.url');
|
||||
} catch (e) {
|
||||
log('Error retrieving the pdf.js base url - ' + e);
|
||||
throw NS_ERROR_WONT_HANDLE_CONTENT;
|
||||
}
|
||||
|
||||
let targetUrl = aRequest.URI.spec;
|
||||
if (targetUrl.indexOf('#pdfjs.action=download') >= 0)
|
||||
throw NS_ERROR_WONT_HANDLE_CONTENT;
|
||||
|
||||
aRequest.cancel(Cr.NS_BINDING_ABORTED);
|
||||
window.location = url.replace('%s', encodeURIComponent(targetUrl));
|
||||
// nsIStreamConverter::convert
|
||||
convert: function (aFromStream, aFromType, aToType, aCtxt) {
|
||||
return aFromStream;
|
||||
},
|
||||
|
||||
classID: Components.ID('{2278dfd0-b75c-11e0-8257-1ba3d93c9f1a}'),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentHandler])
|
||||
// nsIStreamConverter::asyncConvertData
|
||||
asyncConvertData: function (aFromType, aToType, aListener, aCtxt) {
|
||||
// Store the listener passed to us
|
||||
this.listener = aListener;
|
||||
},
|
||||
|
||||
// nsIStreamListener::onDataAvailable
|
||||
onDataAvailable: function (aRequest, aContext, aInputStream, aOffset, aCount) {
|
||||
// Do nothing since all the data loading is handled by the viewer.
|
||||
log("SANITY CHECK: onDataAvailable SHOULD NOT BE CALLED!");
|
||||
},
|
||||
|
||||
// nsIRequestObserver::onStartRequest
|
||||
onStartRequest: function (aRequest, aContext) {
|
||||
// Setup the request so we can use it below.
|
||||
aRequest.QueryInterface(Ci.nsIChannel);
|
||||
|
||||
// Create a new channel that is viewer loaded as a resource.
|
||||
var ioService = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService);
|
||||
var channel = ioService.newChannel(
|
||||
'resource://pdf.js/web/viewer.html', null, null);
|
||||
// Keep the URL the same so the browser sees it as the same.
|
||||
channel.originalURI = aRequest.originalURI;
|
||||
channel.asyncOpen(this.listener, aContext);
|
||||
|
||||
// Cancel the request so the viewer can handle it.
|
||||
aRequest.cancel(Cr.NS_BINDING_ABORTED);
|
||||
},
|
||||
|
||||
// nsIRequestObserver::onStopRequest
|
||||
onStopRequest: function (aRequest, aContext, aStatusCode) {
|
||||
// Do nothing.
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
var NSGetFactory = XPCOMUtils.generateNSGetFactory([pdfContentHandler]);
|
||||
|
||||
|
20
src/core.js
20
src/core.js
@ -624,9 +624,19 @@ var PDFDoc = (function PDFDocClosure() {
|
||||
}
|
||||
|
||||
try {
|
||||
// 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);
|
||||
var worker;
|
||||
if (PDFJS.isFirefoxExtension) {
|
||||
// The firefox extension can't load the worker from the resource://
|
||||
// url so we have to inline the script and then use the blob loader.
|
||||
var bb = new MozBlobBuilder();
|
||||
bb.append(document.querySelector('#PDFJS_SCRIPT_TAG').textContent);
|
||||
var blobUrl = window.URL.createObjectURL(bb.getBlob());
|
||||
worker = new Worker(blobUrl);
|
||||
} else {
|
||||
// Some versions of FF can't create a worker on localhost, see:
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=683280
|
||||
worker = new Worker(workerSrc);
|
||||
}
|
||||
|
||||
var messageHandler = new MessageHandler('main', worker);
|
||||
|
||||
@ -645,7 +655,9 @@ var PDFDoc = (function PDFDocClosure() {
|
||||
// serializing the typed array.
|
||||
messageHandler.send('test', testObj);
|
||||
return;
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
warn('The worker has been disabled.')
|
||||
}
|
||||
}
|
||||
// Either workers are disabled, not supported or have thrown an exception.
|
||||
// Thus, we fallback to a faked worker.
|
||||
|
14
web/viewer-snippet-firefox-extension.html
Normal file
14
web/viewer-snippet-firefox-extension.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!-- This snippet is used in firefox extension, see Makefile -->
|
||||
<base href="resource://pdf.js/web/" />
|
||||
<script type="text/javascript" id="PDFJS_SCRIPT_TAG">
|
||||
<!--
|
||||
// pdf.js is inlined here because resource:// urls won't work
|
||||
// for loading workers.
|
||||
/* PDFJSSCRIPT_INCLUDE_BUNDLE */
|
||||
-->
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
// This specifies the location of the pdf.js file.
|
||||
PDFJS.isFirefoxExtension = true;
|
||||
PDFJS.workerSrc = 'none';
|
||||
</script>
|
@ -2,9 +2,11 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Simple pdf.js page viewer</title>
|
||||
<!-- PDFJSSCRIPT_INCLUDE_FIREFOX_EXTENSION -->
|
||||
|
||||
<link rel="stylesheet" href="viewer.css"/>
|
||||
|
||||
<script type="text/javascript" src="compatibility.js"></script>
|
||||
<script type="text/javascript" src="compatibility.js"></script> <!-- PDFJSSCRIPT_REMOVE_FIREFOX_EXTENSION -->
|
||||
|
||||
<!-- PDFJSSCRIPT_INCLUDE_BUILD -->
|
||||
<script type="text/javascript" src="../src/core.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
|
@ -73,23 +73,11 @@ var Settings = (function SettingsClosure() {
|
||||
}
|
||||
return true;
|
||||
})();
|
||||
var extPrefix = 'extensions.uriloader@pdf.js';
|
||||
var isExtension = location.protocol == 'chrome:' && !isLocalStorageEnabled;
|
||||
var inPrivateBrowsing = false;
|
||||
if (isExtension) {
|
||||
var pbs = Components.classes['@mozilla.org/privatebrowsing;1']
|
||||
.getService(Components.interfaces.nsIPrivateBrowsingService);
|
||||
inPrivateBrowsing = pbs.privateBrowsingEnabled;
|
||||
}
|
||||
|
||||
function Settings(fingerprint) {
|
||||
var database = null;
|
||||
var index;
|
||||
if (inPrivateBrowsing)
|
||||
return false;
|
||||
else if (isExtension)
|
||||
database = Application.prefs.getValue(extPrefix + '.database', '{}');
|
||||
else if (isLocalStorageEnabled)
|
||||
if (isLocalStorageEnabled)
|
||||
database = localStorage.getItem('database') || '{}';
|
||||
else
|
||||
return false;
|
||||
@ -110,31 +98,20 @@ var Settings = (function SettingsClosure() {
|
||||
index = database.files.push({fingerprint: fingerprint}) - 1;
|
||||
this.file = database.files[index];
|
||||
this.database = database;
|
||||
if (isExtension)
|
||||
Application.prefs.setValue(extPrefix + '.database',
|
||||
JSON.stringify(database));
|
||||
else if (isLocalStorageEnabled)
|
||||
if (isLocalStorageEnabled)
|
||||
localStorage.setItem('database', JSON.stringify(database));
|
||||
}
|
||||
|
||||
Settings.prototype = {
|
||||
set: function settingsSet(name, val) {
|
||||
if (inPrivateBrowsing)
|
||||
return false;
|
||||
var file = this.file;
|
||||
file[name] = val;
|
||||
if (isExtension)
|
||||
Application.prefs.setValue(extPrefix + '.database',
|
||||
JSON.stringify(this.database));
|
||||
else if (isLocalStorageEnabled)
|
||||
if (isLocalStorageEnabled)
|
||||
localStorage.setItem('database', JSON.stringify(this.database));
|
||||
},
|
||||
|
||||
get: function settingsGet(name, defaultValue) {
|
||||
if (inPrivateBrowsing)
|
||||
return defaultValue;
|
||||
else
|
||||
return this.file[name] || defaultValue;
|
||||
return this.file[name] || defaultValue;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1011,7 +988,9 @@ window.addEventListener('load', function webViewerLoad(evt) {
|
||||
}
|
||||
|
||||
var scale = ('scale' in params) ? params.scale : 0;
|
||||
PDFView.open(params.file || kDefaultURL, parseFloat(scale));
|
||||
var file = PDFJS.isFirefoxExtension ?
|
||||
window.location.toString() : params.file || kDefaultURL;
|
||||
PDFView.open(file, parseFloat(scale));
|
||||
|
||||
if (!window.File || !window.FileReader || !window.FileList || !window.Blob)
|
||||
document.getElementById('fileInput').setAttribute('hidden', 'true');
|
||||
|
Loading…
x
Reference in New Issue
Block a user