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.