Browse Source

[Firefox addon] Convert the code to be ES6 friendly, in order to better agree with mozilla-central coding conventions (issue 7957)

*Please note: ignoring whitespace changes is most likely necessary for the diff to be readable.*

This patch addresses all the current, in `mozilla-central`, linting failures in the addon. It should thus be possible to change the `.eslintignore` entry for PDF.js in `mozilla-central` from `browser/extensions/pdfjs/**` to `browser/extensions/pdfjs/build/**` and `browser/extensions/pdfjs/web/**` instead.
Note that we cannot, for backwards compatibility reason of the general PDF.js library, at this time make similar changes for files residing in the `build` and `web` directories in `mozilla-central`.

The main changes in this patch are that we now use [classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes) instead of our previous "class-like" functions, and also use the more compact [object shorthand notation](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Object_initializer#New_notations_in_ECMAScript_2015).
A couple of functions were also converted to [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), to reduced usages of `bind(this)` and `var self = this`.

One caveat with ES6 classes is that it's not (yet) possible to define private constants/helper functions within them, which is why the `NetworkManagerClosure` was kept to not change the visibility of those constant/functions.

Besides testing in Firefox Nightly 53, this patch has also been tested in Firefox ESR 45 and SeaMonkey 2.46.
However, I'd gladly welcome help with testing the patch more, to ensure that nothing has gone wrong during the refactoring.

Fixes the first bullet point of issue 7957.
Jonas Jenwald 8 years ago
parent
commit
3ec99f0e12
  1. 2
      .eslintrc
  2. 24
      extensions/firefox/.eslintrc
  3. 4
      extensions/firefox/chrome/content.js
  4. 100
      extensions/firefox/content/PdfJsNetwork.jsm
  5. 22
      extensions/firefox/content/PdfJsTelemetry-addon.jsm
  6. 22
      extensions/firefox/content/PdfJsTelemetry.jsm
  7. 396
      extensions/firefox/content/PdfStreamConverter.jsm
  8. 44
      extensions/firefox/content/PdfjsChromeUtils.jsm
  9. 24
      extensions/firefox/content/PdfjsContentUtils.jsm
  10. 10
      extensions/firefox/tools/l10n.js

2
.eslintrc

@ -119,4 +119,6 @@
} }
}], }],
}, },
// ECMAScript 6
} }

24
extensions/firefox/.eslintrc

@ -6,4 +6,28 @@
"parserOptions": { "parserOptions": {
"ecmaVersion": 6 "ecmaVersion": 6
}, },
"rules": {
// Variables
"no-shadow": "error",
"no-unused-vars": ["error", {
"vars": "local",
"varsIgnorePattern": "^Cc|Ci|Cu|Cr|EXPORTED_SYMBOLS",
"args": "none",
}],
// Stylistic Issues
"space-before-function-paren": ["error", "never"],
// ECMAScript 6
"arrow-body-style": ["error", "as-needed"],
"arrow-parens": ["error", "always"],
"arrow-spacing": ["error", { "before": true, "after": true, }],
"constructor-super": "error",
"no-confusing-arrow": "error",
"no-const-assign": "error",
"no-dupe-class-members": "error",
"no-useless-constructor": "error",
"object-shorthand": ["error", "always", { "avoidQuotes": true }],
},
} }

4
extensions/firefox/chrome/content.js

@ -32,7 +32,7 @@
var isRemote = Services.appinfo.processType === var isRemote = Services.appinfo.processType ===
Services.appinfo.PROCESS_TYPE_CONTENT; Services.appinfo.PROCESS_TYPE_CONTENT;
// Factory that registers/unregisters a constructor as a component. // Factory that registers/unregisters a constructor as a component.
function Factory() { function Factory() {
} }
@ -93,7 +93,7 @@
if (isRemote) { if (isRemote) {
startup(); startup();
addMessageListener('PDFJS:Child:shutdown', function (e) { addMessageListener('PDFJS:Child:shutdown', function() {
shutdown(); shutdown();
}); });
} }

100
extensions/firefox/content/PdfJsNetwork.jsm

