Fix how we're storing settings and change how the save pdf works.
This commit is contained in:
parent
858aab008f
commit
0d839c1c59
152
extensions/firefox/bootstrap.js
vendored
152
extensions/firefox/bootstrap.js
vendored
@ -3,17 +3,155 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const EXT_PREFIX = 'extensions.uriloader@pdf.js';
|
||||||
|
const PDFJS_EVENT_ID = 'pdf.js.message';
|
||||||
let Cc = Components.classes;
|
let Cc = Components.classes;
|
||||||
let Ci = Components.interfaces;
|
let Ci = Components.interfaces;
|
||||||
let Cm = Components.manager;
|
let Cm = Components.manager;
|
||||||
let Cu = Components.utils;
|
let Cu = Components.utils;
|
||||||
|
let application = Cc['@mozilla.org/fuel/application;1']
|
||||||
|
.getService(Ci.fuelIApplication);
|
||||||
|
let privateBrowsing = Cc['@mozilla.org/privatebrowsing;1']
|
||||||
|
.getService(Ci.nsIPrivateBrowsingService);
|
||||||
|
|
||||||
Cu.import('resource://gre/modules/Services.jsm');
|
Cu.import('resource://gre/modules/Services.jsm');
|
||||||
|
|
||||||
function log(str) {
|
function log(str) {
|
||||||
dump(str + '\n');
|
dump(str + '\n');
|
||||||
}
|
}
|
||||||
|
// watchWindows() and unload() are from Ed Lee's examples at
|
||||||
|
// https://github.com/Mardak/restartless/blob/watchWindows/bootstrap.js
|
||||||
|
/**
|
||||||
|
* Apply a callback to each open and new browser windows.
|
||||||
|
*
|
||||||
|
* @param {function} callback 1-parameter function that gets a browser window.
|
||||||
|
*/
|
||||||
|
function watchWindows(callback) {
|
||||||
|
// Wrap the callback in a function that ignores failures
|
||||||
|
function watcher(window) {
|
||||||
|
try {
|
||||||
|
// Now that the window has loaded, only handle browser windows
|
||||||
|
let {documentElement} = window.document;
|
||||||
|
if (documentElement.getAttribute('windowtype') == 'navigator:browser')
|
||||||
|
callback(window);
|
||||||
|
}
|
||||||
|
catch (ex) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for the window to finish loading before running the callback
|
||||||
|
function runOnLoad(window) {
|
||||||
|
// Listen for one load event before checking the window type
|
||||||
|
window.addEventListener('load', function runOnce() {
|
||||||
|
window.removeEventListener('load', runOnce, false);
|
||||||
|
watcher(window);
|
||||||
|
}, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add functionality to existing windows
|
||||||
|
let windows = Services.wm.getEnumerator(null);
|
||||||
|
while (windows.hasMoreElements()) {
|
||||||
|
// Only run the watcher immediately if the window is completely loaded
|
||||||
|
let window = windows.getNext();
|
||||||
|
if (window.document.readyState == 'complete')
|
||||||
|
watcher(window);
|
||||||
|
// Wait for the window to load before continuing
|
||||||
|
else
|
||||||
|
runOnLoad(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Watch for new browser windows opening then wait for it to load
|
||||||
|
function windowWatcher(subject, topic) {
|
||||||
|
if (topic == 'domwindowopened')
|
||||||
|
runOnLoad(subject);
|
||||||
|
}
|
||||||
|
Services.ww.registerNotification(windowWatcher);
|
||||||
|
|
||||||
|
// Make sure to stop watching for windows if we're unloading
|
||||||
|
unload(function() Services.ww.unregisterNotification(windowWatcher));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save callbacks to run when unloading. Optionally scope the callback to a
|
||||||
|
* container, e.g., window. Provide a way to run all the callbacks.
|
||||||
|
*
|
||||||
|
* @param {function} callback 0-parameter function to call on unload.
|
||||||
|
* @param {node} container Remove the callback when this container unloads.
|
||||||
|
* @return {function} A 0-parameter function that undoes adding the callback.
|
||||||
|
*/
|
||||||
|
function unload(callback, container) {
|
||||||
|
// Initialize the array of unloaders on the first usage
|
||||||
|
let unloaders = unload.unloaders;
|
||||||
|
if (unloaders == null)
|
||||||
|
unloaders = unload.unloaders = [];
|
||||||
|
|
||||||
|
// Calling with no arguments runs all the unloader callbacks
|
||||||
|
if (callback == null) {
|
||||||
|
unloaders.slice().forEach(function(unloader) unloader());
|
||||||
|
unloaders.length = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The callback is bound to the lifetime of the container if we have one
|
||||||
|
if (container != null) {
|
||||||
|
// Remove the unloader when the container unloads
|
||||||
|
container.addEventListener('unload', removeUnloader, false);
|
||||||
|
|
||||||
|
// Wrap the callback to additionally remove the unload listener
|
||||||
|
let origCallback = callback;
|
||||||
|
callback = function() {
|
||||||
|
container.removeEventListener('unload', removeUnloader, false);
|
||||||
|
origCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap the callback in a function that ignores failures
|
||||||
|
function unloader() {
|
||||||
|
try {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
catch (ex) {}
|
||||||
|
}
|
||||||
|
unloaders.push(unloader);
|
||||||
|
|
||||||
|
// Provide a way to remove the unloader
|
||||||
|
function removeUnloader() {
|
||||||
|
let index = unloaders.indexOf(unloader);
|
||||||
|
if (index != -1)
|
||||||
|
unloaders.splice(index, 1);
|
||||||
|
}
|
||||||
|
return removeUnloader;
|
||||||
|
}
|
||||||
|
|
||||||
|
function messageCallback(event) {
|
||||||
|
log(event.target.ownerDocument.currentScript);
|
||||||
|
var message = event.target, doc = message.ownerDocument;
|
||||||
|
var inPrivateBrowswing = privateBrowsing.privateBrowsingEnabled;
|
||||||
|
// Verify the message came from a PDF.
|
||||||
|
// TODO
|
||||||
|
var action = message.getUserData('action');
|
||||||
|
var data = message.getUserData('data');
|
||||||
|
switch (action) {
|
||||||
|
case 'download':
|
||||||
|
Services.wm.getMostRecentWindow('navigator:browser').saveURL(data);
|
||||||
|
break;
|
||||||
|
case 'setDatabase':
|
||||||
|
if (inPrivateBrowswing)
|
||||||
|
return;
|
||||||
|
application.prefs.setValue(EXT_PREFIX + '.database', data);
|
||||||
|
break;
|
||||||
|
case 'getDatabase':
|
||||||
|
var response;
|
||||||
|
if (inPrivateBrowswing)
|
||||||
|
response = '{}';
|
||||||
|
else
|
||||||
|
response = application.prefs.getValue(EXT_PREFIX + '.database', '{}');
|
||||||
|
message.setUserData('response', response, null);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// All the boostrap functions:
|
||||||
function startup(aData, aReason) {
|
function startup(aData, aReason) {
|
||||||
let manifestPath = 'chrome.manifest';
|
let manifestPath = 'chrome.manifest';
|
||||||
let manifest = Cc['@mozilla.org/file/local;1']
|
let manifest = Cc['@mozilla.org/file/local;1']
|
||||||
@ -26,11 +164,22 @@ function startup(aData, aReason) {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
log(e);
|
log(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watchWindows(function(window) {
|
||||||
|
window.addEventListener(PDFJS_EVENT_ID, messageCallback, false, true);
|
||||||
|
unload(function() {
|
||||||
|
window.removeEventListener(PDFJS_EVENT_ID, messageCallback, false, true);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function shutdown(aData, aReason) {
|
function shutdown(aData, aReason) {
|
||||||
if (Services.prefs.getBoolPref('extensions.pdf.js.active'))
|
if (Services.prefs.getBoolPref('extensions.pdf.js.active')) {
|
||||||
Services.prefs.setBoolPref('extensions.pdf.js.active', false);
|
Services.prefs.setBoolPref('extensions.pdf.js.active', false);
|
||||||
|
// Clean up with unloaders when we're deactivating
|
||||||
|
if (aReason != APP_SHUTDOWN)
|
||||||
|
unload();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function install(aData, aReason) {
|
function install(aData, aReason) {
|
||||||
@ -39,5 +188,6 @@ function install(aData, aReason) {
|
|||||||
|
|
||||||
function uninstall(aData, aReason) {
|
function uninstall(aData, aReason) {
|
||||||
Services.prefs.clearUserPref('extensions.pdf.js.active');
|
Services.prefs.clearUserPref('extensions.pdf.js.active');
|
||||||
|
application.prefs.setValue(EXT_PREFIX + '.database', '{}');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ function log(aMsg) {
|
|||||||
dump(msg + '\n');
|
dump(msg + '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
const NS_ERROR_WONT_HANDLE_CONTENT = 0x805d0001;
|
const NS_ERROR_NOT_IMPLEMENTED = 0x80004001;
|
||||||
|
|
||||||
function pdfContentHandler() {
|
function pdfContentHandler() {
|
||||||
}
|
}
|
||||||
@ -51,11 +51,13 @@ pdfContentHandler.prototype = {
|
|||||||
|
|
||||||
// nsIStreamConverter::convert
|
// nsIStreamConverter::convert
|
||||||
convert: function(aFromStream, aFromType, aToType, aCtxt) {
|
convert: function(aFromStream, aFromType, aToType, aCtxt) {
|
||||||
return aFromStream;
|
return aFromStream;
|
||||||
},
|
},
|
||||||
|
|
||||||
// nsIStreamConverter::asyncConvertData
|
// nsIStreamConverter::asyncConvertData
|
||||||
asyncConvertData: function(aFromType, aToType, aListener, aCtxt) {
|
asyncConvertData: function(aFromType, aToType, aListener, aCtxt) {
|
||||||
|
if (!Services.prefs.getBoolPref('extensions.pdf.js.active'))
|
||||||
|
throw NS_ERROR_NOT_IMPLEMENTED;
|
||||||
// Store the listener passed to us
|
// Store the listener passed to us
|
||||||
this.listener = aListener;
|
this.listener = aListener;
|
||||||
},
|
},
|
||||||
@ -73,15 +75,6 @@ pdfContentHandler.prototype = {
|
|||||||
// Cancel the request so the viewer can handle it.
|
// Cancel the request so the viewer can handle it.
|
||||||
aRequest.cancel(Cr.NS_BINDING_ABORTED);
|
aRequest.cancel(Cr.NS_BINDING_ABORTED);
|
||||||
|
|
||||||
// Check if we should download.
|
|
||||||
var targetUrl = aRequest.originalURI.spec;
|
|
||||||
var downloadHash = targetUrl.indexOf('?#pdfjs.action=download');
|
|
||||||
if (downloadHash >= 0) {
|
|
||||||
targetUrl = targetUrl.substring(0, downloadHash);
|
|
||||||
Services.wm.getMostRecentWindow("navigator:browser").saveURL(targetUrl);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new channel that is viewer loaded as a resource.
|
// Create a new channel that is viewer loaded as a resource.
|
||||||
var ioService = Cc['@mozilla.org/network/io-service;1']
|
var ioService = Cc['@mozilla.org/network/io-service;1']
|
||||||
.getService(Ci.nsIIOService);
|
.getService(Ci.nsIIOService);
|
||||||
|
@ -61,6 +61,31 @@ var RenderingQueue = (function RenderingQueueClosure() {
|
|||||||
return RenderingQueue;
|
return RenderingQueue;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
var FirefoxCom = (function FirefoxComClosure() {
|
||||||
|
return {
|
||||||
|
/**
|
||||||
|
* Creates an event that hopefully the extension is listening for and will
|
||||||
|
* synchronously respond to.
|
||||||
|
* @param {String} action The action to trigger.
|
||||||
|
* @param {String} data Optional data to send.
|
||||||
|
* @return {*} The response.
|
||||||
|
*/
|
||||||
|
request: function(action, data) {
|
||||||
|
var request = document.createTextNode('');
|
||||||
|
request.setUserData('action', action, null);
|
||||||
|
request.setUserData('data', data, null);
|
||||||
|
document.documentElement.appendChild(request);
|
||||||
|
|
||||||
|
var sender = document.createEvent('Events');
|
||||||
|
sender.initEvent('pdf.js.message', true, false);
|
||||||
|
request.dispatchEvent(sender);
|
||||||
|
var response = request.getUserData('response');
|
||||||
|
document.documentElement.removeChild(request);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
// Settings Manager - This is a utility for saving settings
|
// Settings Manager - This is a utility for saving settings
|
||||||
// First we see if localStorage is available, FF bug #495747
|
// First we see if localStorage is available, FF bug #495747
|
||||||
// If not, we use FUEL in FF
|
// If not, we use FUEL in FF
|
||||||
@ -74,10 +99,14 @@ var Settings = (function SettingsClosure() {
|
|||||||
return true;
|
return true;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
var isFirefoxExtension = PDFJS.isFirefoxExtension;
|
||||||
|
|
||||||
function Settings(fingerprint) {
|
function Settings(fingerprint) {
|
||||||
var database = null;
|
var database = null;
|
||||||
var index;
|
var index;
|
||||||
if (isLocalStorageEnabled)
|
if (isFirefoxExtension)
|
||||||
|
database = FirefoxCom.request('getDatabase', null);
|
||||||
|
else if (isLocalStorageEnabled)
|
||||||
database = localStorage.getItem('database') || '{}';
|
database = localStorage.getItem('database') || '{}';
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
@ -106,8 +135,11 @@ var Settings = (function SettingsClosure() {
|
|||||||
set: function settingsSet(name, val) {
|
set: function settingsSet(name, val) {
|
||||||
var file = this.file;
|
var file = this.file;
|
||||||
file[name] = val;
|
file[name] = val;
|
||||||
if (isLocalStorageEnabled)
|
var database = JSON.stringify(this.database);
|
||||||
localStorage.setItem('database', JSON.stringify(this.database));
|
if (isFirefoxExtension)
|
||||||
|
FirefoxCom.request('setDatabase', database);
|
||||||
|
else if (isLocalStorageEnabled)
|
||||||
|
localStorage.setItem('database', database);
|
||||||
},
|
},
|
||||||
|
|
||||||
get: function settingsGet(name, defaultValue) {
|
get: function settingsGet(name, defaultValue) {
|
||||||
@ -250,13 +282,12 @@ var PDFView = {
|
|||||||
|
|
||||||
download: function pdfViewDownload() {
|
download: function pdfViewDownload() {
|
||||||
var url = this.url.split('#')[0];
|
var url = this.url.split('#')[0];
|
||||||
// For the extension we add an extra '?' to force the page to reload, its
|
if (PDFJS.isFirefoxExtension) {
|
||||||
// stripped off by the extension.
|
FirefoxCom.request('download', url);
|
||||||
if (PDFJS.isFirefoxExtension)
|
} else {
|
||||||
url += '?#pdfjs.action=download';
|
|
||||||
else
|
|
||||||
url += '#pdfjs.action=download', '_parent';
|
url += '#pdfjs.action=download', '_parent';
|
||||||
window.open(url, '_parent');
|
window.open(url, '_parent');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
navigateTo: function pdfViewNavigateTo(dest) {
|
navigateTo: function pdfViewNavigateTo(dest) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user