From 3ec99f0e12c8da2df927937a8a29c1eca7ad020a Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sun, 22 Jan 2017 18:07:53 +0100 Subject: [PATCH] [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. --- .eslintrc | 2 + extensions/firefox/.eslintrc | 24 ++ extensions/firefox/chrome/content.js | 4 +- extensions/firefox/content/PdfJsNetwork.jsm | 100 ++--- .../firefox/content/PdfJsTelemetry-addon.jsm | 22 +- extensions/firefox/content/PdfJsTelemetry.jsm | 22 +- .../firefox/content/PdfStreamConverter.jsm | 400 +++++++++--------- .../firefox/content/PdfjsChromeUtils.jsm | 44 +- .../firefox/content/PdfjsContentUtils.jsm | 24 +- extensions/firefox/tools/l10n.js | 10 +- 10 files changed, 340 insertions(+), 312 deletions(-) diff --git a/.eslintrc b/.eslintrc index be7de86a7..fa220bd7a 100644 --- a/.eslintrc +++ b/.eslintrc @@ -119,4 +119,6 @@ } }], }, + + // ECMAScript 6 } diff --git a/extensions/firefox/.eslintrc b/extensions/firefox/.eslintrc index 71258ac58..bad2e8945 100644 --- a/extensions/firefox/.eslintrc +++ b/extensions/firefox/.eslintrc @@ -6,4 +6,28 @@ "parserOptions": { "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 }], + }, } diff --git a/extensions/firefox/chrome/content.js b/extensions/firefox/chrome/content.js index b9afd9826..ab0c7342f 100644 --- a/extensions/firefox/chrome/content.js +++ b/extensions/firefox/chrome/content.js @@ -32,7 +32,7 @@ var isRemote = Services.appinfo.processType === 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() { } @@ -93,7 +93,7 @@ if (isRemote) { startup(); - addMessageListener('PDFJS:Child:shutdown', function (e) { + addMessageListener('PDFJS:Child:shutdown', function() { shutdown(); }); } diff --git a/extensions/firefox/content/PdfJsNetwork.jsm b/extensions/firefox/content/PdfJsNetwork.jsm index ed5b48760..582c365e7 100644 --- a/extensions/firefox/content/PdfJsNetwork.jsm +++ b/extensions/firefox/content/PdfJsNetwork.jsm @@ -27,24 +27,8 @@ function log(aMsg) { var NetworkManager = (function NetworkManagerClosure() { - var OK_RESPONSE = 200; - var 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); - } + const OK_RESPONSE = 200; + const PARTIAL_CONTENT_RESPONSE = 206; function getArrayBuffer(xhr) { var data = xhr.response; @@ -59,27 +43,43 @@ var NetworkManager = (function NetworkManagerClosure() { return array.buffer; } - NetworkManager.prototype = { - requestRange: function NetworkManager_requestRange(begin, end, listeners) { + class NetworkManagerClass { + 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 = { - begin: begin, - end: end + begin, + end, }; for (var prop in listeners) { args[prop] = listeners[prop]; } return this.request(args); - }, + } - requestFull: function NetworkManager_requestFull(listeners) { + requestFull(listeners) { return this.request(listeners); - }, + } - request: function NetworkManager_request(args) { + request(args) { var xhr = this.getXhr(); var xhrId = this.currXhrId++; var pendingRequest = this.pendingRequests[xhrId] = { - xhr: xhr + xhr, }; xhr.open('GET', this.url); @@ -124,9 +124,9 @@ var NetworkManager = (function NetworkManagerClosure() { xhr.send(null); return xhrId; - }, + } - onProgress: function NetworkManager_onProgress(xhrId, evt) { + onProgress(xhrId, evt) { var pendingRequest = this.pendingRequests[xhrId]; if (!pendingRequest) { // Maybe abortRequest was called... @@ -142,9 +142,9 @@ var NetworkManager = (function NetworkManagerClosure() { if (onProgress) { onProgress(evt); } - }, + } - onStateChange: function NetworkManager_onStateChange(xhrId, evt) { + onStateChange(xhrId, evt) { var pendingRequest = this.pendingRequests[xhrId]; if (!pendingRequest) { // Maybe abortRequest was called... @@ -201,56 +201,56 @@ var NetworkManager = (function NetworkManagerClosure() { var matches = /bytes (\d+)-(\d+)\/(\d+)/.exec(rangeHeader); var begin = parseInt(matches[1], 10); pendingRequest.onDone({ - begin: begin, - chunk: chunk + begin, + chunk, }); } else if (pendingRequest.onProgressiveData) { pendingRequest.onDone(null); } else if (chunk) { pendingRequest.onDone({ begin: 0, - chunk: chunk + chunk, }); } else if (pendingRequest.onError) { pendingRequest.onError(xhr.status); } - }, + } - hasPendingRequests: function NetworkManager_hasPendingRequests() { + hasPendingRequests() { for (var xhrId in this.pendingRequests) { return true; } return false; - }, + } - getRequestXhr: function NetworkManager_getXhr(xhrId) { + getRequestXhr(xhrId) { return this.pendingRequests[xhrId].xhr; - }, + } - isStreamingRequest: function NetworkManager_isStreamingRequest(xhrId) { + isStreamingRequest(xhrId) { return !!(this.pendingRequests[xhrId].onProgressiveData); - }, + } - isPendingRequest: function NetworkManager_isPendingRequest(xhrId) { + isPendingRequest(xhrId) { return xhrId in this.pendingRequests; - }, + } - isLoadedRequest: function NetworkManager_isLoadedRequest(xhrId) { + isLoadedRequest(xhrId) { return xhrId in this.loadedRequests; - }, + } - abortAllRequests: function NetworkManager_abortAllRequests() { + abortAllRequests() { for (var xhrId in this.pendingRequests) { this.abortRequest(xhrId | 0); } - }, + } - abortRequest: function NetworkManager_abortRequest(xhrId) { + abortRequest(xhrId) { var xhr = this.pendingRequests[xhrId].xhr; delete this.pendingRequests[xhrId]; xhr.abort(); } - }; + } - return NetworkManager; + return NetworkManagerClass; })(); diff --git a/extensions/firefox/content/PdfJsTelemetry-addon.jsm b/extensions/firefox/content/PdfJsTelemetry-addon.jsm index 147796f9a..0aa89af0f 100644 --- a/extensions/firefox/content/PdfJsTelemetry-addon.jsm +++ b/extensions/firefox/content/PdfJsTelemetry-addon.jsm @@ -41,47 +41,47 @@ registerAddonHistogram(ADDON_ID, 'PDF_VIEWER_TIME_TO_VIEW_MS', Telemetry.HISTOGR this.PdfJsTelemetry = { - onViewerIsUsed: function () { + onViewerIsUsed() { let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_USED'); histogram.add(true); }, - onFallback: function () { + onFallback() { let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_FALLBACK_SHOWN'); histogram.add(true); }, - onDocumentSize: function (size) { + onDocumentSize(size) { let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_DOCUMENT_SIZE_KB'); histogram.add(size / 1024); }, - onDocumentVersion: function (versionId) { + onDocumentVersion(versionId) { let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_DOCUMENT_VERSION'); histogram.add(versionId); }, - onDocumentGenerator: function (generatorId) { + onDocumentGenerator(generatorId) { let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_DOCUMENT_GENERATOR'); histogram.add(generatorId); }, - onEmbed: function (isObject) { + onEmbed(isObject) { let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_EMBED'); histogram.add(isObject); }, - onFontType: function (fontTypeId) { + onFontType(fontTypeId) { let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_FONT_TYPES'); histogram.add(fontTypeId); }, - onForm: function (isAcroform) { + onForm(isAcroform) { let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_FORM'); histogram.add(isAcroform); }, - onPrint: function () { + onPrint() { let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_PRINT'); histogram.add(true); }, - onStreamType: function (streamTypeId) { + onStreamType(streamTypeId) { let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_STREAM_TYPES'); histogram.add(streamTypeId); }, - onTimeToView: function (ms) { + onTimeToView(ms) { let histogram = Telemetry.getAddonHistogram(ADDON_ID, 'PDF_VIEWER_TIME_TO_VIEW_MS'); histogram.add(ms); } diff --git a/extensions/firefox/content/PdfJsTelemetry.jsm b/extensions/firefox/content/PdfJsTelemetry.jsm index 0d34cd50e..9f0988801 100644 --- a/extensions/firefox/content/PdfJsTelemetry.jsm +++ b/extensions/firefox/content/PdfJsTelemetry.jsm @@ -23,47 +23,47 @@ const Cu = Components.utils; Cu.import('resource://gre/modules/Services.jsm'); this.PdfJsTelemetry = { - onViewerIsUsed: function () { + onViewerIsUsed() { let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_USED'); histogram.add(true); }, - onFallback: function () { + onFallback() { let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_FALLBACK_SHOWN'); histogram.add(true); }, - onDocumentSize: function (size) { + onDocumentSize(size) { let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_DOCUMENT_SIZE_KB'); histogram.add(size / 1024); }, - onDocumentVersion: function (versionId) { + onDocumentVersion(versionId) { let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_DOCUMENT_VERSION'); histogram.add(versionId); }, - onDocumentGenerator: function (generatorId) { + onDocumentGenerator(generatorId) { let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_DOCUMENT_GENERATOR'); histogram.add(generatorId); }, - onEmbed: function (isObject) { + onEmbed(isObject) { let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_EMBED'); histogram.add(isObject); }, - onFontType: function (fontTypeId) { + onFontType(fontTypeId) { let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_FONT_TYPES'); histogram.add(fontTypeId); }, - onForm: function (isAcroform) { + onForm(isAcroform) { let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_FORM'); histogram.add(isAcroform); }, - onPrint: function () { + onPrint() { let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_PRINT'); histogram.add(true); }, - onStreamType: function (streamTypeId) { + onStreamType(streamTypeId) { let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_STREAM_TYPES'); histogram.add(streamTypeId); }, - onTimeToView: function (ms) { + onTimeToView(ms) { let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_TIME_TO_VIEW_MS'); histogram.add(ms); } diff --git a/extensions/firefox/content/PdfStreamConverter.jsm b/extensions/firefox/content/PdfStreamConverter.jsm index dee59a0ed..3afe1527b 100644 --- a/extensions/firefox/content/PdfStreamConverter.jsm +++ b/extensions/firefox/content/PdfStreamConverter.jsm @@ -190,7 +190,7 @@ PdfDataListener.prototype = { this.oncompleteCallback(null, errorCode); } }, - onprogress: function() {}, + onprogress() {}, get oncomplete() { return this.oncompleteCallback; }, @@ -205,24 +205,27 @@ PdfDataListener.prototype = { } }; -// All the priviledged actions. -function ChromeActions(domWindow, contentDispositionFilename) { - this.domWindow = domWindow; - this.contentDispositionFilename = contentDispositionFilename; - this.telemetryState = { - documentInfo: false, - firstPageInfo: false, - streamTypesUsed: [], - fontTypesUsed: [], - startAt: Date.now() - }; -} +/** + * All the privileged actions. + */ +class ChromeActions { + constructor(domWindow, contentDispositionFilename) { + this.domWindow = domWindow; + this.contentDispositionFilename = contentDispositionFilename; + this.telemetryState = { + documentInfo: false, + firstPageInfo: false, + streamTypesUsed: [], + fontTypesUsed: [], + startAt: Date.now() + }; + } -ChromeActions.prototype = { - isInPrivateBrowsing: function() { + isInPrivateBrowsing() { return PrivateBrowsingUtils.isContentWindowPrivate(this.domWindow); - }, - download: function(data, sendResponse) { + } + + download(data, sendResponse) { var self = this; var originalUrl = data.originalUrl; var blobUrl = data.blobUrl || originalUrl; @@ -279,7 +282,7 @@ ChromeActions.prototype = { var listener = { extListener: null, - onStartRequest: function(aRequest, aContext) { + onStartRequest(aRequest, aContext) { var loadContext = self.domWindow .QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIWebNavigation) @@ -290,7 +293,7 @@ ChromeActions.prototype = { aRequest, loadContext, false); this.extListener.onStartRequest(aRequest, aContext); }, - onStopRequest: function(aRequest, aContext, aStatusCode) { + onStopRequest(aRequest, aContext, aStatusCode) { if (this.extListener) { this.extListener.onStopRequest(aRequest, aContext, aStatusCode); } @@ -299,20 +302,21 @@ ChromeActions.prototype = { sendResponse(false); } }, - onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, - aCount) { - this.extListener.onDataAvailable(aRequest, aContext, aInputStream, + onDataAvailable(aRequest, aContext, aDataInputStream, aOffset, aCount) { + this.extListener.onDataAvailable(aRequest, aContext, aDataInputStream, aOffset, aCount); } }; channel.asyncOpen2(listener); }); - }, - getLocale: function() { + } + + getLocale() { return getStringPref('general.useragent.locale', 'en-US'); - }, - getStrings: function(data) { + } + + getStrings(data) { try { // Lazy initialization of localizedStrings if (!('localizedStrings' in this)) { @@ -324,8 +328,9 @@ ChromeActions.prototype = { log('Unable to retrieve localized strings: ' + e); return 'null'; } - }, - supportsIntegratedFind: function() { + } + + supportsIntegratedFind() { // Integrated find is only supported when we're not in a frame if (this.domWindow.frameElement !== null) { return false; @@ -339,22 +344,26 @@ ChromeActions.prototype = { // ... or when the new find events code exists. var findBar = getFindBar(this.domWindow); return !!findBar && ('updateControlState' in findBar); - }, - supportsDocumentFonts: function() { + } + + supportsDocumentFonts() { var prefBrowser = getIntPref('browser.display.use_document_fonts', 1); var prefGfx = getBoolPref('gfx.downloadable_fonts.enabled', true); return (!!prefBrowser && prefGfx); - }, - supportsDocumentColors: function() { + } + + supportsDocumentColors() { return getIntPref('browser.display.document_color_use', 0) !== 2; - }, - supportedMouseWheelZoomModifierKeys: function() { + } + + supportedMouseWheelZoomModifierKeys() { return { ctrlKey: getIntPref('mousewheel.with_control.action', 3) === 3, metaKey: getIntPref('mousewheel.with_meta.action', 1) === 3, }; - }, - reportTelemetry: function (data) { + } + + reportTelemetry(data) { var probeInfo = JSON.parse(data); switch (probeInfo.type) { case 'documentInfo': @@ -409,12 +418,15 @@ ChromeActions.prototype = { PdfJsTelemetry.onPrint(); break; } - }, - fallback: function(args, sendResponse) { - var featureId = args.featureId; - var url = args.url; + } + + /** + * @param {Object} args - Object with `featureId` and `url` properties. + * @param {function} sendResponse - Callback function. + */ + fallback(args, sendResponse) { + var featureId = args.featureId; - var self = this; var domWindow = this.domWindow; var strings = getLocalizedStrings('chrome.properties'); var message; @@ -441,8 +453,9 @@ ChromeActions.prototype = { winmm.removeMessageListener('PDFJS:Child:fallbackDownload', fallbackDownload); }); - }, - updateFindControlState: function(data) { + } + + updateFindControlState(data) { if (!this.supportsIntegratedFind()) { return; } @@ -461,8 +474,9 @@ ChromeActions.prototype = { .getInterface(Ci.nsIContentFrameMessageManager); winmm.sendAsyncMessage('PDFJS:Parent:updateControlState', data); - }, - setPreferences: function(prefs, sendResponse) { + } + + setPreferences(prefs, sendResponse) { var defaultBranch = Services.prefs.getDefaultBranch(PREF_PREFIX + '.'); var numberOfPrefs = 0; var prefValue, prefName; @@ -496,8 +510,9 @@ ChromeActions.prototype = { if (sendResponse) { sendResponse(true); } - }, - getPreferences: function(prefs, sendResponse) { + } + + getPreferences(prefs, sendResponse) { var defaultBranch = Services.prefs.getDefaultBranch(PREF_PREFIX + '.'); var currentPrefs = {}, numberOfPrefs = 0; var prefValue, prefName; @@ -529,17 +544,16 @@ ChromeActions.prototype = { return JSON.stringify(currentPrefs); } } -}; +} -var RangedChromeActions = (function RangedChromeActionsClosure() { - /** - * This is for range requests - */ - function RangedChromeActions( - domWindow, contentDispositionFilename, originalRequest, +/** + * This is for range requests. + */ +class RangedChromeActions extends ChromeActions { + constructor(domWindow, contentDispositionFilename, originalRequest, rangeEnabled, streamingEnabled, dataListener) { - ChromeActions.call(this, domWindow, contentDispositionFilename); + super(domWindow, contentDispositionFilename); this.dataListener = dataListener; this.originalRequest = originalRequest; this.rangeEnabled = rangeEnabled; @@ -551,7 +565,7 @@ var RangedChromeActions = (function RangedChromeActionsClosure() { // Pass all the headers from the original request through var httpHeaderVisitor = { headers: {}, - visitHeader: function(aHeader, aValue) { + visitHeader(aHeader, aValue) { if (aHeader === 'Range') { // When loading the PDF from cache, firefox seems to set the Range // 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, { httpHeaders: httpHeaderVisitor.headers, - getXhr: getXhr + getXhr, }); // 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); - var proto = RangedChromeActions.prototype; - proto.constructor = RangedChromeActions; - - proto.initPassiveLoading = function RangedChromeActions_initPassiveLoading() { - var self = this; + initPassiveLoading() { var data; if (!this.streamingEnabled) { this.originalRequest.cancel(Cr.NS_BINDING_ABORTED); @@ -613,16 +622,16 @@ var RangedChromeActions = (function RangedChromeActionsClosure() { } else { data = this.dataListener.readData(); - this.dataListener.onprogress = function (loaded, total) { - self.domWindow.postMessage({ + this.dataListener.onprogress = (loaded, total) => { + this.domWindow.postMessage({ pdfjsLoadAction: 'progressiveRead', - loaded: loaded, - total: total, - chunk: self.dataListener.readData() + loaded, + total, + chunk: this.dataListener.readData(), }, '*'); }; - this.dataListener.oncomplete = function () { - self.dataListener = null; + this.dataListener.oncomplete = () => { + this.dataListener = null; }; } @@ -632,13 +641,13 @@ var RangedChromeActions = (function RangedChromeActionsClosure() { streamingEnabled: this.streamingEnabled, pdfUrl: this.pdfUrl, length: this.contentLength, - data: data + data, }, '*'); return true; - }; + } - proto.requestDataRange = function RangedChromeActions_requestDataRange(args) { + requestDataRange(args) { if (!this.rangeEnabled) { return; } @@ -650,11 +659,11 @@ var RangedChromeActions = (function RangedChromeActionsClosure() { // errors from chrome code for non-range requests, so this doesn't // seem high-pri this.networkManager.requestRange(begin, end, { - onDone: function RangedChromeActions_onDone(args) { + onDone: function RangedChromeActions_onDone(aArgs) { domWindow.postMessage({ pdfjsLoadAction: 'range', - begin: args.begin, - chunk: args.chunk + begin: aArgs.begin, + chunk: aArgs.chunk, }, '*'); }, onProgress: function RangedChromeActions_onProgress(evt) { @@ -664,162 +673,155 @@ var RangedChromeActions = (function RangedChromeActionsClosure() { }, '*'); } }); - }; + } - proto.abortLoading = function RangedChromeActions_abortLoading() { + abortLoading() { this.networkManager.abortAllRequests(); if (this.originalRequest) { this.originalRequest.cancel(Cr.NS_BINDING_ABORTED); this.originalRequest = 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.dataListener = dataListener; } - StandardChromeActions.prototype = Object.create(ChromeActions.prototype); - var proto = StandardChromeActions.prototype; - proto.constructor = StandardChromeActions; - - proto.initPassiveLoading = - function StandardChromeActions_initPassiveLoading() { - + initPassiveLoading() { if (!this.dataListener) { return false; } - var self = this; - - this.dataListener.onprogress = function ChromeActions_dataListenerProgress( - loaded, total) { - self.domWindow.postMessage({ + this.dataListener.onprogress = (loaded, total) => { + this.domWindow.postMessage({ pdfjsLoadAction: 'progress', - loaded: loaded, - total: total + loaded, + total, }, '*'); }; - this.dataListener.oncomplete = - function StandardChromeActions_dataListenerComplete(data, errorCode) { - self.domWindow.postMessage({ + this.dataListener.oncomplete = (data, errorCode) => { + this.domWindow.postMessage({ pdfjsLoadAction: 'complete', - data: data, - errorCode: errorCode + data, + errorCode, }, '*'); - self.dataListener = null; - self.originalRequest = null; + this.dataListener = null; + this.originalRequest = null; }; return true; - }; + } - proto.abortLoading = function StandardChromeActions_abortLoading() { + abortLoading() { if (this.originalRequest) { this.originalRequest.cancel(Cr.NS_BINDING_ABORTED); this.originalRequest = 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; - var doc = message.ownerDocument; - var action = event.detail.action; - var data = event.detail.data; - 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 { - if (!event.detail.responseExpected) { - doc.documentElement.removeChild(message); - response = null; - } else { - response = function sendResponse(response) { - try { - var listener = doc.createEvent('CustomEvent'); - let detail = Cu.cloneInto({ response: response }, doc.defaultView); - listener.initCustomEvent('pdf.js.response', true, false, detail); - 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; - } - }; +} + +/** + * Event listener to trigger chrome privileged code. + */ +class RequestListener { + constructor(actions) { + this.actions = actions; + } + + // Receive an event and synchronously or asynchronously responds. + receive(event) { + var message = event.target; + var doc = message.ownerDocument; + var action = event.detail.action; + var data = event.detail.data; + 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 { + if (!event.detail.responseExpected) { + doc.documentElement.removeChild(message); + response = null; + } else { + response = function sendResponse(aResponse) { + try { + var listener = doc.createEvent('CustomEvent'); + let detail = Cu.cloneInto({ response: aResponse }, doc.defaultView); + listener.initCustomEvent('pdf.js.response', true, false, detail); + 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) { - this.unbind(); - this.contentWindow.removeEventListener(e.type, unload); - }.bind(this); - this.contentWindow.addEventListener('unload', unload); +/** + * Forwards events from the eventElement to the contentWindow only if the + * content window matches the currently selected browser window. + */ +class FindEventManager { + constructor(contentWindow) { + this.contentWindow = contentWindow; + this.winmm = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDocShell) + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIContentFrameMessageManager); + } - // 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); -}; + bind() { + var unload = function(e) { + this.unbind(); + this.contentWindow.removeEventListener(e.type, unload); + }.bind(this); + this.contentWindow.addEventListener('unload', unload); -FindEventManager.prototype.receiveMessage = function(msg) { - var detail = msg.data.detail; - var type = msg.data.type; - var contentWindow = this.contentWindow; + // 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); - var forward = contentWindow.document.createEvent('CustomEvent'); - forward.initCustomEvent(type, true, true, detail); - contentWindow.dispatchEvent(forward); -}; + receiveMessage(msg) { + var detail = msg.data.detail; + var type = msg.data.type; + var contentWindow = this.contentWindow; -FindEventManager.prototype.unbind = function() { - this.winmm.sendAsyncMessage('PDFJS:Parent:removeEventListener'); -}; + detail = Cu.cloneInto(detail, contentWindow); + var forward = contentWindow.document.createEvent('CustomEvent'); + forward.initCustomEvent(type, true, true, detail); + contentWindow.dispatchEvent(forward); + } + + unbind() { + this.winmm.sendAsyncMessage('PDFJS:Parent:removeEventListener'); + } +} function PdfStreamConverter() { } @@ -858,18 +860,18 @@ PdfStreamConverter.prototype = { */ // nsIStreamConverter::convert - convert: function(aFromStream, aFromType, aToType, aCtxt) { + convert(aFromStream, aFromType, aToType, aCtxt) { throw Cr.NS_ERROR_NOT_IMPLEMENTED; }, // nsIStreamConverter::asyncConvertData - asyncConvertData: function(aFromType, aToType, aListener, aCtxt) { + asyncConvertData(aFromType, aToType, aListener, aCtxt) { // Store the listener passed to us this.listener = aListener; }, // nsIStreamListener::onDataAvailable - onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) { + onDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount) { if (!this.dataListener) { return; } @@ -881,7 +883,7 @@ PdfStreamConverter.prototype = { }, // nsIRequestObserver::onStartRequest - onStartRequest: function(aRequest, aContext) { + onStartRequest(aRequest, aContext) { // Setup the request so we can use it below. var isHttpRequest = false; try { @@ -960,14 +962,14 @@ PdfStreamConverter.prototype = { // request(aRequest) below so we don't overwrite the original channel and // trigger an assertion. var proxy = { - onStartRequest: function(request, context) { + onStartRequest(request, context) { listener.onStartRequest(aRequest, aContext); }, - onDataAvailable: function(request, context, inputStream, offset, count) { + onDataAvailable(request, context, inputStream, offset, count) { listener.onDataAvailable(aRequest, aContext, inputStream, offset, count); }, - onStopRequest: function(request, context, statusCode) { + onStopRequest(request, context, statusCode) { // We get the DOM window here instead of before the request since it // may have changed during a redirect. var domWindow = getDOMWindow(channel); @@ -1017,7 +1019,7 @@ PdfStreamConverter.prototype = { }, // nsIRequestObserver::onStopRequest - onStopRequest: function(aRequest, aContext, aStatusCode) { + onStopRequest(aRequest, aContext, aStatusCode) { if (!this.dataListener) { // Do nothing return; diff --git a/extensions/firefox/content/PdfjsChromeUtils.jsm b/extensions/firefox/content/PdfjsChromeUtils.jsm index fccbd88b3..fec780c4b 100644 --- a/extensions/firefox/content/PdfjsChromeUtils.jsm +++ b/extensions/firefox/content/PdfjsChromeUtils.jsm @@ -51,7 +51,7 @@ var PdfjsChromeUtils = { * Public API */ - init: function () { + init() { this._browsers = new WeakSet(); if (!this._ppmm) { // global parent process message manager (PPMM) @@ -78,7 +78,7 @@ var PdfjsChromeUtils = { } }, - uninit: function () { + uninit() { if (this._ppmm) { this._ppmm.removeMessageListener('PDFJS:Parent:clearUserPref', this); this._ppmm.removeMessageListener('PDFJS:Parent:setIntPref', this); @@ -107,7 +107,7 @@ var PdfjsChromeUtils = { * instruct the child to refresh its configuration and (possibly) * the module's registration. */ - notifyChildOfSettingsChange: function () { + notifyChildOfSettingsChange() { if (Services.appinfo.processType === Services.appinfo.PROCESS_TYPE_DEFAULT && this._ppmm) { // XXX kinda bad, we want to get the parent process mm associated @@ -123,13 +123,13 @@ var PdfjsChromeUtils = { * Events */ - observe: function(aSubject, aTopic, aData) { + observe(aSubject, aTopic, aData) { if (aTopic === 'quit-application') { this.uninit(); } }, - receiveMessage: function (aMsg) { + receiveMessage(aMsg) { switch (aMsg.name) { case 'PDFJS:Parent:clearUserPref': this._clearUserPref(aMsg.data.name); @@ -166,20 +166,20 @@ var PdfjsChromeUtils = { * Internal */ - _findbarFromMessage: function(aMsg) { + _findbarFromMessage(aMsg) { let browser = aMsg.target; let tabbrowser = browser.getTabBrowser(); let tab = tabbrowser.getTabForBrowser(browser); return tabbrowser.getFindBar(tab); }, - _updateControlState: function (aMsg) { + _updateControlState(aMsg) { let data = aMsg.data; this._findbarFromMessage(aMsg) .updateControlState(data.result, data.findPrevious); }, - handleEvent: function(aEvent) { + handleEvent(aEvent) { // To avoid forwarding the message as a CPOW, create a structured cloneable // version of the event for both performance, and ease of usage, reasons. let type = aEvent.type; @@ -197,8 +197,7 @@ var PdfjsChromeUtils = { } // Only forward the events if the current browser is a registered browser. let mm = browser.messageManager; - mm.sendAsyncMessage('PDFJS:Child:handleEvent', - { type: type, detail: detail }); + mm.sendAsyncMessage('PDFJS:Child:handleEvent', { type, detail, }); aEvent.preventDefault(); }, @@ -207,7 +206,7 @@ var PdfjsChromeUtils = { 'findhighlightallchange', 'findcasesensitivitychange'], - _addEventListener: function (aMsg) { + _addEventListener(aMsg) { let browser = aMsg.target; if (this._browsers.has(browser)) { throw new Error('FindEventManager was bound 2nd time ' + @@ -226,7 +225,7 @@ var PdfjsChromeUtils = { } }, - _removeEventListener: function (aMsg) { + _removeEventListener(aMsg) { let browser = aMsg.target; if (!this._browsers.has(browser)) { 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 + '.'); if (unPrefixedName[0] !== '' || this._allowedPrefNames.indexOf(unPrefixedName[1]) === -1) { @@ -252,27 +251,27 @@ var PdfjsChromeUtils = { } }, - _clearUserPref: function (aPrefName) { + _clearUserPref(aPrefName) { this._ensurePreferenceAllowed(aPrefName); Services.prefs.clearUserPref(aPrefName); }, - _setIntPref: function (aPrefName, aPrefValue) { + _setIntPref(aPrefName, aPrefValue) { this._ensurePreferenceAllowed(aPrefName); Services.prefs.setIntPref(aPrefName, aPrefValue); }, - _setBoolPref: function (aPrefName, aPrefValue) { + _setBoolPref(aPrefName, aPrefValue) { this._ensurePreferenceAllowed(aPrefName); Services.prefs.setBoolPref(aPrefName, aPrefValue); }, - _setCharPref: function (aPrefName, aPrefValue) { + _setCharPref(aPrefName, aPrefValue) { this._ensurePreferenceAllowed(aPrefName); Services.prefs.setCharPref(aPrefName, aPrefValue); }, - _setStringPref: function (aPrefName, aPrefValue) { + _setStringPref(aPrefName, aPrefValue) { this._ensurePreferenceAllowed(aPrefName); let str = Cc['@mozilla.org/supports-string;1'] .createInstance(Ci.nsISupportsString); @@ -285,7 +284,7 @@ var PdfjsChromeUtils = { * we bounce this pdfjs enabled configuration check over to the * parent. */ - isDefaultHandlerApp: function () { + isDefaultHandlerApp() { var handlerInfo = Svc.mime.getFromTypeAndExtension(PDF_CONTENT_TYPE, 'pdf'); return (!handlerInfo.alwaysAskBeforeHandling && handlerInfo.preferredAction === Ci.nsIHandlerInfo.handleInternally); @@ -295,7 +294,7 @@ var PdfjsChromeUtils = { * Display a notification warning when the renderer isn't sure * a pdf displayed correctly. */ - _displayWarning: function (aMsg) { + _displayWarning(aMsg) { let data = aMsg.data; let browser = aMsg.target; @@ -308,13 +307,12 @@ var PdfjsChromeUtils = { let messageSent = false; function sendMessage(download) { let mm = browser.messageManager; - mm.sendAsyncMessage('PDFJS:Child:fallbackDownload', - { download: download }); + mm.sendAsyncMessage('PDFJS:Child:fallbackDownload', { download, }); } let buttons = [{ label: data.label, accessKey: data.accessKey, - callback: function() { + callback() { messageSent = true; sendMessage(true); } diff --git a/extensions/firefox/content/PdfjsContentUtils.jsm b/extensions/firefox/content/PdfjsContentUtils.jsm index aec9f8c76..63830fa11 100644 --- a/extensions/firefox/content/PdfjsContentUtils.jsm +++ b/extensions/firefox/content/PdfjsContentUtils.jsm @@ -38,7 +38,7 @@ var PdfjsContentUtils = { Services.appinfo.PROCESS_TYPE_CONTENT); }, - init: function () { + init() { // child *process* mm, or when loaded into the parent for in-content // support the psuedo child process mm 'child PPMM'. if (!this._mm) { @@ -49,7 +49,7 @@ var PdfjsContentUtils = { } }, - uninit: function () { + uninit() { if (this._mm) { this._mm.removeMessageListener('PDFJS:Child:refreshSettings', this); Services.obs.removeObserver(this, 'quit-application'); @@ -63,34 +63,34 @@ var PdfjsContentUtils = { * approved pdfjs prefs in chrome utils. */ - clearUserPref: function (aPrefName) { + clearUserPref(aPrefName) { this._mm.sendSyncMessage('PDFJS:Parent:clearUserPref', { name: aPrefName }); }, - setIntPref: function (aPrefName, aPrefValue) { + setIntPref(aPrefName, aPrefValue) { this._mm.sendSyncMessage('PDFJS:Parent:setIntPref', { name: aPrefName, value: aPrefValue }); }, - setBoolPref: function (aPrefName, aPrefValue) { + setBoolPref(aPrefName, aPrefValue) { this._mm.sendSyncMessage('PDFJS:Parent:setBoolPref', { name: aPrefName, value: aPrefValue }); }, - setCharPref: function (aPrefName, aPrefValue) { + setCharPref(aPrefName, aPrefValue) { this._mm.sendSyncMessage('PDFJS:Parent:setCharPref', { name: aPrefName, value: aPrefValue }); }, - setStringPref: function (aPrefName, aPrefValue) { + setStringPref(aPrefName, aPrefValue) { this._mm.sendSyncMessage('PDFJS:Parent:setStringPref', { name: aPrefName, value: aPrefValue @@ -101,7 +101,7 @@ var PdfjsContentUtils = { * Forwards default app query to the parent where we check various * handler app settings only available in the parent process. */ - isDefaultHandlerApp: function () { + isDefaultHandlerApp() { 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 * 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. let winmm = aWindow.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIDocShell) @@ -118,7 +118,7 @@ var PdfjsContentUtils = { winmm.sendAsyncMessage('PDFJS:Parent:displayWarning', { message: aMessage, label: aLabel, - accessKey: accessKey + accessKey: aAccessKey, }); }, @@ -126,13 +126,13 @@ var PdfjsContentUtils = { * Events */ - observe: function(aSubject, aTopic, aData) { + observe(aSubject, aTopic, aData) { if (aTopic === 'quit-application') { this.uninit(); } }, - receiveMessage: function (aMsg) { + receiveMessage(aMsg) { switch (aMsg.name) { case 'PDFJS:Child:refreshSettings': // Only react to this if we are remote. diff --git a/extensions/firefox/tools/l10n.js b/extensions/firefox/tools/l10n.js index e45cf200a..3fd173b8e 100644 --- a/extensions/firefox/tools/l10n.js +++ b/extensions/firefox/tools/l10n.js @@ -121,12 +121,12 @@ get: translateString, // get the document language - getLanguage: function() { + getLanguage() { return gLanguage; }, // get the direction (ltr|rtl) of the current language - getDirection: function() { + getDirection() { // http://www.w3.org/International/questions/qa-scripts // Arabic, Hebrew, Farsi, Pashto, Urdu var rtlList = ['ar', 'he', 'fa', 'ps', 'ur']; @@ -137,9 +137,11 @@ return (rtlList.indexOf(shortCode) >= 0) ? 'rtl' : 'ltr'; }, - getReadyState: function() { return gReadyState; }, + getReadyState() { + return gReadyState; + }, - setExternalLocalizerServices: function (externalLocalizerServices) { + setExternalLocalizerServices(externalLocalizerServices) { gExternalLocalizerServices = externalLocalizerServices; // ... in case if we missed DOMContentLoaded above.