@ -27,24 +27,8 @@ function log(aMsg) {
var NetworkManager = (function NetworkManagerClosure() { var NetworkManager = (function NetworkManagerClosure() {
var OK_RESPONSE = 200; const OK_RESPONSE = 200;
var PARTIAL_CONTENT_RESPONSE = 206; const PARTIAL_CONTENT_RESPONSE = 206;
function NetworkManager(url, args) {
this.url = url;
args = args || {};
this.isHttp = /^https?:/i.test(url);
this.httpHeaders = (this.isHttp && args.httpHeaders) || {};
this.withCredentials = args.withCredentials || false;
this.getXhr = args.getXhr ||
function NetworkManager_getXhr() {
return new XMLHttpRequest();
};
this.currXhrId = 0;
this.pendingRequests = Object.create(null);
this.loadedRequests = Object.create(null);
}
function getArrayBuffer(xhr) { function getArrayBuffer(xhr) {
var data = xhr.response; var data = xhr.response;
@ -59,27 +43,43 @@ var NetworkManager = (function NetworkManagerClosure() {
return array.buffer; return array.buffer;
} }
NetworkManager.prototype = { class NetworkManagerClass {
requestRange: function NetworkManager_requestRange(begin, end, listeners) { constructor(url, args) {
this.url = url;
args = args || {};
this.isHttp = /^https?:/i.test(url);
this.httpHeaders = (this.isHttp && args.httpHeaders) || {};
this.withCredentials = args.withCredentials || false;
this.getXhr = args.getXhr ||
function NetworkManager_getXhr() {
return new XMLHttpRequest();
};
this.currXhrId = 0;
this.pendingRequests = Object.create(null);
this.loadedRequests = Object.create(null);
}
requestRange(begin, end, listeners) {
var args = { var args = {
begin: begin, begin,
end: end end,
}; };
for (var prop in listeners) { for (var prop in listeners) {
args[prop] = listeners[prop]; args[prop] = listeners[prop];
} }
return this.request(args); return this.request(args);
}, }
requestFull: function NetworkManager_requestFull(listeners) { requestFull(listeners) {
return this.request(listeners); return this.request(listeners);
}, }
request: function NetworkManager_request(args) { request(args) {
var xhr = this.getXhr(); var xhr = this.getXhr();
var xhrId = this.currXhrId++; var xhrId = this.currXhrId++;
var pendingRequest = this.pendingRequests[xhrId] = { var pendingRequest = this.pendingRequests[xhrId] = {
xhr: xhr xhr,
}; };
xhr.open('GET', this.url); xhr.open('GET', this.url);
@ -124,9 +124,9 @@ var NetworkManager = (function NetworkManagerClosure() {
xhr.send(null); xhr.send(null);
return xhrId; return xhrId;
}, }
onProgress: function NetworkManager_onProgress(xhrId, evt) { onProgress(xhrId, evt) {
var pendingRequest = this.pendingRequests[xhrId]; var pendingRequest = this.pendingRequests[xhrId];
if (!pendingRequest) { if (!pendingRequest) {
// Maybe abortRequest was called... // Maybe abortRequest was called...
@ -142,9 +142,9 @@ var NetworkManager = (function NetworkManagerClosure() {
if (onProgress) { if (onProgress) {
onProgress(evt); onProgress(evt);
} }
}, }
onStateChange: function NetworkManager_onStateChange(xhrId, evt) { onStateChange(xhrId, evt) {
var pendingRequest = this.pendingRequests[xhrId]; var pendingRequest = this.pendingRequests[xhrId];
if (!pendingRequest) { if (!pendingRequest) {
// Maybe abortRequest was called... // Maybe abortRequest was called...
@ -201,56 +201,56 @@ var NetworkManager = (function NetworkManagerClosure() {
var matches = /bytes (\d+)-(\d+)\/(\d+)/.exec(rangeHeader); var matches = /bytes (\d+)-(\d+)\/(\d+)/.exec(rangeHeader);
var begin = parseInt(matches[1], 10); var begin = parseInt(matches[1], 10);
pendingRequest.onDone({ pendingRequest.onDone({
begin: begin, begin,
chunk: chunk chunk,
}); });
} else if (pendingRequest.onProgressiveData) { } else if (pendingRequest.onProgressiveData) {
pendingRequest.onDone(null); pendingRequest.onDone(null);
} else if (chunk) { } else if (chunk) {
pendingRequest.onDone({ pendingRequest.onDone({
begin: 0, begin: 0,
chunk: chunk chunk,
}); });
} else if (pendingRequest.onError) { } else if (pendingRequest.onError) {
pendingRequest.onError(xhr.status); pendingRequest.onError(xhr.status);
} }
}, }
hasPendingRequests: function NetworkManager_hasPendingRequests() { hasPendingRequests() {
for (var xhrId in this.pendingRequests) { for (var xhrId in this.pendingRequests) {
return true; return true;
} }
return false; return false;
}, }
getRequestXhr: function NetworkManager_getXhr(xhrId) { getRequestXhr(xhrId) {
return this.pendingRequests[xhrId].xhr; return this.pendingRequests[xhrId].xhr;
}, }
isStreamingRequest: function NetworkManager_isStreamingRequest(xhrId) { isStreamingRequest(xhrId) {
return !!(this.pendingRequests[xhrId].onProgressiveData); return !!(this.pendingRequests[xhrId].onProgressiveData);
}, }
isPendingRequest: function NetworkManager_isPendingRequest(xhrId) { isPendingRequest(xhrId) {
return xhrId in this.pendingRequests; return xhrId in this.pendingRequests;
}, }
isLoadedRequest: function NetworkManager_isLoadedRequest(xhrId) { isLoadedRequest(xhrId) {
return xhrId in this.loadedRequests; return xhrId in this.loadedRequests;
}, }
abortAllRequests: function NetworkManager_abortAllRequests() { abortAllRequests() {
for (var xhrId in this.pendingRequests) { for (var xhrId in this.pendingRequests) {
this.abortRequest(xhrId | 0); this.abortRequest(xhrId | 0);
} }
}, }
abortRequest: function NetworkManager_abortRequest(xhrId) { abortRequest(xhrId) {
var xhr = this.pendingRequests[xhrId].xhr; var xhr = this.pendingRequests[xhrId].xhr;
delete this.pendingRequests[xhrId]; delete this.pendingRequests[xhrId];
xhr.abort(); xhr.abort();
} }
}; }
return NetworkManager; return NetworkManagerClass;
})(); })();

22
extensions/firefox/content/PdfJsTelemetry-addon.jsm

@ -41,47 +41,47 @@ registerAddonHistogram(ADDON_ID, 'PDF_VIEWER_TIME_TO_VIEW_MS', Telemetry.HISTOGR
this.PdfJsTelemetry = { this.PdfJsTelemetry = {
onViewerIsUsed: function () { onViewerIsUsed() {
let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_USED'); let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_USED');
histogram.add(true); histogram.add(true);
}, },
onFallback: function () { onFallback() {
let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_FALLBACK_SHOWN'); let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_FALLBACK_SHOWN');
histogram.add(true); histogram.add(true);
}, },
onDocumentSize: function (size) { onDocumentSize(size) {
let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_DOCUMENT_SIZE_KB'); let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_DOCUMENT_SIZE_KB');
histogram.add(size / 1024); histogram.add(size / 1024);
}, },
onDocumentVersion: function (versionId) { onDocumentVersion(versionId) {
let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_DOCUMENT_VERSION'); let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_DOCUMENT_VERSION');
histogram.add(versionId); histogram.add(versionId);
}, },
onDocumentGenerator: function (generatorId) { onDocumentGenerator(generatorId) {
let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_DOCUMENT_GENERATOR'); let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_DOCUMENT_GENERATOR');
histogram.add(generatorId); histogram.add(generatorId);
}, },
onEmbed: function (isObject) { onEmbed(isObject) {
let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_EMBED'); let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_EMBED');
histogram.add(isObject); histogram.add(isObject);
}, },
onFontType: function (fontTypeId) { onFontType(fontTypeId) {
let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_FONT_TYPES'); let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_FONT_TYPES');
histogram.add(fontTypeId); histogram.add(fontTypeId);
}, },
onForm: function (isAcroform) { onForm(isAcroform) {
let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_FORM'); let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_FORM');
histogram.add(isAcroform); histogram.add(isAcroform);
}, },
onPrint: function () { onPrint() {
let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_PRINT'); let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_PRINT');
histogram.add(true); histogram.add(true);
}, },
onStreamType: function (streamTypeId) { onStreamType(streamTypeId) {
let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_STREAM_TYPES'); let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_STREAM_TYPES');
histogram.add(streamTypeId); histogram.add(streamTypeId);
}, },
onTimeToView: function (ms) { onTimeToView(ms) {
let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_TIME_TO_VIEW_MS'); let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_TIME_TO_VIEW_MS');
histogram.add(ms); histogram.add(ms);
} }

22
extensions/firefox/content/PdfJsTelemetry.jsm

@ -23,47 +23,47 @@ const Cu = Components.utils;
Cu.import('resource://gre/modules/Services.jsm'); Cu.import('resource://gre/modules/Services.jsm');
this.PdfJsTelemetry = { this.PdfJsTelemetry = {
onViewerIsUsed: function () { onViewerIsUsed() {
let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_USED'); let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_USED');
histogram.add(true); histogram.add(true);
}, },
onFallback: function () { onFallback() {
let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_FALLBACK_SHOWN'); let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_FALLBACK_SHOWN');
histogram.add(true); histogram.add(true);
}, },
onDocumentSize: function (size) { onDocumentSize(size) {
let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_DOCUMENT_SIZE_KB'); let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_DOCUMENT_SIZE_KB');
histogram.add(size / 1024); histogram.add(size / 1024);
}, },
onDocumentVersion: function (versionId) { onDocumentVersion(versionId) {
let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_DOCUMENT_VERSION'); let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_DOCUMENT_VERSION');
histogram.add(versionId); histogram.add(versionId);
}, },
onDocumentGenerator: function (generatorId) { onDocumentGenerator(generatorId) {
let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_DOCUMENT_GENERATOR'); let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_DOCUMENT_GENERATOR');
histogram.add(generatorId); histogram.add(generatorId);
}, },
onEmbed: function (isObject) { onEmbed(isObject) {
let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_EMBED'); let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_EMBED');
histogram.add(isObject); histogram.add(isObject);
}, },
onFontType: function (fontTypeId) { onFontType(fontTypeId) {
let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_FONT_TYPES'); let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_FONT_TYPES');
histogram.add(fontTypeId); histogram.add(fontTypeId);
}, },
onForm: function (isAcroform) { onForm(isAcroform) {
let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_FORM'); let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_FORM');
histogram.add(isAcroform); histogram.add(isAcroform);
}, },
onPrint: function () { onPrint() {
let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_PRINT'); let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_PRINT');
histogram.add(true); histogram.add(true);
}, },
onStreamType: function (streamTypeId) { onStreamType(streamTypeId) {
let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_STREAM_TYPES'); let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_STREAM_TYPES');
histogram.add(streamTypeId); histogram.add(streamTypeId);
}, },
onTimeToView: function (ms) { onTimeToView(ms) {
let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_TIME_TO_VIEW_MS'); let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_TIME_TO_VIEW_MS');
histogram.add(ms); histogram.add(ms);
} }

