diff -Nru firefox-trunk-67.0~a1~hg20190207r457544/accessible/generic/TableAccessible.cpp firefox-trunk-67.0~a1~hg20190209r458331/accessible/generic/TableAccessible.cpp --- firefox-trunk-67.0~a1~hg20190207r457544/accessible/generic/TableAccessible.cpp 2019-02-07 12:50:25.000000000 +0000 +++ firefox-trunk-67.0~a1~hg20190209r458331/accessible/generic/TableAccessible.cpp 2019-02-09 08:54:08.000000000 +0000 @@ -263,3 +263,34 @@ return cell; } + +int32_t TableAccessible::ColIndexAt(uint32_t aCellIdx) { + uint32_t colCount = ColCount(); + if (colCount < 1 || aCellIdx >= colCount * RowCount()) { + return -1; // Error: column count is 0 or index out of bounds. + } + + return aCellIdx % colCount; +} + +int32_t TableAccessible::RowIndexAt(uint32_t aCellIdx) { + uint32_t colCount = ColCount(); + if (colCount < 1 || aCellIdx >= colCount * RowCount()) { + return -1; // Error: column count is 0 or index out of bounds. + } + + return aCellIdx / colCount; +} + +void TableAccessible::RowAndColIndicesAt(uint32_t aCellIdx, int32_t* aRowIdx, + int32_t* aColIdx) { + uint32_t colCount = ColCount(); + if (colCount < 1 || aCellIdx >= colCount * RowCount()) { + *aRowIdx = -1; + *aColIdx = -1; + return; // Error: column count is 0 or index out of bounds. + } + + *aRowIdx = aCellIdx / colCount; + *aColIdx = aCellIdx % colCount; +} diff -Nru firefox-trunk-67.0~a1~hg20190207r457544/accessible/generic/TableAccessible.h firefox-trunk-67.0~a1~hg20190209r458331/accessible/generic/TableAccessible.h --- firefox-trunk-67.0~a1~hg20190207r457544/accessible/generic/TableAccessible.h 2019-02-07 12:50:25.000000000 +0000 +++ firefox-trunk-67.0~a1~hg20190209r458331/accessible/generic/TableAccessible.h 2019-02-09 08:54:08.000000000 +0000 @@ -56,27 +56,25 @@ /** * Return the column index of the cell with the given index. + * This returns -1 if the column count is 0 or an invalid index is being + * passed in. */ - virtual int32_t ColIndexAt(uint32_t aCellIdx) { - return aCellIdx % ColCount(); - } + virtual int32_t ColIndexAt(uint32_t aCellIdx); /** * Return the row index of the cell with the given index. + * This returns -1 if the column count is 0 or an invalid index is being + * passed in. */ - virtual int32_t RowIndexAt(uint32_t aCellIdx) { - return aCellIdx / ColCount(); - } + virtual int32_t RowIndexAt(uint32_t aCellIdx); /** * Get the row and column indices for the cell at the given index. + * This returns -1 for both output parameters if the column count is 0 or an + * invalid index is being passed in. */ virtual void RowAndColIndicesAt(uint32_t aCellIdx, int32_t* aRowIdx, - int32_t* aColIdx) { - uint32_t colCount = ColCount(); - *aRowIdx = aCellIdx / colCount; - *aColIdx = aCellIdx % colCount; - } + int32_t* aColIdx); /** * Return the number of columns occupied by the cell at the given row and diff -Nru firefox-trunk-67.0~a1~hg20190207r457544/accessible/windows/ia2/ia2AccessibleTable.cpp firefox-trunk-67.0~a1~hg20190209r458331/accessible/windows/ia2/ia2AccessibleTable.cpp --- firefox-trunk-67.0~a1~hg20190207r457544/accessible/windows/ia2/ia2AccessibleTable.cpp 2019-02-07 12:50:25.000000000 +0000 +++ firefox-trunk-67.0~a1~hg20190209r458331/accessible/windows/ia2/ia2AccessibleTable.cpp 2019-02-09 08:54:08.000000000 +0000 @@ -137,11 +137,16 @@ *aColIdx = 0; if (!mTable) return CO_E_OBJNOTCONNECTED; - if (aCellIdx < 0 || static_cast(aCellIdx) >= - mTable->ColCount() * mTable->RowCount()) + if (aCellIdx < 0) { return E_INVALIDARG; + } - *aColIdx = mTable->ColIndexAt(aCellIdx); + long colIdx = mTable->ColIndexAt(aCellIdx); + if (colIdx == -1) { // Indicates an error. + return E_INVALIDARG; + } + + *aColIdx = colIdx; return S_OK; } @@ -246,11 +251,16 @@ *aRowIdx = 0; if (!mTable) return CO_E_OBJNOTCONNECTED; - if (aCellIdx < 0 || static_cast(aCellIdx) >= - mTable->ColCount() * mTable->RowCount()) + if (aCellIdx < 0) { + return E_INVALIDARG; + } + + long rowIdx = mTable->RowIndexAt(aCellIdx); + if (rowIdx == -1) { // Indicates an error. return E_INVALIDARG; + } - *aRowIdx = mTable->RowIndexAt(aCellIdx); + *aRowIdx = rowIdx; return S_OK; } @@ -406,12 +416,16 @@ *aIsSelected = false; if (!mTable) return CO_E_OBJNOTCONNECTED; - if (aCellIdx < 0 || static_cast(aCellIdx) >= - mTable->ColCount() * mTable->RowCount()) + if (aCellIdx < 0) { return E_INVALIDARG; + } int32_t colIdx = 0, rowIdx = 0; mTable->RowAndColIndicesAt(aCellIdx, &rowIdx, &colIdx); + if (rowIdx == -1 || colIdx == -1) { // Indicates an error. + return E_INVALIDARG; + } + *aRowIdx = rowIdx; *aColIdx = colIdx; *aRowExtents = mTable->RowExtentAt(rowIdx, colIdx); diff -Nru firefox-trunk-67.0~a1~hg20190207r457544/browser/app/blocklist.xml firefox-trunk-67.0~a1~hg20190209r458331/browser/app/blocklist.xml --- firefox-trunk-67.0~a1~hg20190207r457544/browser/app/blocklist.xml 2019-02-07 12:50:25.000000000 +0000 +++ firefox-trunk-67.0~a1~hg20190209r458331/browser/app/blocklist.xml 2019-02-09 08:54:08.000000000 +0000 @@ -1,5 +1,5 @@ - + @@ -2480,6 +2480,10 @@ + + + + diff -Nru firefox-trunk-67.0~a1~hg20190207r457544/browser/app/moz.build firefox-trunk-67.0~a1~hg20190209r458331/browser/app/moz.build --- firefox-trunk-67.0~a1~hg20190207r457544/browser/app/moz.build 2019-02-07 12:50:25.000000000 +0000 +++ firefox-trunk-67.0~a1~hg20190209r458331/browser/app/moz.build 2019-02-09 08:54:08.000000000 +0000 @@ -105,11 +105,6 @@ 'user32.dll', ] - if CONFIG['CC_TYPE'] == "msvc": - CFLAGS += ['-guard:cf'] - CXXFLAGS += ['-guard:cf'] - LDFLAGS += ['-guard:cf'] - # Control the default heap size. # This is the heap returned by GetProcessHeap(). # As we use the CRT heap, the default size is too large and wastes VM. diff -Nru firefox-trunk-67.0~a1~hg20190207r457544/browser/app/profile/firefox.js firefox-trunk-67.0~a1~hg20190209r458331/browser/app/profile/firefox.js --- firefox-trunk-67.0~a1~hg20190207r457544/browser/app/profile/firefox.js 2019-02-07 12:50:25.000000000 +0000 +++ firefox-trunk-67.0~a1~hg20190209r458331/browser/app/profile/firefox.js 2019-02-09 08:54:08.000000000 +0000 @@ -58,11 +58,6 @@ pref("extensions.startupScanScopes", 0); pref("extensions.geckoProfiler.acceptedExtensionIds", "geckoprofiler@mozilla.com,quantum-foxfooding@mozilla.com,raptor@mozilla.org"); -#if defined(XP_LINUX) || defined (XP_MACOSX) -pref("extensions.geckoProfiler.getSymbolRules", "localBreakpad,nm"); -#else // defined(XP_WIN) -pref("extensions.geckoProfiler.getSymbolRules", "localBreakpad,dump_syms.exe"); -#endif // Add-on content security policies. @@ -974,11 +969,7 @@ pref("browser.privatebrowsing.autostart", false); // Whether to show the new private browsing UI with in-content search box. -#ifdef EARLY_BETA_OR_EARLIER pref("browser.privatebrowsing.searchUI", true); -#else -pref("browser.privatebrowsing.searchUI", false); -#endif // Whether the bookmark panel should be shown when bookmarking a page. pref("browser.bookmarks.editDialog.showForNewBookmarks", true); @@ -1041,7 +1032,7 @@ // For information on what the level number means, see // SetSecurityLevelForGPUProcess() in // security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp -pref("security.sandbox.gpu.level", 0); +pref("security.sandbox.gpu.level", 1); // Controls whether we disable win32k for the processes. // true means that win32k system calls are not permitted. @@ -1534,11 +1525,7 @@ // Enable GMP support in the addon manager. pref("media.gmp-provider.enabled", true); -// Enable blocking access to storage from tracking resources only in nightly -// and early beta. By default the value is 0: BEHAVIOR_ACCEPT -#ifdef EARLY_BETA_OR_EARLIER pref("network.cookie.cookieBehavior", 4 /* BEHAVIOR_REJECT_TRACKER */); -#endif pref("browser.contentblocking.allowlist.storage.enabled", true); diff -Nru firefox-trunk-67.0~a1~hg20190207r457544/browser/base/content/aboutTabCrashed.xhtml firefox-trunk-67.0~a1~hg20190209r458331/browser/base/content/aboutTabCrashed.xhtml --- firefox-trunk-67.0~a1~hg20190207r457544/browser/base/content/aboutTabCrashed.xhtml 2019-02-07 12:50:25.000000000 +0000 +++ firefox-trunk-67.0~a1~hg20190209r458331/browser/base/content/aboutTabCrashed.xhtml 2019-02-09 08:54:08.000000000 +0000 @@ -15,8 +15,9 @@ href="chrome://browser/content/aboutTabCrashed.css"/> + - + diff -Nru firefox-trunk-67.0~a1~hg20190207r457544/browser/base/content/browser-addons.js firefox-trunk-67.0~a1~hg20190209r458331/browser/base/content/browser-addons.js --- firefox-trunk-67.0~a1~hg20190207r457544/browser/base/content/browser-addons.js 2019-02-07 12:50:25.000000000 +0000 +++ firefox-trunk-67.0~a1~hg20190209r458331/browser/base/content/browser-addons.js 2019-02-09 08:54:08.000000000 +0000 @@ -6,6 +6,138 @@ // This file is loaded into the browser window scope. /* eslint-env mozilla/browser-window */ +customElements.define("addon-progress-notification", class MozAddonProgressNotification extends customElements.get("popupnotification") { + show() { + super.show(); + this.progressmeter = document.getElementById("addon-progress-notification-progressmeter"); + + this.progresstext = document.getElementById("addon-progress-notification-progresstext"); + + if (!this.notification) + return; + + this.notification.options.installs.forEach(function(aInstall) { + aInstall.addListener(this); + }, this); + + // Calling updateProgress can sometimes cause this notification to be + // removed in the middle of refreshing the notification panel which + // makes the panel get refreshed again. Just initialise to the + // undetermined state and then schedule a proper check at the next + // opportunity + this.setProgress(0, -1); + this._updateProgressTimeout = setTimeout(this.updateProgress.bind(this), 0); + } + + disconnectedCallback() { + this.destroy(); + } + + destroy() { + if (!this.notification) + return; + this.notification.options.installs.forEach(function(aInstall) { + aInstall.removeListener(this); + }, this); + + clearTimeout(this._updateProgressTimeout); + } + + setProgress(aProgress, aMaxProgress) { + if (aMaxProgress == -1) { + this.progressmeter.removeAttribute("value"); + } else { + this.progressmeter.setAttribute("value", (aProgress * 100) / aMaxProgress); + } + + let now = Date.now(); + + if (!this.notification.lastUpdate) { + this.notification.lastUpdate = now; + this.notification.lastProgress = aProgress; + return; + } + + let delta = now - this.notification.lastUpdate; + if ((delta < 400) && (aProgress < aMaxProgress)) + return; + + delta /= 1000; + + // This algorithm is the same used by the downloads code. + let speed = (aProgress - this.notification.lastProgress) / delta; + if (this.notification.speed) + speed = speed * 0.9 + this.notification.speed * 0.1; + + this.notification.lastUpdate = now; + this.notification.lastProgress = aProgress; + this.notification.speed = speed; + + let status = null; + [status, this.notification.last] = DownloadUtils.getDownloadStatus(aProgress, aMaxProgress, speed, this.notification.last); + this.progresstext.setAttribute("value", status); + this.progresstext.setAttribute("tooltiptext", status); + } + + cancel() { + let installs = this.notification.options.installs; + installs.forEach(function(aInstall) { + try { + aInstall.cancel(); + } catch (e) { + // Cancel will throw if the download has already failed + } + }, this); + + PopupNotifications.remove(this.notification); + } + + updateProgress() { + if (!this.notification) + return; + + let downloadingCount = 0; + let progress = 0; + let maxProgress = 0; + + this.notification.options.installs.forEach(function(aInstall) { + if (aInstall.maxProgress == -1) + maxProgress = -1; + progress += aInstall.progress; + if (maxProgress >= 0) + maxProgress += aInstall.maxProgress; + if (aInstall.state < AddonManager.STATE_DOWNLOADED) + downloadingCount++; + }); + + if (downloadingCount == 0) { + this.destroy(); + this.progressmeter.removeAttribute("value"); + let status = gNavigatorBundle.getString("addonDownloadVerifying"); + this.progresstext.setAttribute("value", status); + this.progresstext.setAttribute("tooltiptext", status); + } else { + this.setProgress(progress, maxProgress); + } + } + + onDownloadProgress() { + this.updateProgress(); + } + + onDownloadFailed() { + this.updateProgress(); + } + + onDownloadCancelled() { + this.updateProgress(); + } + + onDownloadEnded() { + this.updateProgress(); + } +}); + // Removes a doorhanger notification if all of the installs it was notifying // about have ended in some way. function removeNotificationOnEnd(notification, installs) { diff -Nru firefox-trunk-67.0~a1~hg20190207r457544/browser/base/content/browser-contentblocking.js firefox-trunk-67.0~a1~hg20190209r458331/browser/base/content/browser-contentblocking.js --- firefox-trunk-67.0~a1~hg20190207r457544/browser/base/content/browser-contentblocking.js 2019-02-07 12:50:25.000000000 +0000 +++ firefox-trunk-67.0~a1~hg20190209r458331/browser/base/content/browser-contentblocking.js 2019-02-09 08:54:08.000000000 +0000 @@ -2,6 +2,226 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +var Fingerprinting = { + PREF_ENABLED: "privacy.trackingprotection.fingerprinting.enabled", + + strings: { + get subViewBlocked() { + delete this.subViewBlocked; + return this.subViewBlocked = + gNavigatorBundle.getString("contentBlocking.fingerprintersView.blocked.label"); + }, + }, + + init() { + XPCOMUtils.defineLazyPreferenceGetter(this, "enabled", this.PREF_ENABLED, false); + this.updateCategoryLabel(); + }, + + get categoryItem() { + delete this.categoryItem; + return this.categoryItem = + document.getElementById("identity-popup-content-blocking-category-fingerprinters"); + }, + + get categoryLabel() { + delete this.categoryLabel; + return this.categoryLabel = + document.getElementById("identity-popup-content-blocking-fingerprinters-state-label"); + }, + + get subViewList() { + delete this.subViewList; + return this.subViewList = document.getElementById("identity-popup-fingerprintersView-list"); + }, + + updateCategoryLabel() { + let label; + if (this.enabled) { + label = ContentBlocking.showBlockedLabels ? "contentBlocking.cryptominers.blocking.label" : null; + } else { + label = ContentBlocking.showAllowedLabels ? "contentBlocking.cryptominers.allowed.label" : null; + } + this.categoryLabel.textContent = label ? gNavigatorBundle.getString(label) : ""; + }, + + isBlocking(state) { + return (state & Ci.nsIWebProgressListener.STATE_BLOCKED_FINGERPRINTING_CONTENT) != 0; + }, + + isAllowing(state) { + return this.enabled && (state & Ci.nsIWebProgressListener.STATE_LOADED_FINGERPRINTING_CONTENT) != 0; + }, + + isDetected(state) { + return this.isBlocking(state) || this.isAllowing(state); + }, + + async updateSubView() { + let contentBlockingLog = await gBrowser.selectedBrowser.getContentBlockingLog(); + contentBlockingLog = JSON.parse(contentBlockingLog); + + let fragment = document.createDocumentFragment(); + for (let [origin, actions] of Object.entries(contentBlockingLog)) { + let listItem = this._createListItem(origin, actions); + if (listItem) { + fragment.appendChild(listItem); + } + } + + this.subViewList.textContent = ""; + this.subViewList.append(fragment); + }, + + _createListItem(origin, actions) { + let isAllowed = actions.some(([state]) => this.isAllowing(state)); + let isDetected = isAllowed || actions.some(([state]) => this.isBlocking(state)); + + if (!isDetected) { + return null; + } + + let uri = Services.io.newURI(origin); + + let listItem = document.createXULElement("hbox"); + listItem.className = "identity-popup-content-blocking-list-item"; + listItem.classList.toggle("allowed", isAllowed); + // Repeat the host in the tooltip in case it's too long + // and overflows in our panel. + listItem.tooltipText = uri.host; + + let image = document.createXULElement("image"); + image.className = "identity-popup-fingerprintersView-icon"; + image.classList.toggle("allowed", isAllowed); + listItem.append(image); + + let label = document.createXULElement("label"); + label.value = uri.host; + label.className = "identity-popup-content-blocking-list-host-label"; + label.setAttribute("crop", "end"); + listItem.append(label); + + if (!isAllowed) { + let stateLabel = document.createXULElement("label"); + stateLabel.value = this.strings.subViewBlocked; + stateLabel.className = "identity-popup-content-blocking-list-state-label"; + listItem.append(stateLabel); + } + + return listItem; + }, +}; + +var Cryptomining = { + PREF_ENABLED: "privacy.trackingprotection.cryptomining.enabled", + + strings: { + get subViewBlocked() { + delete this.subViewBlocked; + return this.subViewBlocked = + gNavigatorBundle.getString("contentBlocking.cryptominersView.blocked.label"); + }, + }, + + init() { + XPCOMUtils.defineLazyPreferenceGetter(this, "enabled", this.PREF_ENABLED, false); + this.updateCategoryLabel(); + }, + + get categoryItem() { + delete this.categoryItem; + return this.categoryItem = + document.getElementById("identity-popup-content-blocking-category-cryptominers"); + }, + + get categoryLabel() { + delete this.categoryLabel; + return this.categoryLabel = + document.getElementById("identity-popup-content-blocking-cryptominers-state-label"); + }, + + get subViewList() { + delete this.subViewList; + return this.subViewList = document.getElementById("identity-popup-cryptominersView-list"); + }, + + updateCategoryLabel() { + let label; + if (this.enabled) { + label = ContentBlocking.showBlockedLabels ? "contentBlocking.cryptominers.blocking.label" : null; + } else { + label = ContentBlocking.showAllowedLabels ? "contentBlocking.cryptominers.allowed.label" : null; + } + this.categoryLabel.textContent = label ? gNavigatorBundle.getString(label) : ""; + }, + + isBlocking(state) { + return (state & Ci.nsIWebProgressListener.STATE_BLOCKED_CRYPTOMINING_CONTENT) != 0; + }, + + isAllowing(state) { + return this.enabled && (state & Ci.nsIWebProgressListener.STATE_LOADED_CRYPTOMINING_CONTENT) != 0; + }, + + isDetected(state) { + return this.isBlocking(state) || this.isAllowing(state); + }, + + async updateSubView() { + let contentBlockingLog = await gBrowser.selectedBrowser.getContentBlockingLog(); + contentBlockingLog = JSON.parse(contentBlockingLog); + + let fragment = document.createDocumentFragment(); + for (let [origin, actions] of Object.entries(contentBlockingLog)) { + let listItem = this._createListItem(origin, actions); + if (listItem) { + fragment.appendChild(listItem); + } + } + + this.subViewList.textContent = ""; + this.subViewList.append(fragment); + }, + + _createListItem(origin, actions) { + let isAllowed = actions.some(([state]) => this.isAllowing(state)); + let isDetected = isAllowed || actions.some(([state]) => this.isBlocking(state)); + + if (!isDetected) { + return null; + } + + let uri = Services.io.newURI(origin); + + let listItem = document.createXULElement("hbox"); + listItem.className = "identity-popup-content-blocking-list-item"; + listItem.classList.toggle("allowed", isAllowed); + // Repeat the host in the tooltip in case it's too long + // and overflows in our panel. + listItem.tooltipText = uri.host; + + let image = document.createXULElement("image"); + image.className = "identity-popup-cryptominersView-icon"; + image.classList.toggle("allowed", isAllowed); + listItem.append(image); + + let label = document.createXULElement("label"); + label.value = uri.host; + label.className = "identity-popup-content-blocking-list-host-label"; + label.setAttribute("crop", "end"); + listItem.append(label); + + if (!isAllowed) { + let stateLabel = document.createXULElement("label"); + stateLabel.value = this.strings.subViewBlocked; + stateLabel.className = "identity-popup-content-blocking-list-state-label"; + listItem.append(stateLabel); + } + + return listItem; + }, +}; + var TrackingProtection = { reportBreakageLabel: "trackingprotection", telemetryIdentifier: "tp", @@ -85,20 +305,12 @@ this.categoryLabel.textContent = label ? gNavigatorBundle.getString(label) : ""; }, - // FIXME This must change! Fingerprinting and cryptomining must have theirs - // own sections. See bug 1522566. isBlocking(state) { - return (state & Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT) != 0 || - (state & Ci.nsIWebProgressListener.STATE_BLOCKED_FINGERPRINTING_CONTENT) != 0 || - (state & Ci.nsIWebProgressListener.STATE_BLOCKED_CRYPTOMINING_CONTENT) != 0; + return (state & Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT) != 0; }, - // FIXME This must change! Fingerprinting and cryptomining must have theirs - // own sections. See bug 1522566. isAllowing(state) { - return (state & Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT) != 0 || - (state & Ci.nsIWebProgressListener.STATE_LOADED_FINGERPRINTING_CONTENT) != 0 || - (state & Ci.nsIWebProgressListener.STATE_LOADED_CRYPTOMINING_CONTENT) != 0; + return (state & Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT) != 0; }, isDetected(state) { @@ -109,8 +321,8 @@ let previousURI = gBrowser.currentURI.spec; let previousWindow = gBrowser.selectedBrowser.innerWindowID; - let contentBlockingLogJSON = await gBrowser.selectedBrowser.getContentBlockingLog(); - let contentBlockingLog = JSON.parse(contentBlockingLogJSON); + let contentBlockingLog = await gBrowser.selectedBrowser.getContentBlockingLog(); + contentBlockingLog = JSON.parse(contentBlockingLog); // Don't tell the user to turn on TP if they are already blocking trackers. this.strictInfo.hidden = this.enabled; @@ -177,12 +389,8 @@ async _createListItem(origin, actions) { // Figure out if this list entry was actually detected by TP or something else. - let isDetected = false; - let isAllowed = false; - for (let [state] of actions) { - isAllowed = isAllowed || this.isAllowing(state); - isDetected = isDetected || isAllowed || this.isBlocking(state); - } + let isAllowed = actions.some(([state]) => this.isAllowing(state)); + let isDetected = isAllowed || actions.some(([state]) => this.isBlocking(state)); if (!isDetected) { return null; @@ -336,8 +544,8 @@ }, async updateSubView() { - let contentBlockingLogJSON = await gBrowser.selectedBrowser.getContentBlockingLog(); - let contentBlockingLog = JSON.parse(contentBlockingLogJSON); + let contentBlockingLog = await gBrowser.selectedBrowser.getContentBlockingLog(); + contentBlockingLog = JSON.parse(contentBlockingLog); let categories = this._processContentBlockingLog(contentBlockingLog); @@ -630,11 +838,13 @@ // when blockable content is detected. A blocker must be an object // with at least the following two properties: // - enabled: Whether the blocker is currently turned on. + // - isDetected(state): Given a content blocking state, whether the blocker has + // either allowed or blocked elements. // - categoryItem: The DOM item that represents the entry in the category list. // // It may also contain an init() and uninit() function, which will be called // on ContentBlocking.init() and ContentBlocking.uninit(). - blockers: [TrackingProtection, ThirdPartyCookies], + blockers: [TrackingProtection, ThirdPartyCookies, Fingerprinting, Cryptomining], get _baseURIForChannelClassifier() { // Convert document URI into the format used by @@ -813,6 +1023,16 @@ this.identityPopupMultiView.showSubView("identity-popup-cookiesView"); }, + async showFingerprintersSubview() { + await Fingerprinting.updateSubView(); + this.identityPopupMultiView.showSubView("identity-popup-fingerprintersView"); + }, + + async showCryptominersSubview() { + await Cryptomining.updateSubView(); + this.identityPopupMultiView.showSubView("identity-popup-cryptominersView"); + }, + shieldHistogramAdd(value) { if (PrivateBrowsingUtils.isWindowPrivate(window)) { return; diff -Nru firefox-trunk-67.0~a1~hg20190207r457544/browser/base/content/browser.css firefox-trunk-67.0~a1~hg20190209r458331/browser/base/content/browser.css --- firefox-trunk-67.0~a1~hg20190207r457544/browser/base/content/browser.css 2019-02-07 12:50:25.000000000 +0000 +++ firefox-trunk-67.0~a1~hg20190209r458331/browser/base/content/browser.css 2019-02-09 08:54:08.000000000 +0000 @@ -301,8 +301,8 @@ %ifdef MENUBAR_CAN_AUTOHIDE -#toolbar-menubar:not([autohide=true]) + #TabsToolbar > .titlebar-buttonbox-container, -#toolbar-menubar:not([autohide=true]) + #TabsToolbar .titlebar-spacer, +:root:not([chromehidden~="menubar"]) #toolbar-menubar:not([autohide=true]) + #TabsToolbar > .titlebar-buttonbox-container, +:root:not([chromehidden~="menubar"]) #toolbar-menubar:not([autohide=true]) + #TabsToolbar .titlebar-spacer, %endif %ifndef MOZ_WIDGET_COCOA %ifndef MOZ_WIDGET_GTK @@ -780,10 +780,7 @@ #identity-box.chromeUI ~ #page-action-buttons > .urlbar-page-action:not(#star-button-box), .urlbar-history-dropmarker[usertyping], .urlbar-go-button:not([usertyping]), -.urlbar-go-button:not([parentfocused="true"]), -#urlbar[pageproxystate="invalid"] > #identity-box > #blocked-permissions-container, -#urlbar[pageproxystate="invalid"] > #identity-box > #notification-popup-box, -#urlbar[pageproxystate="invalid"] > #identity-box > #identity-icon-labels { +.urlbar-go-button:not([parentfocused="true"]) { display: none; } @@ -791,12 +788,6 @@ -moz-user-focus: normal; } -#urlbar[pageproxystate="invalid"] > #identity-box { - pointer-events: none; - -moz-user-focus: ignore; -} - - /* We leave 49ch plus whatever space the download button will need when it * appears. Normally this should be 16px for the icon, plus 2 * 2px padding * plus the toolbarbutton-inner-padding. We're adding 4px to ensure things @@ -1016,10 +1007,6 @@ -moz-stack-sizing: ignore; } -#addon-progress-notification { - -moz-binding: url("chrome://browser/content/urlbarBindings.xml#addon-progress-notification"); -} - browser[tabmodalPromptShowing] { -moz-user-focus: none !important; } diff -Nru firefox-trunk-67.0~a1~hg20190207r457544/browser/base/content/browser.js firefox-trunk-67.0~a1~hg20190209r458331/browser/base/content/browser.js --- firefox-trunk-67.0~a1~hg20190207r457544/browser/base/content/browser.js 2019-02-07 12:50:25.000000000 +0000 +++ firefox-trunk-67.0~a1~hg20190209r458331/browser/base/content/browser.js 2019-02-09 08:54:08.000000000 +0000 @@ -12,6 +12,7 @@ XPCOMUtils.defineLazyModuleGetters(this, { AddonManager: "resource://gre/modules/AddonManager.jsm", + AMTelemetry: "resource://gre/modules/AddonManager.jsm", BrowserUsageTelemetry: "resource:///modules/BrowserUsageTelemetry.jsm", BrowserUtils: "resource://gre/modules/BrowserUtils.jsm", BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm", @@ -23,6 +24,7 @@ CustomizableUI: "resource:///modules/CustomizableUI.jsm", Deprecated: "resource://gre/modules/Deprecated.jsm", DownloadsCommon: "resource:///modules/DownloadsCommon.jsm", + DownloadUtils: "resource://gre/modules/DownloadUtils.jsm", E10SUtils: "resource://gre/modules/E10SUtils.jsm", ExtensionsUI: "resource:///modules/ExtensionsUI.jsm", FormValidationHandler: "resource:///modules/FormValidationHandler.jsm", @@ -1033,12 +1035,6 @@ // A shared function used by both remote and non-remote browser XBL bindings to // load a URI or redirect it to the correct process. function _loadURI(browser, uri, params = {}) { - let tab = gBrowser.getTabForBrowser(browser); - // Preloaded browsers don't have tabs, so we ignore those. - if (tab) { - maybeRecordAbandonmentTelemetry(tab, "newURI"); - } - if (!uri) { uri = "about:blank"; } @@ -2047,16 +2043,6 @@ evt.preventDefault(); } -function maybeRecordAbandonmentTelemetry(tab, type) { - if (!tab.hasAttribute("busy")) { - return; - } - - let histogram = Services.telemetry - .getHistogramById("BUSY_TAB_ABANDONED"); - histogram.add(type); -} - function gotoHistoryIndex(aEvent) { let index = aEvent.target.getAttribute("index"); if (!index) @@ -2068,8 +2054,6 @@ // Normal click. Go there in the current tab and update session history. try { - maybeRecordAbandonmentTelemetry(gBrowser.selectedTab, - "historyNavigation"); gBrowser.gotoIndex(index); } catch (ex) { return false; @@ -2088,7 +2072,6 @@ if (where == "current") { try { - maybeRecordAbandonmentTelemetry(gBrowser.selectedTab, "forward"); gBrowser.goForward(); } catch (ex) { } @@ -2102,7 +2085,6 @@ if (where == "current") { try { - maybeRecordAbandonmentTelemetry(gBrowser.selectedTab, "back"); gBrowser.goBack(); } catch (ex) { } @@ -2134,7 +2116,6 @@ } function BrowserStop() { - maybeRecordAbandonmentTelemetry(gBrowser.selectedTab, "stop"); gBrowser.webNavigation.stop(Ci.nsIWebNavigation.STOP_ALL); } @@ -3263,14 +3244,6 @@ return; } - // Do this after the above case where we might flip remoteness. - // Unfortunately, we'll count the remoteness flip case as a - // "newURL" load, since we're using loadURI, but hopefully - // that's rare enough to not matter. - for (let tab of unchangedRemoteness) { - maybeRecordAbandonmentTelemetry(tab, "reload"); - } - // Reset temporary permissions on the remaining tabs to reload. // This is done here because we only want to reset // permissions on user reload. @@ -6373,6 +6346,12 @@ let btnFlags = BUTTON_POS_0 * titleString + BUTTON_POS_1 * titleCancel; let response = confirmEx(null, title, message, btnFlags, btnTitle, null, null, null, {value: 0}); + AMTelemetry.recordActionEvent({ + object: "browserAction", + action: "uninstall", + value: response ? "cancelled" : "accepted", + extra: {addonId: addon.id}, + }); if (response == 0) { addon.uninstall(); } @@ -6383,6 +6362,11 @@ if (id) { let viewID = "addons://detail/" + encodeURIComponent(id); BrowserOpenAddonsMgr(viewID); + AMTelemetry.recordActionEvent({ + object: "browserAction", + action: "manage", + extra: {addonId: id}, + }); } }, }; diff -Nru firefox-trunk-67.0~a1~hg20190207r457544/browser/base/content/browser-pageActions.js firefox-trunk-67.0~a1~hg20190209r458331/browser/base/content/browser-pageActions.js --- firefox-trunk-67.0~a1~hg20190207r457544/browser/base/content/browser-pageActions.js 2019-02-07 12:50:25.000000000 +0000 +++ firefox-trunk-67.0~a1~hg20190209r458331/browser/base/content/browser-pageActions.js 2019-02-09 08:54:08.000000000 +0000 @@ -875,6 +875,11 @@ this._contextAction = null; PageActions.logTelemetry("managed", action); + AMTelemetry.recordActionEvent({ + object: "pageAction", + action: "manage", + extra: {addonId: action.extensionID}, + }); let viewID = "addons://detail/" + encodeURIComponent(action.extensionID); window.BrowserOpenAddonsMgr(viewID); @@ -1194,7 +1199,7 @@ showBrowserPageActionFeedback(this.action); }, errorCode => { - if (errorCode != Ci.nsISearchInstallCallback.ERROR_DUPLICATE_ENGINE) { + if (errorCode != Ci.nsISearchService.ERROR_DUPLICATE_ENGINE) { // Download error is shown by the search service return; } diff -Nru firefox-trunk-67.0~a1~hg20190207r457544/browser/base/content/browser-siteIdentity.js firefox-trunk-67.0~a1~hg20190209r458331/browser/base/content/browser-siteIdentity.js --- firefox-trunk-67.0~a1~hg20190207r457544/browser/base/content/browser-siteIdentity.js 2019-02-07 12:50:25.000000000 +0000 +++ firefox-trunk-67.0~a1~hg20190209r458331/browser/base/content/browser-siteIdentity.js 2019-02-09 08:54:08.000000000 +0000 @@ -273,7 +273,9 @@ recordClick(object) { let extra = {}; for (let blocker of ContentBlocking.blockers) { - extra[blocker.telemetryIdentifier] = blocker.activated ? "true" : "false"; + if (blocker.telemetryIdentifier) { + extra[blocker.telemetryIdentifier] = blocker.activated ? "true" : "false"; + } } Services.telemetry.recordEvent("security.ui.identitypopup", "click", object, null, extra); }, @@ -869,7 +871,9 @@ let extra = {}; for (let blocker of ContentBlocking.blockers) { - extra[blocker.telemetryIdentifier] = blocker.activated ? "true" : "false"; + if (blocker.telemetryIdentifier) { + extra[blocker.telemetryIdentifier] = blocker.activated ? "true" : "false"; + } } let shieldStatus = ContentBlocking.iconBox.hasAttribute("active") ? "shield-showing" : "shield-hidden"; diff -Nru firefox-trunk-67.0~a1~hg20190207r457544/browser/base/content/content.js firefox-trunk-67.0~a1~hg20190209r458331/browser/base/content/content.js --- firefox-trunk-67.0~a1~hg20190207r457544/browser/base/content/content.js 2019-02-07 12:50:25.000000000 +0000 +++ firefox-trunk-67.0~a1~hg20190209r458331/browser/base/content/content.js 2019-02-09 08:54:08.000000000 +0000 @@ -61,7 +61,7 @@ if (shouldIgnoreLoginManagerEvent(event)) { return; } - LoginManagerContent.onUsernameInput(event); + LoginManagerContent.onDOMAutoComplete(event); }); ContentMetaHandler.init(this); diff -Nru firefox-trunk-67.0~a1~hg20190207r457544/browser/base/content/popup-notifications.inc firefox-trunk-67.0~a1~hg20190209r458331/browser/base/content/popup-notifications.inc --- firefox-trunk-67.0~a1~hg20190207r457544/browser/base/content/popup-notifications.inc 2019-02-07 12:50:25.000000000 +0000 +++ firefox-trunk-67.0~a1~hg20190209r458331/browser/base/content/popup-notifications.inc 2019-02-09 08:54:08.000000000 +0000 @@ -61,7 +61,7 @@ -