396
extensions/firefox/content/PdfStreamConverter.jsm

@ -190,7 +190,7 @@ PdfDataListener.prototype = {
this.oncompleteCallback(null, errorCode); this.oncompleteCallback(null, errorCode);
} }
}, },
onprogress: function() {}, onprogress() {},
get oncomplete() { get oncomplete() {
return this.oncompleteCallback; return this.oncompleteCallback;
}, },
@ -205,24 +205,27 @@ PdfDataListener.prototype = {
} }
}; };
// All the priviledged actions. /**
function ChromeActions(domWindow, contentDispositionFilename) { * All the privileged actions.
this.domWindow = domWindow; */
this.contentDispositionFilename = contentDispositionFilename; class ChromeActions {
this.telemetryState = { constructor(domWindow, contentDispositionFilename) {
documentInfo: false, this.domWindow = domWindow;
firstPageInfo: false, this.contentDispositionFilename = contentDispositionFilename;
streamTypesUsed: [], this.telemetryState = {
fontTypesUsed: [], documentInfo: false,
startAt: Date.now() firstPageInfo: false,
}; streamTypesUsed: [],
} fontTypesUsed: [],
startAt: Date.now()
};
}
ChromeActions.prototype = { isInPrivateBrowsing() {
isInPrivateBrowsing: function() {
return PrivateBrowsingUtils.isContentWindowPrivate(this.domWindow); return PrivateBrowsingUtils.isContentWindowPrivate(this.domWindow);
}, }
download: function(data, sendResponse) {
download(data, sendResponse) {
var self = this; var self = this;
var originalUrl = data.originalUrl; var originalUrl = data.originalUrl;
var blobUrl = data.blobUrl || originalUrl; var blobUrl = data.blobUrl || originalUrl;
@ -279,7 +282,7 @@ ChromeActions.prototype = {
var listener = { var listener = {
extListener: null, extListener: null,
onStartRequest: function(aRequest, aContext) { onStartRequest(aRequest, aContext) {
var loadContext = self.domWindow var loadContext = self.domWindow
.QueryInterface(Ci.nsIInterfaceRequestor) .QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation) .getInterface(Ci.nsIWebNavigation)
@ -290,7 +293,7 @@ ChromeActions.prototype = {
aRequest, loadContext, false); aRequest, loadContext, false);
this.extListener.onStartRequest(aRequest, aContext); this.extListener.onStartRequest(aRequest, aContext);
}, },
onStopRequest: function(aRequest, aContext, aStatusCode) { onStopRequest(aRequest, aContext, aStatusCode) {
if (this.extListener) { if (this.extListener) {
this.extListener.onStopRequest(aRequest, aContext, aStatusCode); this.extListener.onStopRequest(aRequest, aContext, aStatusCode);
} }
@ -299,20 +302,21 @@ ChromeActions.prototype = {
sendResponse(false); sendResponse(false);
} }
}, },
onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, onDataAvailable(aRequest, aContext, aDataInputStream, aOffset, aCount) {
aCount) { this.extListener.onDataAvailable(aRequest, aContext, aDataInputStream,
this.extListener.onDataAvailable(aRequest, aContext, aInputStream,
aOffset, aCount); aOffset, aCount);
} }
}; };
channel.asyncOpen2(listener); channel.asyncOpen2(listener);
}); });
}, }
getLocale: function() {
getLocale() {
return getStringPref('general.useragent.locale', 'en-US'); return getStringPref('general.useragent.locale', 'en-US');
}, }
getStrings: function(data) {
getStrings(data) {
try { try {
// Lazy initialization of localizedStrings // Lazy initialization of localizedStrings
if (!('localizedStrings' in this)) { if (!('localizedStrings' in this)) {
@ -324,8 +328,9 @@ ChromeActions.prototype = {
log('Unable to retrieve localized strings: ' + e); log('Unable to retrieve localized strings: ' + e);
return 'null'; return 'null';
} }
}, }
supportsIntegratedFind: function() {
supportsIntegratedFind() {
// Integrated find is only supported when we're not in a frame // Integrated find is only supported when we're not in a frame
if (this.domWindow.frameElement !== null) { if (this.domWindow.frameElement !== null) {
return false; return false;
@ -339,22 +344,26 @@ ChromeActions.prototype = {
// ... or when the new find events code exists. // ... or when the new find events code exists.
var findBar = getFindBar(this.domWindow); var findBar = getFindBar(this.domWindow);
return !!findBar && ('updateControlState' in findBar); return !!findBar && ('updateControlState' in findBar);
}, }
supportsDocumentFonts: function() {
supportsDocumentFonts() {
var prefBrowser = getIntPref('browser.display.use_document_fonts', 1); var prefBrowser = getIntPref('browser.display.use_document_fonts', 1);
var prefGfx = getBoolPref('gfx.downloadable_fonts.enabled', true); var prefGfx = getBoolPref('gfx.downloadable_fonts.enabled', true);
return (!!prefBrowser && prefGfx); return (!!prefBrowser && prefGfx);
}, }
supportsDocumentColors: function() {
supportsDocumentColors() {
return getIntPref('browser.display.document_color_use', 0) !== 2; return getIntPref('browser.display.document_color_use', 0) !== 2;
}, }
supportedMouseWheelZoomModifierKeys: function() {
supportedMouseWheelZoomModifierKeys() {
return { return {
ctrlKey: getIntPref('mousewheel.with_control.action', 3) === 3, ctrlKey: getIntPref('mousewheel.with_control.action', 3) === 3,
metaKey: getIntPref('mousewheel.with_meta.action', 1) === 3, metaKey: getIntPref('mousewheel.with_meta.action', 1) === 3,
}; };
}, }
reportTelemetry: function (data) {
reportTelemetry(data) {
var probeInfo = JSON.parse(data); var probeInfo = JSON.parse(data);
switch (probeInfo.type) { switch (probeInfo.type) {
case 'documentInfo': case 'documentInfo':
@ -409,12 +418,15 @@ ChromeActions.prototype = {
PdfJsTelemetry.onPrint(); PdfJsTelemetry.onPrint();
break; break;
} }
}, }
fallback: function(args, sendResponse) {
/**
* @param {Object} args - Object with `featureId` and `url` properties.
* @param {function} sendResponse - Callback function.
*/
fallback(args, sendResponse) {
var featureId = args.featureId; var featureId = args.featureId;
var url = args.url;
var self = this;
var domWindow = this.domWindow; var domWindow = this.domWindow;
var strings = getLocalizedStrings('chrome.properties'); var strings = getLocalizedStrings('chrome.properties');
var message; var message;
@ -441,8 +453,9 @@ ChromeActions.prototype = {
winmm.removeMessageListener('PDFJS:Child:fallbackDownload', winmm.removeMessageListener('PDFJS:Child:fallbackDownload',
fallbackDownload); fallbackDownload);
}); });
}, }
updateFindControlState: function(data) {
updateFindControlState(data) {
if (!this.supportsIntegratedFind()) { if (!this.supportsIntegratedFind()) {
return; return;
} }
@ -461,8 +474,9 @@ ChromeActions.prototype = {
.getInterface(Ci.nsIContentFrameMessageManager); .getInterface(Ci.nsIContentFrameMessageManager);
winmm.sendAsyncMessage('PDFJS:Parent:updateControlState', data); winmm.sendAsyncMessage('PDFJS:Parent:updateControlState', data);
}, }
setPreferences: function(prefs, sendResponse) {
setPreferences(prefs, sendResponse) {
var defaultBranch = Services.prefs.getDefaultBranch(PREF_PREFIX + '.'); var defaultBranch = Services.prefs.getDefaultBranch(PREF_PREFIX + '.');
var numberOfPrefs = 0; var numberOfPrefs = 0;
var prefValue, prefName; var prefValue, prefName;
@ -496,8 +510,9 @@ ChromeActions.prototype = {
if (sendResponse) { if (sendResponse) {
sendResponse(true); sendResponse(true);
} }
}, }
getPreferences: function(prefs, sendResponse) {
getPreferences(prefs, sendResponse) {
var defaultBranch = Services.prefs.getDefaultBranch(PREF_PREFIX + '.'); var defaultBranch = Services.prefs.getDefaultBranch(PREF_PREFIX + '.');
var currentPrefs = {}, numberOfPrefs = 0; var currentPrefs = {}, numberOfPrefs = 0;
var prefValue, prefName; var prefValue, prefName;
@ -529,17 +544,16 @@ ChromeActions.prototype = {
return JSON.stringify(currentPrefs); return JSON.stringify(currentPrefs);
} }
} }
}; }
var RangedChromeActions = (function RangedChromeActionsClosure() { /**
/** * This is for range requests.
* This is for range requests */
*/ class RangedChromeActions extends ChromeActions {
function RangedChromeActions( constructor(domWindow, contentDispositionFilename, originalRequest,
domWindow, contentDispositionFilename, originalRequest,
rangeEnabled, streamingEnabled, dataListener) { rangeEnabled, streamingEnabled, dataListener) {
ChromeActions.call(this, domWindow, contentDispositionFilename); super(domWindow, contentDispositionFilename);
this.dataListener = dataListener; this.dataListener = dataListener;
this.originalRequest = originalRequest; this.originalRequest = originalRequest;
this.rangeEnabled = rangeEnabled; this.rangeEnabled = rangeEnabled;
@ -551,7 +565,7 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
// Pass all the headers from the original request through // Pass all the headers from the original request through
var httpHeaderVisitor = { var httpHeaderVisitor = {
headers: {}, headers: {},
visitHeader: function(aHeader, aValue) { visitHeader(aHeader, aValue) {
if (aHeader === 'Range') { if (aHeader === 'Range') {
// When loading the PDF from cache, firefox seems to set the Range // When loading the PDF from cache, firefox seems to set the Range
// request header to fetch only the unfetched portions of the file // request header to fetch only the unfetched portions of the file
@ -587,7 +601,7 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
this.networkManager = new NetworkManager(this.pdfUrl, { this.networkManager = new NetworkManager(this.pdfUrl, {
httpHeaders: httpHeaderVisitor.headers, httpHeaders: httpHeaderVisitor.headers,
getXhr: getXhr getXhr,
}); });
// If we are in range request mode, this means we manually issued xhr // If we are in range request mode, this means we manually issued xhr
@ -598,12 +612,7 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
}); });
} }
RangedChromeActions.prototype = Object.create(ChromeActions.prototype); initPassiveLoading() {
var proto = RangedChromeActions.prototype;
proto.constructor = RangedChromeActions;
proto.initPassiveLoading = function RangedChromeActions_initPassiveLoading() {
var self = this;
var data; var data;
if (!this.streamingEnabled) { if (!this.streamingEnabled) {
this.originalRequest.cancel(Cr.NS_BINDING_ABORTED); this.originalRequest.cancel(Cr.NS_BINDING_ABORTED);
@ -613,16 +622,16 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
} else { } else {
data = this.dataListener.readData(); data = this.dataListener.readData();
this.dataListener.onprogress = function (loaded, total) { this.dataListener.onprogress = (loaded, total) => {
self.domWindow.postMessage({ this.domWindow.postMessage({
pdfjsLoadAction: 'progressiveRead', pdfjsLoadAction: 'progressiveRead',
loaded: loaded, loaded,
total: total, total,
chunk: self.dataListener.readData() chunk: this.dataListener.readData(),
}, '*'); }, '*');
}; };
this.dataListener.oncomplete = function () { this.dataListener.oncomplete = () => {
self.dataListener = null; this.dataListener = null;
}; };
} }
@ -632,13 +641,13 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
streamingEnabled: this.streamingEnabled, streamingEnabled: this.streamingEnabled,
pdfUrl: this.pdfUrl, pdfUrl: this.pdfUrl,
length: this.contentLength, length: this.contentLength,
data: data data,
}, '*'); }, '*');
return true; return true;
}; }
proto.requestDataRange = function RangedChromeActions_requestDataRange(args) { requestDataRange(args) {
if (!this.rangeEnabled) { if (!this.rangeEnabled) {
return; return;
} }
@ -650,11 +659,11 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
// errors from chrome code for non-range requests, so this doesn't // errors from chrome code for non-range requests, so this doesn't
// seem high-pri // seem high-pri
this.networkManager.requestRange(begin, end, { this.networkManager.requestRange(begin, end, {
onDone: function RangedChromeActions_onDone(args) { onDone: function RangedChromeActions_onDone(aArgs) {
domWindow.postMessage({ domWindow.postMessage({
pdfjsLoadAction: 'range', pdfjsLoadAction: 'range',
begin: args.begin, begin: aArgs.begin,
chunk: args.chunk chunk: aArgs.chunk,
}, '*'); }, '*');
}, },
onProgress: function RangedChromeActions_onProgress(evt) { onProgress: function RangedChromeActions_onProgress(evt) {
@ -664,162 +673,155 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
}, '*'); }, '*');
} }
}); });
}; }
proto.abortLoading = function RangedChromeActions_abortLoading() { abortLoading() {
this.networkManager.abortAllRequests(); this.networkManager.abortAllRequests();
if (this.originalRequest) { if (this.originalRequest) {
this.originalRequest.cancel(Cr.NS_BINDING_ABORTED); this.originalRequest.cancel(Cr.NS_BINDING_ABORTED);
this.originalRequest = null; this.originalRequest = null;
} }
this.dataListener = null; this.dataListener = null;
}; }
}
return RangedChromeActions;
})();
var StandardChromeActions = (function StandardChromeActionsClosure() {
/**
* This is for a single network stream
*/
function StandardChromeActions(domWindow, contentDispositionFilename,
originalRequest, dataListener) {
ChromeActions.call(this, domWindow, contentDispositionFilename); /**
* This is for a single network stream.
*/
class StandardChromeActions extends ChromeActions {
constructor(domWindow, contentDispositionFilename, originalRequest,
dataListener) {
super(domWindow, contentDispositionFilename);
this.originalRequest = originalRequest; this.originalRequest = originalRequest;
this.dataListener = dataListener; this.dataListener = dataListener;
} }
StandardChromeActions.prototype = Object.create(ChromeActions.prototype); initPassiveLoading() {
var proto = StandardChromeActions.prototype;
proto.constructor = StandardChromeActions;
proto.initPassiveLoading =
function StandardChromeActions_initPassiveLoading() {
if (!this.dataListener) { if (!this.dataListener) {
return false; return false;
} }
var self = this; this.dataListener.onprogress = (loaded, total) => {
this.domWindow.postMessage({
this.dataListener.onprogress = function ChromeActions_dataListenerProgress(
loaded, total) {
self.domWindow.postMessage({
pdfjsLoadAction: 'progress', pdfjsLoadAction: 'progress',
loaded: loaded, loaded,
total: total total,
}, '*'); }, '*');
}; };
this.dataListener.oncomplete = this.dataListener.oncomplete = (data, errorCode) => {
function StandardChromeActions_dataListenerComplete(data, errorCode) { this.domWindow.postMessage({
self.domWindow.postMessage({
pdfjsLoadAction: 'complete', pdfjsLoadAction: 'complete',
data: data, data,
errorCode: errorCode errorCode,
}, '*'); }, '*');
self.dataListener = null; this.dataListener = null;
self.originalRequest = null; this.originalRequest = null;
}; };
return true; return true;
}; }
proto.abortLoading = function StandardChromeActions_abortLoading() { abortLoading() {
if (this.originalRequest) { if (this.originalRequest) {
this.originalRequest.cancel(Cr.NS_BINDING_ABORTED); this.originalRequest.cancel(Cr.NS_BINDING_ABORTED);
this.originalRequest = null; this.originalRequest = null;
} }
this.dataListener = null; this.dataListener = null;
}; }
return StandardChromeActions;
})();
// Event listener to trigger chrome privileged code.
function RequestListener(actions) {
this.actions = actions;
} }
// Receive an event and synchronously or asynchronously responds.
RequestListener.prototype.receive = function(event) { /**
var message = event.target; * Event listener to trigger chrome privileged code.
var doc = message.ownerDocument; */
var action = event.detail.action; class RequestListener {
var data = event.detail.data; constructor(actions) {
var sync = event.detail.sync; this.actions = actions;
var actions = this.actions;
if (!(action in actions)) {
log('Unknown action: ' + action);
return;
} }
var response;
if (sync) { // Receive an event and synchronously or asynchronously responds.
response = actions[action].call(this.actions, data); receive(event) {
event.detail.response = Cu.cloneInto(response, doc.defaultView); var message = event.target;
} else { var doc = message.ownerDocument;
if (!event.detail.responseExpected) { var action = event.detail.action;
doc.documentElement.removeChild(message); var data = event.detail.data;
response = null; var sync = event.detail.sync;
var actions = this.actions;
if (!(action in actions)) {
log('Unknown action: ' + action);
return;
}
var response;
if (sync) {
response = actions[action].call(this.actions, data);
event.detail.response = Cu.cloneInto(response, doc.defaultView);
} else { } else {
response = function sendResponse(response) { if (!event.detail.responseExpected) {
try { doc.documentElement.removeChild(message);
var listener = doc.createEvent('CustomEvent'); response = null;
let detail = Cu.cloneInto({ response: response }, doc.defaultView); } else {
listener.initCustomEvent('pdf.js.response', true, false, detail); response = function sendResponse(aResponse) {
return message.dispatchEvent(listener); try {
} catch (e) { var listener = doc.createEvent('CustomEvent');
// doc is no longer accessible because the requestor is already let detail = Cu.cloneInto({ response: aResponse }, doc.defaultView);
// gone. unloaded content cannot receive the response anyway. listener.initCustomEvent('pdf.js.response', true, false, detail);
return false; return message.dispatchEvent(listener);
} } catch (e) {
}; // doc is no longer accessible because the requestor is already
// gone. unloaded content cannot receive the response anyway.
return false;
}
};
}
actions[action].call(this.actions, data, response);
} }
actions[action].call(this.actions, data, response);
} }
};
// Forwards events from the eventElement to the contentWindow only if the
// content window matches the currently selected browser window.
function FindEventManager(contentWindow) {
this.contentWindow = contentWindow;
this.winmm = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIContentFrameMessageManager);
} }
FindEventManager.prototype.bind = function() { /**
var unload = function(e) { * Forwards events from the eventElement to the contentWindow only if the
this.unbind(); * content window matches the currently selected browser window.
this.contentWindow.removeEventListener(e.type, unload); */
}.bind(this); class FindEventManager {
this.contentWindow.addEventListener('unload', unload); constructor(contentWindow) {
this.contentWindow = contentWindow;
// We cannot directly attach listeners to for the find events this.winmm = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
// since the FindBar is in the parent process. Instead we're .getInterface(Ci.nsIDocShell)
// asking the PdfjsChromeUtils to do it for us and forward .QueryInterface(Ci.nsIInterfaceRequestor)
// all the find events to us. .getInterface(Ci.nsIContentFrameMessageManager);
this.winmm.sendAsyncMessage('PDFJS:Parent:addEventListener'); }
this.winmm.addMessageListener('PDFJS:Child:handleEvent', this);
};
FindEventManager.prototype.receiveMessage = function(msg) { bind() {
var detail = msg.data.detail; var unload = function(e) {
var type = msg.data.type; this.unbind();
var contentWindow = this.contentWindow; this.contentWindow.removeEventListener(e.type, unload);
}.bind(this);
this.contentWindow.addEventListener('unload', unload);
// We cannot directly attach listeners to for the find events
// since the FindBar is in the parent process. Instead we're
// asking the PdfjsChromeUtils to do it for us and forward
// all the find events to us.
this.winmm.sendAsyncMessage('PDFJS:Parent:addEventListener');
this.winmm.addMessageListener('PDFJS:Child:handleEvent', this);
}
detail = Cu.cloneInto(detail, contentWindow); receiveMessage(msg) {
var forward = contentWindow.document.createEvent('CustomEvent'); var detail = msg.data.detail;
forward.initCustomEvent(type, true, true, detail); var type = msg.data.type;
contentWindow.dispatchEvent(forward); var contentWindow = this.contentWindow;
};
FindEventManager.prototype.unbind = function() { detail = Cu.cloneInto(detail, contentWindow);
this.winmm.sendAsyncMessage('PDFJS:Parent:removeEventListener'); var forward = contentWindow.document.createEvent('CustomEvent');
}; forward.initCustomEvent(type, true, true, detail);
contentWindow.dispatchEvent(forward);
}
unbind() {
this.winmm.sendAsyncMessage('PDFJS:Parent:removeEventListener');
}
}
function PdfStreamConverter() { function PdfStreamConverter() {
} }
@ -858,18 +860,18 @@ PdfStreamConverter.prototype = {
*/ */
// nsIStreamConverter::convert // nsIStreamConverter::convert
convert: function(aFromStream, aFromType, aToType, aCtxt) { convert(aFromStream, aFromType, aToType, aCtxt) {
throw Cr.NS_ERROR_NOT_IMPLEMENTED; throw Cr.NS_ERROR_NOT_IMPLEMENTED;
}, },
// nsIStreamConverter::asyncConvertData // nsIStreamConverter::asyncConvertData
asyncConvertData: function(aFromType, aToType, aListener, aCtxt) { asyncConvertData(aFromType, aToType, aListener, aCtxt) {
// Store the listener passed to us // Store the listener passed to us
this.listener = aListener; this.listener = aListener;
}, },
// nsIStreamListener::onDataAvailable // nsIStreamListener::onDataAvailable
onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) { onDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount) {
if (!this.dataListener) { if (!this.dataListener) {
return; return;
} }
@ -881,7 +883,7 @@ PdfStreamConverter.prototype = {
}, },
// nsIRequestObserver::onStartRequest // nsIRequestObserver::onStartRequest
onStartRequest: function(aRequest, aContext) { onStartRequest(aRequest, aContext) {
// Setup the request so we can use it below. // Setup the request so we can use it below.
var isHttpRequest = false; var isHttpRequest = false;
try { try {
@ -960,14 +962,14 @@ PdfStreamConverter.prototype = {
// request(aRequest) below so we don't overwrite the original channel and // request(aRequest) below so we don't overwrite the original channel and
// trigger an assertion. // trigger an assertion.
var proxy = { var proxy = {
onStartRequest: function(request, context) { onStartRequest(request, context) {
listener.onStartRequest(aRequest, aContext); listener.onStartRequest(aRequest, aContext);
}, },
onDataAvailable: function(request, context, inputStream, offset, count) { onDataAvailable(request, context, inputStream, offset, count) {
listener.onDataAvailable(aRequest, aContext, inputStream, listener.onDataAvailable(aRequest, aContext, inputStream,
offset, count); offset, count);
}, },
onStopRequest: function(request, context, statusCode) { onStopRequest(request, context, statusCode) {
// We get the DOM window here instead of before the request since it // We get the DOM window here instead of before the request since it
// may have changed during a redirect. // may have changed during a redirect.
var domWindow = getDOMWindow(channel); var domWindow = getDOMWindow(channel);
@ -1017,7 +1019,7 @@ PdfStreamConverter.prototype = {
}, },
// nsIRequestObserver::onStopRequest // nsIRequestObserver::onStopRequest
onStopRequest: function(aRequest, aContext, aStatusCode) { onStopRequest(aRequest, aContext, aStatusCode) {
if (!this.dataListener) { if (!this.dataListener) {
// Do nothing // Do nothing
return; return;

44
extensions/firefox/content/PdfjsChromeUtils.jsm

@ -51,7 +51,7 @@ var PdfjsChromeUtils = {
* Public API * Public API
*/ */
init: function () { init() {
this._browsers = new WeakSet(); this._browsers = new WeakSet();
if (!this._ppmm) { if (!this._ppmm) {
// global parent process message manager (PPMM) // global parent process message manager (PPMM)
@ -78,7 +78,7 @@ var PdfjsChromeUtils = {
} }
}, },
uninit: function () { uninit() {
if (this._ppmm) { if (this._ppmm) {
this._ppmm.removeMessageListener('PDFJS:Parent:clearUserPref', this); this._ppmm.removeMessageListener('PDFJS:Parent:clearUserPref', this);
this._ppmm.removeMessageListener('PDFJS:Parent:setIntPref', this); this._ppmm.removeMessageListener('PDFJS:Parent:setIntPref', this);
@ -107,7 +107,7 @@ var PdfjsChromeUtils = {
* instruct the child to refresh its configuration and (possibly) * instruct the child to refresh its configuration and (possibly)
* the module's registration. * the module's registration.
*/ */
notifyChildOfSettingsChange: function () { notifyChildOfSettingsChange() {
if (Services.appinfo.processType === if (Services.appinfo.processType ===
Services.appinfo.PROCESS_TYPE_DEFAULT && this._ppmm) { Services.appinfo.PROCESS_TYPE_DEFAULT && this._ppmm) {
// XXX kinda bad, we want to get the parent process mm associated // XXX kinda bad, we want to get the parent process mm associated
@ -123,13 +123,13 @@ var PdfjsChromeUtils = {
* Events * Events
*/ */
observe: function(aSubject, aTopic, aData) { observe(aSubject, aTopic, aData) {
if (aTopic === 'quit-application') { if (aTopic === 'quit-application') {
this.uninit(); this.uninit();
} }
}, },
receiveMessage: function (aMsg) { receiveMessage(aMsg) {
switch (aMsg.name) { switch (aMsg.name) {
case 'PDFJS:Parent:clearUserPref': case 'PDFJS:Parent:clearUserPref':
this._clearUserPref(aMsg.data.name); this._clearUserPref(aMsg.data.name);
@ -166,20 +166,20 @@ var PdfjsChromeUtils = {
* Internal * Internal
*/ */
_findbarFromMessage: function(aMsg) { _findbarFromMessage(aMsg) {
let browser = aMsg.target; let browser = aMsg.target;
let tabbrowser = browser.getTabBrowser(); let tabbrowser = browser.getTabBrowser();
let tab = tabbrowser.getTabForBrowser(browser); let tab = tabbrowser.getTabForBrowser(browser);
return tabbrowser.getFindBar(tab); return tabbrowser.getFindBar(tab);
}, },
_updateControlState: function (aMsg) { _updateControlState(aMsg) {
let data = aMsg.data; let data = aMsg.data;
this._findbarFromMessage(aMsg) this._findbarFromMessage(aMsg)
.updateControlState(data.result, data.findPrevious); .updateControlState(data.result, data.findPrevious);
}, },
handleEvent: function(aEvent) { handleEvent(aEvent) {
// To avoid forwarding the message as a CPOW, create a structured cloneable // To avoid forwarding the message as a CPOW, create a structured cloneable
// version of the event for both performance, and ease of usage, reasons. // version of the event for both performance, and ease of usage, reasons.
let type = aEvent.type; let type = aEvent.type;
@ -197,8 +197,7 @@ var PdfjsChromeUtils = {
} }
// Only forward the events if the current browser is a registered browser. // Only forward the events if the current browser is a registered browser.
let mm = browser.messageManager; let mm = browser.messageManager;
mm.sendAsyncMessage('PDFJS:Child:handleEvent', mm.sendAsyncMessage('PDFJS:Child:handleEvent', { type, detail, });
{ type: type, detail: detail });
aEvent.preventDefault(); aEvent.preventDefault();
}, },
@ -207,7 +206,7 @@ var PdfjsChromeUtils = {
'findhighlightallchange', 'findhighlightallchange',
'findcasesensitivitychange'], 'findcasesensitivitychange'],
_addEventListener: function (aMsg) { _addEventListener(aMsg) {
let browser = aMsg.target; let browser = aMsg.target;
if (this._browsers.has(browser)) { if (this._browsers.has(browser)) {
throw new Error('FindEventManager was bound 2nd time ' + throw new Error('FindEventManager was bound 2nd time ' +
@ -226,7 +225,7 @@ var PdfjsChromeUtils = {
} }
}, },
_removeEventListener: function (aMsg) { _removeEventListener(aMsg) {
let browser = aMsg.target; let browser = aMsg.target;
if (!this._browsers.has(browser)) { if (!this._browsers.has(browser)) {
throw new Error('FindEventManager was unbound without binding it first.'); throw new Error('FindEventManager was unbound without binding it first.');
@ -242,7 +241,7 @@ var PdfjsChromeUtils = {
} }
}, },
_ensurePreferenceAllowed: function (aPrefName) { _ensurePreferenceAllowed(aPrefName) {
let unPrefixedName = aPrefName.split(PREF_PREFIX + '.'); let unPrefixedName = aPrefName.split(PREF_PREFIX + '.');
if (unPrefixedName[0] !== '' || if (unPrefixedName[0] !== '' ||
this._allowedPrefNames.indexOf(unPrefixedName[1]) === -1) { this._allowedPrefNames.indexOf(unPrefixedName[1]) === -1) {
@ -252,27 +251,27 @@ var PdfjsChromeUtils = {
} }
}, },
_clearUserPref: function (aPrefName) { _clearUserPref(aPrefName) {
this._ensurePreferenceAllowed(aPrefName); this._ensurePreferenceAllowed(aPrefName);
Services.prefs.clearUserPref(aPrefName); Services.prefs.clearUserPref(aPrefName);
}, },
_setIntPref: function (aPrefName, aPrefValue) { _setIntPref(aPrefName, aPrefValue) {
this._ensurePreferenceAllowed(aPrefName); this._ensurePreferenceAllowed(aPrefName);
Services.prefs.setIntPref(aPrefName, aPrefValue); Services.prefs.setIntPref(aPrefName, aPrefValue);
}, },
_setBoolPref: function (aPrefName, aPrefValue) { _setBoolPref(aPrefName, aPrefValue) {
this._ensurePreferenceAllowed(aPrefName); this._ensurePreferenceAllowed(aPrefName);
Services.prefs.setBoolPref(aPrefName, aPrefValue); Services.prefs.setBoolPref(aPrefName, aPrefValue);
}, },
_setCharPref: function (aPrefName, aPrefValue) { _setCharPref(aPrefName, aPrefValue) {
this._ensurePreferenceAllowed(aPrefName); this._ensurePreferenceAllowed(aPrefName);
Services.prefs.setCharPref(aPrefName, aPrefValue); Services.prefs.setCharPref(aPrefName, aPrefValue);
}, },
_setStringPref: function (aPrefName, aPrefValue) { _setStringPref(aPrefName, aPrefValue) {
this._ensurePreferenceAllowed(aPrefName); this._ensurePreferenceAllowed(aPrefName);
let str = Cc['@mozilla.org/supports-string;1'] let str = Cc['@mozilla.org/supports-string;1']
.createInstance(Ci.nsISupportsString); .createInstance(Ci.nsISupportsString);
@ -285,7 +284,7 @@ var PdfjsChromeUtils = {
* we bounce this pdfjs enabled configuration check over to the * we bounce this pdfjs enabled configuration check over to the
* parent. * parent.
*/ */
isDefaultHandlerApp: function () { isDefaultHandlerApp() {
var handlerInfo = Svc.mime.getFromTypeAndExtension(PDF_CONTENT_TYPE, 'pdf'); var handlerInfo = Svc.mime.getFromTypeAndExtension(PDF_CONTENT_TYPE, 'pdf');
return (!handlerInfo.alwaysAskBeforeHandling && return (!handlerInfo.alwaysAskBeforeHandling &&
handlerInfo.preferredAction === Ci.nsIHandlerInfo.handleInternally); handlerInfo.preferredAction === Ci.nsIHandlerInfo.handleInternally);
@ -295,7 +294,7 @@ var PdfjsChromeUtils = {
* Display a notification warning when the renderer isn't sure * Display a notification warning when the renderer isn't sure
* a pdf displayed correctly. * a pdf displayed correctly.
*/ */
_displayWarning: function (aMsg) { _displayWarning(aMsg) {
let data = aMsg.data; let data = aMsg.data;
let browser = aMsg.target; let browser = aMsg.target;
@ -308,13 +307,12 @@ var PdfjsChromeUtils = {
let messageSent = false; let messageSent = false;
function sendMessage(download) { function sendMessage(download) {
let mm = browser.messageManager; let mm = browser.messageManager;
mm.sendAsyncMessage('PDFJS:Child:fallbackDownload', mm.sendAsyncMessage('PDFJS:Child:fallbackDownload', { download, });
{ download: download });
} }
let buttons = [{ let buttons = [{
label: data.label, label: data.label,
accessKey: data.accessKey, accessKey: data.accessKey,
callback: function() { callback() {
messageSent = true; messageSent = true;
sendMessage(true); sendMessage(true);
} }

24
extensions/firefox/content/PdfjsContentUtils.jsm

@ -38,7 +38,7 @@ var PdfjsContentUtils = {
Services.appinfo.PROCESS_TYPE_CONTENT); Services.appinfo.PROCESS_TYPE_CONTENT);
}, },
init: function () { init() {
// child *process* mm, or when loaded into the parent for in-content // child *process* mm, or when loaded into the parent for in-content
// support the psuedo child process mm 'child PPMM'. // support the psuedo child process mm 'child PPMM'.
if (!this._mm) { if (!this._mm) {
@ -49,7 +49,7 @@ var PdfjsContentUtils = {
} }
}, },
uninit: function () { uninit() {
if (this._mm) { if (this._mm) {
this._mm.removeMessageListener('PDFJS:Child:refreshSettings', this); this._mm.removeMessageListener('PDFJS:Child:refreshSettings', this);
Services.obs.removeObserver(this, 'quit-application'); Services.obs.removeObserver(this, 'quit-application');
@ -63,34 +63,34 @@ var PdfjsContentUtils = {
* approved pdfjs prefs in chrome utils. * approved pdfjs prefs in chrome utils.
*/ */
clearUserPref: function (aPrefName) { clearUserPref(aPrefName) {
this._mm.sendSyncMessage('PDFJS:Parent:clearUserPref', { this._mm.sendSyncMessage('PDFJS:Parent:clearUserPref', {
name: aPrefName name: aPrefName
}); });
}, },
setIntPref: function (aPrefName, aPrefValue) { setIntPref(aPrefName, aPrefValue) {
this._mm.sendSyncMessage('PDFJS:Parent:setIntPref', { this._mm.sendSyncMessage('PDFJS:Parent:setIntPref', {
name: aPrefName, name: aPrefName,
value: aPrefValue value: aPrefValue
}); });
}, },
setBoolPref: function (aPrefName, aPrefValue) { setBoolPref(aPrefName, aPrefValue) {
this._mm.sendSyncMessage('PDFJS:Parent:setBoolPref', { this._mm.sendSyncMessage('PDFJS:Parent:setBoolPref', {
name: aPrefName, name: aPrefName,
value: aPrefValue value: aPrefValue
}); });
}, },
setCharPref: function (aPrefName, aPrefValue) { setCharPref(aPrefName, aPrefValue) {
this._mm.sendSyncMessage('PDFJS:Parent:setCharPref', { this._mm.sendSyncMessage('PDFJS:Parent:setCharPref', {
name: aPrefName, name: aPrefName,
value: aPrefValue value: aPrefValue
}); });
}, },
setStringPref: function (aPrefName, aPrefValue) { setStringPref(aPrefName, aPrefValue) {
this._mm.sendSyncMessage('PDFJS:Parent:setStringPref', { this._mm.sendSyncMessage('PDFJS:Parent:setStringPref', {
name: aPrefName, name: aPrefName,
value: aPrefValue value: aPrefValue
@ -101,7 +101,7 @@ var PdfjsContentUtils = {
* Forwards default app query to the parent where we check various * Forwards default app query to the parent where we check various
* handler app settings only available in the parent process. * handler app settings only available in the parent process.
*/ */
isDefaultHandlerApp: function () { isDefaultHandlerApp() {
return this._mm.sendSyncMessage('PDFJS:Parent:isDefaultHandlerApp')[0]; return this._mm.sendSyncMessage('PDFJS:Parent:isDefaultHandlerApp')[0];
}, },
@ -109,7 +109,7 @@ var PdfjsContentUtils = {
* Request the display of a notification warning in the associated window * Request the display of a notification warning in the associated window
* when the renderer isn't sure a pdf displayed correctly. * when the renderer isn't sure a pdf displayed correctly.
*/ */
displayWarning: function (aWindow, aMessage, aLabel, accessKey) { displayWarning(aWindow, aMessage, aLabel, aAccessKey) {
// the child's dom frame mm associated with the window. // the child's dom frame mm associated with the window.
let winmm = aWindow.QueryInterface(Ci.nsIInterfaceRequestor) let winmm = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell) .getInterface(Ci.nsIDocShell)
@ -118,7 +118,7 @@ var PdfjsContentUtils = {
winmm.sendAsyncMessage('PDFJS:Parent:displayWarning', { winmm.sendAsyncMessage('PDFJS:Parent:displayWarning', {
message: aMessage, message: aMessage,
label: aLabel, label: aLabel,
accessKey: accessKey accessKey: aAccessKey,
}); });
}, },
@ -126,13 +126,13 @@ var PdfjsContentUtils = {
* Events * Events
*/ */
observe: function(aSubject, aTopic, aData) { observe(aSubject, aTopic, aData) {
if (aTopic === 'quit-application') { if (aTopic === 'quit-application') {
this.uninit(); this.uninit();
} }
}, },
receiveMessage: function (aMsg) { receiveMessage(aMsg) {
switch (aMsg.name) { switch (aMsg.name) {
case 'PDFJS:Child:refreshSettings': case 'PDFJS:Child:refreshSettings':
// Only react to this if we are remote. // Only react to this if we are remote.

10
extensions/firefox/tools/l10n.js

@ -121,12 +121,12 @@
get: translateString, get: translateString,
// get the document language // get the document language
getLanguage: function() { getLanguage() {
return gLanguage; return gLanguage;
}, },
// get the direction (ltr|rtl) of the current language // get the direction (ltr|rtl) of the current language
getDirection: function() { getDirection() {
// http://www.w3.org/International/questions/qa-scripts // http://www.w3.org/International/questions/qa-scripts
// Arabic, Hebrew, Farsi, Pashto, Urdu // Arabic, Hebrew, Farsi, Pashto, Urdu
var rtlList = ['ar', 'he', 'fa', 'ps', 'ur']; var rtlList = ['ar', 'he', 'fa', 'ps', 'ur'];
@ -137,9 +137,11 @@
return (rtlList.indexOf(shortCode) >= 0) ? 'rtl' : 'ltr'; return (rtlList.indexOf(shortCode) >= 0) ? 'rtl' : 'ltr';
}, },
getReadyState: function() { return gReadyState; }, getReadyState() {
return gReadyState;
},
setExternalLocalizerServices: function (externalLocalizerServices) { setExternalLocalizerServices(externalLocalizerServices) {
gExternalLocalizerServices = externalLocalizerServices; gExternalLocalizerServices = externalLocalizerServices;
// ... in case if we missed DOMContentLoaded above. // ... in case if we missed DOMContentLoaded above.

Loading…
Cancel
Save