Merge inbound to mozilla-central. a=merge

This commit is contained in:
Noemi Erli 2018-02-13 11:39:36 +02:00
commit d03ad8843e
303 changed files with 2311 additions and 1020 deletions

View File

@ -32,8 +32,6 @@ ARIAGridAccessible::
{
}
NS_IMPL_ISUPPORTS_INHERITED0(ARIAGridAccessible, Accessible)
////////////////////////////////////////////////////////////////////////////////
// Table
@ -543,8 +541,6 @@ ARIARowAccessible::
mGenericTypes |= eTableRow;
}
NS_IMPL_ISUPPORTS_INHERITED0(ARIARowAccessible, Accessible)
GroupPos
ARIARowAccessible::GroupPosition()
{
@ -575,8 +571,6 @@ ARIAGridCellAccessible::
mGenericTypes |= eTableCell;
}
NS_IMPL_ISUPPORTS_INHERITED0(ARIAGridCellAccessible, HyperTextAccessible)
////////////////////////////////////////////////////////////////////////////////
// TableCell

View File

@ -22,7 +22,7 @@ class ARIAGridAccessible : public AccessibleWrap,
public:
ARIAGridAccessible(nsIContent* aContent, DocAccessible* aDoc);
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(ARIAGridAccessible, AccessibleWrap)
// Accessible
virtual TableAccessible* AsTable() override { return this; }
@ -81,7 +81,7 @@ class ARIARowAccessible : public AccessibleWrap
public:
ARIARowAccessible(nsIContent* aContent, DocAccessible* aDoc);
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(ARIARowAccessible, AccessibleWrap)
// Accessible
virtual mozilla::a11y::GroupPos GroupPosition() override;
@ -100,7 +100,8 @@ class ARIAGridCellAccessible : public HyperTextAccessibleWrap,
public:
ARIAGridCellAccessible(nsIContent* aContent, DocAccessible* aDoc);
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(ARIAGridCellAccessible,
HyperTextAccessibleWrap)
// Accessible
virtual TableCellAccessible* AsTableCell() override { return this; }

View File

@ -31,8 +31,6 @@ ApplicationAccessible::ApplicationAccessible() :
MOZ_ASSERT(mAppInfo, "no application info");
}
NS_IMPL_ISUPPORTS_INHERITED0(ApplicationAccessible, Accessible)
////////////////////////////////////////////////////////////////////////////////
// nsIAccessible

View File

@ -32,7 +32,7 @@ public:
ApplicationAccessible();
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(ApplicationAccessible, AccessibleWrap)
// Accessible
virtual void Shutdown() override;

View File

@ -27,8 +27,6 @@ LeafAccessible::
mStateFlags |= eNoKidsFromDOM;
}
NS_IMPL_ISUPPORTS_INHERITED0(LeafAccessible, Accessible)
////////////////////////////////////////////////////////////////////////////////
// LeafAccessible: Accessible public
@ -66,8 +64,6 @@ LeafAccessible::IsAcceptableChild(nsIContent* aEl) const
// LinkableAccessible
////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS_INHERITED0(LinkableAccessible, AccessibleWrap)
////////////////////////////////////////////////////////////////////////////////
// LinkableAccessible. nsIAccessible

View File

@ -30,7 +30,7 @@ public:
LeafAccessible(nsIContent* aContent, DocAccessible* aDoc);
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(LeafAccessible, AccessibleWrap)
// Accessible
virtual Accessible* ChildAtPoint(int32_t aX, int32_t aY,
@ -60,7 +60,7 @@ public:
{
}
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(LinkableAccessible, AccessibleWrap)
// Accessible
virtual void Value(nsString& aValue) override;

View File

@ -56,8 +56,6 @@ HyperTextAccessible::
mGenericTypes |= eHyperText;
}
NS_IMPL_ISUPPORTS_INHERITED0(HyperTextAccessible, Accessible)
role
HyperTextAccessible::NativeRole()
{

View File

@ -51,7 +51,7 @@ class HyperTextAccessible : public AccessibleWrap
public:
HyperTextAccessible(nsIContent* aContent, DocAccessible* aDoc);
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(HyperTextAccessible, AccessibleWrap)
// Accessible
virtual nsAtom* LandmarkRole() const override;

View File

@ -50,12 +50,6 @@ OuterDocAccessible::~OuterDocAccessible()
{
}
////////////////////////////////////////////////////////////////////////////////
// nsISupports
NS_IMPL_ISUPPORTS_INHERITED0(OuterDocAccessible,
Accessible)
////////////////////////////////////////////////////////////////////////////////
// Accessible public (DON'T add methods here)

View File

@ -26,7 +26,7 @@ class OuterDocAccessible final : public AccessibleWrap
public:
OuterDocAccessible(nsIContent* aContent, DocAccessible* aDoc);
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(OuterDocAccessible, AccessibleWrap)
DocAccessibleParent* RemoteChildDoc() const;

View File

@ -52,7 +52,7 @@ using namespace mozilla::dom;
////////////////////////////////////////////////////////////////////////////////
// nsISupports
NS_IMPL_ISUPPORTS_INHERITED0(RootAccessible, DocAccessible)
NS_IMPL_ISUPPORTS_INHERITED(RootAccessible, DocAccessible, nsIDOMEventListener)
////////////////////////////////////////////////////////////////////////////////
// Constructor/destructor

View File

@ -15,8 +15,6 @@ HTMLCanvasAccessible::
{
}
NS_IMPL_ISUPPORTS_INHERITED0(HTMLCanvasAccessible, HyperTextAccessible)
role
HTMLCanvasAccessible::NativeRole()
{

View File

@ -20,7 +20,8 @@ public:
HTMLCanvasAccessible(nsIContent* aContent, DocAccessible* aDoc);
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLCanvasAccessible,
HyperTextAccessibleWrap)
// Accessible
virtual a11y::role NativeRole() override;

View File

@ -56,8 +56,6 @@ HTMLBRAccessible::NativeName(nsString& aName)
// HTMLLabelAccessible
////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS_INHERITED0(HTMLLabelAccessible, HyperTextAccessible)
ENameValueFlag
HTMLLabelAccessible::NativeName(nsString& aName)
{
@ -107,8 +105,6 @@ HTMLLabelAccessible::DoAction(uint8_t aIndex)
// nsHTMLOuputAccessible
////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS_INHERITED0(HTMLOutputAccessible, HyperTextAccessible)
Relation
HTMLOutputAccessible::RelationByType(RelationType aType)
{
@ -208,8 +204,6 @@ HTMLSummaryAccessible::IsWidget() const
// HTMLHeaderOrFooterAccessible
////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS_INHERITED0(HTMLHeaderOrFooterAccessible, HyperTextAccessible)
role
HTMLHeaderOrFooterAccessible::NativeRole()
{

View File

@ -57,7 +57,8 @@ public:
HTMLLabelAccessible(nsIContent* aContent, DocAccessible* aDoc) :
HyperTextAccessibleWrap(aContent, aDoc) {}
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLLabelAccessible,
HyperTextAccessibleWrap)
// Accessible
virtual Relation RelationByType(RelationType aType) override;
@ -82,7 +83,8 @@ public:
HTMLOutputAccessible(nsIContent* aContent, DocAccessible* aDoc) :
HyperTextAccessibleWrap(aContent, aDoc) {}
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLOutputAccessible,
HyperTextAccessibleWrap)
// Accessible
virtual Relation RelationByType(RelationType aType) override;
@ -124,7 +126,8 @@ public:
HTMLHeaderOrFooterAccessible(nsIContent* aContent, DocAccessible* aDoc) :
HyperTextAccessibleWrap(aContent, aDoc) {}
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLHeaderOrFooterAccessible,
HyperTextAccessibleWrap)
// Accessible
virtual nsAtom* LandmarkRole() const override;

View File

@ -285,9 +285,6 @@ HTMLTextFieldAccessible::
mType = eHTMLTextFieldType;
}
NS_IMPL_ISUPPORTS_INHERITED0(HTMLTextFieldAccessible,
HyperTextAccessible)
role
HTMLTextFieldAccessible::NativeRole()
{

View File

@ -114,7 +114,8 @@ public:
HTMLTextFieldAccessible(nsIContent* aContent, DocAccessible* aDoc);
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLTextFieldAccessible,
HyperTextAccessibleWrap)
// HyperTextAccessible
virtual already_AddRefed<TextEditor> GetEditor() const override;

View File

@ -33,11 +33,6 @@ HTMLImageMapAccessible::
UpdateChildAreas(false);
}
////////////////////////////////////////////////////////////////////////////////
// HTMLImageMapAccessible: nsISupports
NS_IMPL_ISUPPORTS_INHERITED0(HTMLImageMapAccessible, ImageAccessible)
////////////////////////////////////////////////////////////////////////////////
// HTMLImageMapAccessible: Accessible public

View File

@ -21,7 +21,8 @@ public:
HTMLImageMapAccessible(nsIContent* aContent, DocAccessible* aDoc);
// nsISupports and cycle collector
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLImageMapAccessible,
ImageAccessibleWrap)
// Accessible
virtual a11y::role NativeRole() override;

View File

@ -27,8 +27,6 @@ HTMLLinkAccessible::
{
}
NS_IMPL_ISUPPORTS_INHERITED0(HTMLLinkAccessible, HyperTextAccessible)
////////////////////////////////////////////////////////////////////////////////
// nsIAccessible

View File

@ -16,7 +16,8 @@ class HTMLLinkAccessible : public HyperTextAccessibleWrap
public:
HTMLLinkAccessible(nsIContent* aContent, DocAccessible* aDoc);
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLLinkAccessible,
HyperTextAccessibleWrap)
// Accessible
virtual void Value(nsString& aValue) override;

View File

@ -21,8 +21,6 @@ using namespace mozilla::a11y;
// HTMLListAccessible
////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS_INHERITED0(HTMLListAccessible, HyperTextAccessible)
role
HTMLListAccessible::NativeRole()
{
@ -55,8 +53,6 @@ HTMLLIAccessible::
}
}
NS_IMPL_ISUPPORTS_INHERITED0(HTMLLIAccessible, HyperTextAccessible)
void
HTMLLIAccessible::Shutdown()
{

View File

@ -25,7 +25,8 @@ public:
HyperTextAccessibleWrap(aContent, aDoc) { mGenericTypes |= eList; }
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLListAccessible,
HyperTextAccessibleWrap)
// Accessible
virtual a11y::role NativeRole() override;
@ -45,7 +46,8 @@ public:
HTMLLIAccessible(nsIContent* aContent, DocAccessible* aDoc);
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLLIAccessible,
HyperTextAccessibleWrap)
// Accessible
virtual void Shutdown() override;

View File

@ -52,8 +52,6 @@ HTMLTableCellAccessible::
mGenericTypes |= eTableCell;
}
NS_IMPL_ISUPPORTS_INHERITED0(HTMLTableCellAccessible, HyperTextAccessible)
////////////////////////////////////////////////////////////////////////////////
// HTMLTableCellAccessible: Accessible implementation
@ -357,8 +355,6 @@ HTMLTableHeaderCellAccessible::NativeRole()
// HTMLTableRowAccessible
////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS_INHERITED0(HTMLTableRowAccessible, Accessible)
role
HTMLTableRowAccessible::NativeRole()
{
@ -388,8 +384,6 @@ HTMLTableRowAccessible::GroupPosition()
// HTMLTableAccessible
////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS_INHERITED0(HTMLTableAccessible, Accessible)
////////////////////////////////////////////////////////////////////////////////
// HTMLTableAccessible: Accessible

View File

@ -26,7 +26,8 @@ public:
HTMLTableCellAccessible(nsIContent* aContent, DocAccessible* aDoc);
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLTableCellAccessible,
HyperTextAccessibleWrap)
// Accessible
virtual TableCellAccessible* AsTableCell() override { return this; }
@ -92,7 +93,7 @@ public:
mGenericTypes |= eTableRow;
}
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLTableRowAccessible, AccessibleWrap)
// Accessible
virtual a11y::role NativeRole() override;
@ -123,7 +124,7 @@ public:
mGenericTypes |= eTable;
}
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLTableAccessible, AccessibleWrap)
// TableAccessible
virtual Accessible* Caption() const override;

View File

@ -32,6 +32,8 @@ public:
DECL_IUNKNOWN_INHERITED
// nsISupports
// Need to declare addref/release here unconditionally, because
// ia2AccessibleTable has pure-virtual refcounting.
NS_DECL_ISUPPORTS_INHERITED
virtual void Shutdown() override;
@ -54,6 +56,8 @@ public:
DECL_IUNKNOWN_INHERITED
// nsISupports
// Need to declare addref/release here unconditionally, because
// ia2AccessibleTable has pure-virtual refcounting.
NS_DECL_ISUPPORTS_INHERITED
virtual void Shutdown() override;

View File

@ -26,8 +26,6 @@ XULAlertAccessible::~XULAlertAccessible()
{
}
NS_IMPL_ISUPPORTS_INHERITED0(XULAlertAccessible, Accessible)
role
XULAlertAccessible::NativeRole()
{

View File

@ -20,7 +20,7 @@ class XULAlertAccessible : public AccessibleWrap
public:
XULAlertAccessible(nsIContent* aContent, DocAccessible* aDoc);
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(XULAlertAccessible, AccessibleWrap)
// Accessible
virtual mozilla::a11y::ENameValueFlag Name(nsString& aName) override;

View File

@ -54,8 +54,6 @@ XULButtonAccessible::~XULButtonAccessible()
////////////////////////////////////////////////////////////////////////////////
// XULButtonAccessible: nsISupports
NS_IMPL_ISUPPORTS_INHERITED0(XULButtonAccessible, Accessible)
////////////////////////////////////////////////////////////////////////////////
// XULButtonAccessible: nsIAccessible

View File

@ -33,7 +33,7 @@ public:
XULButtonAccessible(nsIContent* aContent, DocAccessible* aDoc);
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(XULButtonAccessible, AccessibleWrap)
// Accessible
virtual mozilla::a11y::role NativeRole() override;

View File

@ -551,8 +551,6 @@ XULListitemAccessible::~XULListitemAccessible()
{
}
NS_IMPL_ISUPPORTS_INHERITED0(XULListitemAccessible, Accessible)
Accessible*
XULListitemAccessible::GetListAccessible() const
{
@ -693,9 +691,6 @@ XULListCellAccessible::
////////////////////////////////////////////////////////////////////////////////
// nsISupports
NS_IMPL_ISUPPORTS_INHERITED0(XULListCellAccessible,
HyperTextAccessible)
////////////////////////////////////////////////////////////////////////////////
// XULListCellAccessible: TableCell

View File

@ -106,7 +106,8 @@ class XULListitemAccessible : public XULMenuitemAccessible
public:
enum { eAction_Click = 0 };
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(XULListitemAccessible,
XULMenuitemAccessible)
XULListitemAccessible(nsIContent* aContent, DocAccessible* aDoc);
@ -149,7 +150,8 @@ public:
XULListCellAccessible(nsIContent* aContent, DocAccessible* aDoc);
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(XULListCellAccessible,
HyperTextAccessibleWrap)
// Accessible
virtual TableCellAccessible* AsTableCell() override { return this; }

View File

@ -1746,3 +1746,20 @@ pref("extensions.screenshots.disabled", false);
// Preference that allows individual users to leave Screenshots enabled, but
// disable uploading to the server.
pref("extensions.screenshots.upload-disabled", false);
// Preferences for BrowserErrorReporter.jsm
// Only collect errors on Nightly, and specifically not local builds
#if defined(NIGHTLY_BUILD) && MOZ_UPDATE_CHANNEL != default
pref("browser.chrome.errorReporter.enabled", true);
#else
pref("browser.chrome.errorReporter.enabled", false);
#endif
pref("browser.chrome.errorReporter.sampleRate", "0.001");
pref("browser.chrome.errorReporter.publicKey", "c709cb7a2c0b4f0882fcc84a5af161ec");
pref("browser.chrome.errorReporter.projectId", "339");
pref("browser.chrome.errorReporter.submitUrl", "https://sentry.prod.mozaws.net/api/339/store/");
pref("browser.chrome.errorReporter.logLevel", "Error");
// URL for Learn More link for browser error logging in preferences
pref("browser.chrome.errorReporter.infoURL",
"https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/nightly-error-collection");

View File

@ -88,6 +88,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
AutoCompletePopup: "resource://gre/modules/AutoCompletePopup.jsm",
BookmarkHTMLUtils: "resource://gre/modules/BookmarkHTMLUtils.jsm",
BookmarkJSONUtils: "resource://gre/modules/BookmarkJSONUtils.jsm",
BrowserErrorReporter: "resource:///modules/BrowserErrorReporter.jsm",
BrowserUITelemetry: "resource:///modules/BrowserUITelemetry.jsm",
BrowserUsageTelemetry: "resource:///modules/BrowserUsageTelemetry.jsm",
ContentClick: "resource:///modules/ContentClick.jsm",
@ -355,6 +356,16 @@ BrowserGlue.prototype = {
return this.pingCentre;
},
/**
* Lazily initialize BrowserErrorReporter
*/
get browserErrorReporter() {
Object.defineProperty(this, "browserErrorReporter", {
value: new BrowserErrorReporter(),
});
return this.browserErrorReporter;
},
_sendMainPingCentrePing() {
const ACTIVITY_STREAM_ENABLED_PREF = "browser.newtabpage.activity-stream.enabled";
const ACTIVITY_STREAM_ID = "activity-stream";
@ -1055,6 +1066,11 @@ BrowserGlue.prototype = {
NewTabUtils.uninit();
AutoCompletePopup.uninit();
DateTimePickerHelper.uninit();
// Browser errors are only collected on Nightly
if (AppConstants.NIGHTLY_BUILD && AppConstants.MOZ_DATA_REPORTING) {
this.browserErrorReporter.uninit();
}
},
// All initial windows have opened.
@ -1064,6 +1080,11 @@ BrowserGlue.prototype = {
}
this._windowsWereRestored = true;
// Browser errors are only collected on Nightly
if (AppConstants.NIGHTLY_BUILD && AppConstants.MOZ_DATA_REPORTING) {
this.browserErrorReporter.init();
}
BrowserUsageTelemetry.init();
BrowserUITelemetry.init();

View File

@ -119,6 +119,9 @@ Preferences.addAll([
]);
// Data Choices tab
if (AppConstants.NIGHTLY_BUILD) {
Preferences.add({ id: "browser.chrome.errorCollection.enabled", type: "bool" });
}
if (AppConstants.MOZ_CRASHREPORTER) {
Preferences.add({ id: "browser.crashReports.unsubmittedCheck.autoSubmit2", type: "bool" });
}
@ -410,6 +413,9 @@ var gPrivacyPane = {
if (AppConstants.MOZ_DATA_REPORTING) {
this.initDataCollection();
if (AppConstants.NIGHTLY_BUILD) {
this.initCollectBrowserErrors();
}
if (AppConstants.MOZ_CRASHREPORTER) {
this.initSubmitCrashes();
}
@ -1528,6 +1534,11 @@ var gPrivacyPane = {
"dataCollectionPrivacyNotice");
},
initCollectBrowserErrors() {
this._setupLearnMoreLink("browser.chrome.errorCollection.infoURL",
"collectBrowserErrorsLearnMore");
},
initSubmitCrashes() {
this._setupLearnMoreLink("toolkit.crashreporter.infoURL",
"crashReporterLearnMore");
@ -1538,7 +1549,7 @@ var gPrivacyPane = {
*/
_setupLearnMoreLink(pref, element) {
// set up the Learn More link with the correct URL
let url = Services.prefs.getCharPref(pref);
let url = Services.urlFormatter.formatURLPref(pref);
let el = document.getElementById(element);
if (url) {

View File

@ -586,6 +586,18 @@
<description id="TelemetryDisabledDesc" class="indent tip-caption" control="telemetryGroup">&healthReportingDisabled.label;</description>
#endif
#ifdef NIGHTLY_BUILD
<hbox align="center">
<checkbox id="collectBrowserErrorsBox"
class="tail-with-learn-more"
preference="browser.chrome.errorCollection.enabled"
label="&collectBrowserErrors.label;"
accesskey="&collectBrowserErrors.accesskey;"/>
<label id="collectBrowserErrorsLearnMore"
class="learnMore text-link">&collectBrowserErrorsLearnMore.label;</label>
</hbox>
#endif
#ifdef MOZ_CRASHREPORTER
<hbox align="center">
<checkbox id="automaticallySubmitCrashesBox"

View File

@ -63,6 +63,7 @@ skip-if = !e10s
skip-if = e10s
[browser_permissions_urlFieldHidden.js]
[browser_proxy_backup.js]
[browser_privacypane.js]
[browser_privacypane_1.js]
[browser_privacypane_3.js]
[browser_privacypane_4.js]

View File

@ -0,0 +1,50 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint-disable mozilla/no-cpows-in-tests */
// Test the initial value of Browser Error collection checkbox
add_task(async function testBrowserErrorInitialValue() {
// Skip if non-Nightly since the checkbox will be missing.
if (!AppConstants.NIGHTLY_BUILD) {
return;
}
await SpecialPowers.pushPrefEnv({
set: [["browser.chrome.errorCollection.enabled", true]],
});
await openPreferencesViaOpenPreferencesAPI("privacy-reports", {leaveOpen: true});
let doc = gBrowser.contentDocument;
ok(
doc.querySelector("#collectBrowserErrorsBox").checked,
"Checkbox for collecting browser errors should be checked when the pref is true"
);
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
await SpecialPowers.popPrefEnv();
});
// Test that the Learn More link is set to the correct, formatted URL from a
// pref value
add_task(async function testBrowserErrorLearnMore() {
// Skip if non-Nightly since the checkbox will be missing.
if (!AppConstants.NIGHTLY_BUILD) {
return;
}
await SpecialPowers.pushPrefEnv({
set: [["browser.chrome.errorCollection.infoURL", "https://example.com/%NAME%/"]],
});
await openPreferencesViaOpenPreferencesAPI("privacy-reports", {leaveOpen: true});
let doc = gBrowser.contentDocument;
is(
doc.querySelector("#collectBrowserErrorsLearnMore").href,
`https://example.com/${Services.appinfo.name}/`,
"Learn More link for browser error collection should have an href set by a pref"
);
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
await SpecialPowers.popPrefEnv();
});

View File

@ -37,6 +37,10 @@ available. -->
<!ENTITY dataCollectionDesc.label "We strive to provide you with choices and collect only what we need to provide and improve &brandShortName; for everyone. We always ask permission before receiving personal information.">
<!ENTITY dataCollectionPrivacyNotice.label "Privacy Notice">
<!ENTITY collectBrowserErrors.label "Allow &brandShortName; to send browser error reports (including error messages) to Mozilla">
<!ENTITY collectBrowserErrors.accesskey "b">
<!ENTITY collectBrowserErrorsLearnMore.label "Learn more">
<!ENTITY alwaysSubmitCrashReports1.label "Allow &brandShortName; to send crash reports to Mozilla">
<!ENTITY alwaysSubmitCrashReports1.accesskey "c">
<!ENTITY crashReporterLearnMore.label "Learn more">

View File

@ -0,0 +1,214 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/Timer.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.defineModuleGetter(this, "Log", "resource://gre/modules/Log.jsm");
ChromeUtils.defineModuleGetter(this, "UpdateUtils", "resource://gre/modules/UpdateUtils.jsm");
Cu.importGlobalProperties(["fetch", "URL"]);
this.EXPORTED_SYMBOLS = ["BrowserErrorReporter"];
const ERROR_PREFIX_RE = /^[^\W]+:/m;
const PREF_ENABLED = "browser.chrome.errorReporter.enabled";
const PREF_LOG_LEVEL = "browser.chrome.errorReporter.logLevel";
const PREF_PROJECT_ID = "browser.chrome.errorReporter.projectId";
const PREF_PUBLIC_KEY = "browser.chrome.errorReporter.publicKey";
const PREF_SAMPLE_RATE = "browser.chrome.errorReporter.sampleRate";
const PREF_SUBMIT_URL = "browser.chrome.errorReporter.submitUrl";
// https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIScriptError#Categories
const REPORTED_CATEGORIES = new Set([
"XPConnect JavaScript",
"component javascript",
"chrome javascript",
"chrome registration",
"XBL",
"XBL Prototype Handler",
"XBL Content Sink",
"xbl javascript",
"FrameConstructor",
]);
/**
* Collects nsIScriptError messages logged to the browser console and reports
* them to a remotely-hosted error collection service.
*
* This is a PROTOTYPE; it will be removed in the future and potentially
* replaced with a more robust implementation. It is meant to only collect
* errors from Nightly (and local builds if enabled for development purposes)
* and has not been reviewed for use outside of Nightly.
*
* The outgoing requests are designed to be compatible with version 7 of Sentry.
*/
class BrowserErrorReporter {
constructor(fetchMethod = this._defaultFetch) {
// A fake fetch is passed by the tests to avoid network connections
this.fetch = fetchMethod;
// Values that don't change between error reports.
this.requestBodyTemplate = {
request: {
headers: {
"User-Agent": Services.appShell.hiddenDOMWindow.navigator.userAgent,
},
},
logger: "javascript",
platform: "javascript",
release: Services.appinfo.version,
environment: UpdateUtils.getUpdateChannel(false),
tags: {
appBuildID: Services.appinfo.appBuildID,
changeset: AppConstants.SOURCE_REVISION_URL,
},
};
XPCOMUtils.defineLazyPreferenceGetter(
this,
"collectionEnabled",
PREF_ENABLED,
false,
this.handleEnabledPrefChanged.bind(this),
);
}
/**
* Lazily-created logger
*/
get logger() {
const logger = Log.repository.getLogger("BrowserErrorReporter");
logger.addAppender(new Log.ConsoleAppender(new Log.BasicFormatter()));
logger.manageLevelFromPref(PREF_LOG_LEVEL);
Object.defineProperty(this, "logger", {value: logger});
return this.logger;
}
init() {
if (this.collectionEnabled) {
Services.console.registerListener(this);
// Processing already-logged messages in case any errors occurred before
// startup.
for (const message of Services.console.getMessageArray()) {
this.observe(message);
}
}
}
uninit() {
try {
Services.console.unregisterListener(this);
} catch (err) {} // It probably wasn't registered.
}
handleEnabledPrefChanged(prefName, previousValue, newValue) {
if (newValue) {
Services.console.registerListener(this);
} else {
try {
Services.console.unregisterListener(this);
} catch (err) {} // It probably wasn't registered.
}
}
async observe(message) {
try {
message.QueryInterface(Ci.nsIScriptError);
} catch (err) {
return; // Not an error
}
const isWarning = message.flags & message.warningFlag;
const isFromChrome = REPORTED_CATEGORIES.has(message.category);
if (!isFromChrome || isWarning) {
return;
}
// Sample the amount of errors we send out
const sampleRate = Number.parseFloat(Services.prefs.getCharPref(PREF_SAMPLE_RATE));
if (!Number.isFinite(sampleRate) || (Math.random() >= sampleRate)) {
return;
}
// Parse the error type from the message if present (e.g. "TypeError: Whoops").
let errorMessage = message.errorMessage;
let errorName = "Error";
if (message.errorMessage.match(ERROR_PREFIX_RE)) {
const parts = message.errorMessage.split(":");
errorName = parts[0];
errorMessage = parts.slice(1).join(":").trim();
}
// Pull and normalize stacktrace frames from the message
const frames = [];
let frame = message.stack;
// Avoid an infinite loop by limiting traces to 100 frames.
while (frame && frames.length < 100) {
frames.push({
function: frame.functionDisplayName,
filename: frame.source,
lineno: frame.line,
colno: frame.column,
in_app: true,
});
frame = frame.parent;
}
// Sentry-compatible request body copied from an example generated by Raven.js 3.22.1.
const requestBody = Object.assign({}, this.requestBodyTemplate, {
project: Services.prefs.getCharPref(PREF_PROJECT_ID),
exception: {
values: [
{
type: errorName,
// Error messages may contain PII; see bug 1426482 for privacy
// review and server-side mitigation.
value: errorMessage,
stacktrace: {
frames,
}
},
],
},
culprit: message.sourceName,
});
requestBody.request.url = message.sourceName;
const url = new URL(Services.prefs.getCharPref(PREF_SUBMIT_URL));
url.searchParams.set("sentry_client", "firefox-error-reporter/1.0.0");
url.searchParams.set("sentry_version", "7");
url.searchParams.set("sentry_key", Services.prefs.getCharPref(PREF_PUBLIC_KEY));
try {
await this.fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Accept": "application/json",
},
// Sentry throws an auth error without a referrer specified.
referrer: "https://fake.mozilla.org",
body: JSON.stringify(requestBody)
});
this.logger.debug("Sent error successfully.");
} catch (error) {
this.logger.warn(`Failed to send error: ${error}`);
}
}
async _defaultFetch(...args) {
// Do not make network requests while running in automation
if (Cu.isInAutomation) {
return null;
}
return fetch(...args);
}
}

View File

@ -123,6 +123,7 @@ EXTRA_JS_MODULES += [
'AboutHome.jsm',
'AboutNewTab.jsm',
'AttributionCode.jsm',
'BrowserErrorReporter.jsm',
'BrowserUITelemetry.jsm',
'BrowserUsageTelemetry.jsm',
'ContentClick.jsm',

View File

@ -2,6 +2,9 @@
support-files =
head.js
[browser_BrowserErrorReporter.js]
support-files =
browser_BrowserErrorReporter.html
[browser_BrowserUITelemetry_buckets.js]
skip-if = !e10s # Bug 1373549
[browser_BrowserUITelemetry_defaults.js]

View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test page</title>
</head>
<body>
<script>
// Line and column numbers are significant and used in tests, make sure to
// update the tests if you make any changes to this file!
function madeToFail() {
madeToFail2();
}
function madeToFail2() {
throw new Error("testFetchArguments error");
}
madeToFail();
</script>
</body>
</html>

View File

@ -0,0 +1,387 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
ChromeUtils.import("resource:///modules/BrowserErrorReporter.jsm", this);
/* global sinon */
Services.scriptloader.loadSubScript("resource://testing-common/sinon-2.3.2.js");
registerCleanupFunction(function() {
delete window.sinon;
});
const PREF_ENABLED = "browser.chrome.errorReporter.enabled";
const PREF_PROJECT_ID = "browser.chrome.errorReporter.projectId";
const PREF_PUBLIC_KEY = "browser.chrome.errorReporter.publicKey";
const PREF_SAMPLE_RATE = "browser.chrome.errorReporter.sampleRate";
const PREF_SUBMIT_URL = "browser.chrome.errorReporter.submitUrl";
function createScriptError(options = {}) {
const scriptError = Cc["@mozilla.org/scripterror;1"].createInstance(Ci.nsIScriptError);
scriptError.init(
options.message || "",
options.sourceName || null,
options.sourceLine || null,
options.lineNumber || null,
options.columnNumber || null,
options.flags || Ci.nsIScriptError.errorFlag,
options.category || "chrome javascript",
);
return scriptError;
}
// Wrapper around Services.console.logMessage that waits for the message to be
// logged before resolving, since messages are logged asynchronously.
function logMessage(message) {
return new Promise(resolve => {
Services.console.registerListener({
observe(loggedMessage) {
if (loggedMessage.message === message.message) {
Services.console.unregisterListener(this);
resolve();
}
},
});
Services.console.logMessage(message);
});
}
// Wrapper similar to logMessage, but for logStringMessage.
function logStringMessage(message) {
return new Promise(resolve => {
Services.console.registerListener({
observe(loggedMessage) {
if (loggedMessage.message === message) {
Services.console.unregisterListener(this);
resolve();
}
},
});
Services.console.logStringMessage(message);
});
}
// Finds the fetch spy call for an error with a matching message.
function fetchCallForMessage(fetchSpy, message) {
for (const call of fetchSpy.getCalls()) {
const body = JSON.parse(call.args[1].body);
if (body.exception.values[0].value.includes(message)) {
return call;
}
}
return null;
}
// Helper to test if a fetch spy was called with the given error message.
// Used in tests where unrelated JS errors from other code are logged.
function fetchPassedError(fetchSpy, message) {
return fetchCallForMessage(fetchSpy, message) !== null;
}
add_task(async function testInitPrefDisabled() {
const fetch = sinon.spy();
const reporter = new BrowserErrorReporter(fetch);
await SpecialPowers.pushPrefEnv({set: [
[PREF_ENABLED, false],
[PREF_SAMPLE_RATE, "1.0"],
]});
reporter.init();
await logMessage(createScriptError({message: "Logged while disabled"}));
ok(
!fetchPassedError(fetch, "Logged while disabled"),
"Reporter does not listen for errors if the enabled pref is false.",
);
reporter.uninit();
});
add_task(async function testInitUninitPrefEnabled() {
const fetch = sinon.spy();
const reporter = new BrowserErrorReporter(fetch);
await SpecialPowers.pushPrefEnv({set: [
[PREF_ENABLED, true],
[PREF_SAMPLE_RATE, "1.0"],
]});
reporter.init();
await logMessage(createScriptError({message: "Logged after init"}));
ok(
fetchPassedError(fetch, "Logged after init"),
"Reporter listens for errors if the enabled pref is true.",
);
fetch.reset();
ok(!fetch.called, "Fetch spy was reset.");
reporter.uninit();
await logMessage(createScriptError({message: "Logged after uninit"}));
ok(
!fetchPassedError(fetch, "Logged after uninit"),
"Reporter does not listen for errors after uninit.",
);
});
add_task(async function testInitPastMessages() {
const fetch = sinon.spy();
const reporter = new BrowserErrorReporter(fetch);
await SpecialPowers.pushPrefEnv({set: [
[PREF_ENABLED, true],
[PREF_SAMPLE_RATE, "1.0"],
]});
await logMessage(createScriptError({message: "Logged before init"}));
reporter.init();
ok(
fetchPassedError(fetch, "Logged before init"),
"Reporter collects errors logged before initialization.",
);
reporter.uninit();
});
add_task(async function testEnabledPrefWatcher() {
const fetch = sinon.spy();
const reporter = new BrowserErrorReporter(fetch);
await SpecialPowers.pushPrefEnv({set: [
[PREF_ENABLED, false],
[PREF_SAMPLE_RATE, "1.0"],
]});
reporter.init();
await logMessage(createScriptError({message: "Shouldn't report"}));
ok(
!fetchPassedError(fetch, "Shouldn't report"),
"Reporter does not collect errors if the enable pref is false.",
);
await SpecialPowers.pushPrefEnv({set: [
[PREF_ENABLED, true],
]});
ok(
!fetchPassedError(fetch, "Shouldn't report"),
"Reporter does not collect past-logged errors if it is enabled mid-run.",
);
await logMessage(createScriptError({message: "Should report"}));
ok(
fetchPassedError(fetch, "Should report"),
"Reporter collects errors logged after the enabled pref is turned on mid-run",
);
reporter.uninit();
});
add_task(async function testNonErrorLogs() {
const fetch = sinon.spy();
const reporter = new BrowserErrorReporter(fetch);
await SpecialPowers.pushPrefEnv({set: [
[PREF_ENABLED, true],
[PREF_SAMPLE_RATE, "1.0"],
]});
reporter.init();
await logStringMessage("Not a scripterror instance.");
ok(
!fetchPassedError(fetch, "Not a scripterror instance."),
"Reporter does not collect normal log messages or warnings.",
);
await logMessage(createScriptError({
message: "Warning message",
flags: Ci.nsIScriptError.warningFlag,
}));
ok(
!fetchPassedError(fetch, "Warning message"),
"Reporter does not collect normal log messages or warnings.",
);
await logMessage(createScriptError({
message: "Non-chrome category",
category: "totally from a website",
}));
ok(
!fetchPassedError(fetch, "Non-chrome category"),
"Reporter does not collect normal log messages or warnings.",
);
await logMessage(createScriptError({message: "Is error"}));
ok(
fetchPassedError(fetch, "Is error"),
"Reporter collects error messages.",
);
reporter.uninit();
});
add_task(async function testSampling() {
const fetch = sinon.spy();
const reporter = new BrowserErrorReporter(fetch);
await SpecialPowers.pushPrefEnv({set: [
[PREF_ENABLED, true],
[PREF_SAMPLE_RATE, "1.0"],
]});
reporter.init();
await logMessage(createScriptError({message: "Should log"}));
ok(
fetchPassedError(fetch, "Should log"),
"A 1.0 sample rate will cause the reporter to always collect errors.",
);
await SpecialPowers.pushPrefEnv({set: [
[PREF_SAMPLE_RATE, "0.0"],
]});
await logMessage(createScriptError({message: "Shouldn't log"}));
ok(
!fetchPassedError(fetch, "Shouldn't log"),
"A 0.0 sample rate will cause the reporter to never collect errors.",
);
await SpecialPowers.pushPrefEnv({set: [
[PREF_SAMPLE_RATE, ")fasdf"],
]});
await logMessage(createScriptError({message: "Also shouldn't log"}));
ok(
!fetchPassedError(fetch, "Also shouldn't log"),
"An invalid sample rate will cause the reporter to never collect errors.",
);
});
add_task(async function testNameMessage() {
const fetch = sinon.spy();
const reporter = new BrowserErrorReporter(fetch);
await SpecialPowers.pushPrefEnv({set: [
[PREF_ENABLED, true],
[PREF_SAMPLE_RATE, "1.0"],
]});
reporter.init();
await logMessage(createScriptError({message: "No name"}));
let call = fetchCallForMessage(fetch, "No name");
let body = JSON.parse(call.args[1].body);
is(
body.exception.values[0].type,
"Error",
"Reporter uses a generic type when no name is in the message.",
);
is(
body.exception.values[0].value,
"No name",
"Reporter uses error message as the exception value.",
);
await logMessage(createScriptError({message: "FooError: Has name"}));
call = fetchCallForMessage(fetch, "Has name");
body = JSON.parse(call.args[1].body);
is(
body.exception.values[0].type,
"FooError",
"Reporter uses the error type from the message.",
);
is(
body.exception.values[0].value,
"Has name",
"Reporter uses error message as the value parameter.",
);
await logMessage(createScriptError({message: "FooError: Has :extra: colons"}));
call = fetchCallForMessage(fetch, "Has :extra: colons");
body = JSON.parse(call.args[1].body);
is(
body.exception.values[0].type,
"FooError",
"Reporter uses the error type from the message.",
);
is(
body.exception.values[0].value,
"Has :extra: colons",
"Reporter uses error message as the value parameter.",
);
reporter.uninit();
});
add_task(async function testFetchArguments() {
const fetch = sinon.spy();
const reporter = new BrowserErrorReporter(fetch);
await SpecialPowers.pushPrefEnv({set: [
[PREF_ENABLED, true],
[PREF_SAMPLE_RATE, "1.0"],
[PREF_PROJECT_ID, "123"],
[PREF_PUBLIC_KEY, "foobar"],
[PREF_SUBMIT_URL, "https://errors.example.com/api/123/store/"],
]});
reporter.init();
const testPageUrl = (
"chrome://mochitests/content/browser/browser/modules/test/browser/" +
"browser_BrowserErrorReporter.html"
);
const errorRaisedPromise = new Promise(resolve => {
Services.console.registerListener({
observe(loggedMessage) {
if (loggedMessage.message.toString().includes("testFetchArguments error")) {
Services.console.unregisterListener(this);
resolve();
}
},
});
});
SimpleTest.expectUncaughtException();
await BrowserTestUtils.withNewTab(testPageUrl, async () => {
await errorRaisedPromise;
const call = fetchCallForMessage(fetch, "testFetchArguments error");
const body = JSON.parse(call.args[1].body);
const url = new URL(call.args[0]);
is(url.origin, "https://errors.example.com", "Reporter builds API url from DSN pref.");
is(url.pathname, "/api/123/store/", "Reporter builds API url from DSN pref.");
is(
url.searchParams.get("sentry_client"),
"firefox-error-reporter/1.0.0",
"Reporter identifies itself in the outgoing request",
);
is(url.searchParams.get("sentry_version"), "7", "Reporter is compatible with Sentry 7.");
is(url.searchParams.get("sentry_key"), "foobar", "Reporter pulls API key from DSN pref.");
is(body.project, "123", "Reporter pulls project ID from DSN pref.");
is(call.args[1].referrer, "https://fake.mozilla.org", "Reporter uses a fake referer.");
Assert.deepEqual(
body.exception,
{
values: [
{
type: "Error",
value: "testFetchArguments error",
stacktrace: {
frames: [
{
function: "madeToFail2",
filename: testPageUrl,
lineno: 15,
colno: 15,
in_app: true,
},
{
function: "madeToFail",
filename: testPageUrl,
lineno: 12,
colno: 9,
in_app: true,
},
{
function: null,
filename: testPageUrl,
lineno: 17,
colno: 7,
in_app: true,
}
]
}
}
]
},
"Reporter builds stack trace from scriptError correctly.",
);
});
});

View File

@ -1171,7 +1171,28 @@ StackFrames.prototype = {
Parser.reflectionAPI.parse(aString);
return aString; // Watch expression can be executed safely.
} catch (e) {
return "\"" + e.name + ": " + e.message + "\""; // Syntax error.
function safelyEscape(aString) {
// Convert `str`, a string, to JSON -- that is, to a string beginning
// and ending with double-quotes, followed by string contents escaped
// such that the overall string contents are a JSON string literal.
let str = JSON.stringify(aString);
// Remove the leading and trailing double-quotes.
str = str.substring(1, str.length - 1);
// JSON string literals are not a subset of JS string literals in this
// one weird case: JSON string literals can directly contain U+2028
// LINE SEPARATOR and U+2029 PARAGRAPH SEPARATOR. Replace these code
// points with escaped forms.
str = str.replace(/\u2028/g, "\\u2028");
str = str.replace(/\u2029/g, "\\u2029");
return str;
}
return "\"" +
safelyEscape(e.name) + ": " +
safelyEscape(e.message) +
"\""; // Syntax error.
}
});

View File

@ -38,38 +38,77 @@ function test() {
});
});
let totalExpressionsAdded = 0;
function addExpressions() {
function addExpression(aExpression) {
gWatch.addExpression(aExpression);
++totalExpressionsAdded;
}
is(totalExpressionsAdded, 0, "addExpressions must only be called once");
// The order in which expressions are added here almost doesn't matter for
// this test's purposes. (Excepting only the position of the final test.)
// Use the same order as in `checkWatchExpressions` for simplicity.
addExpression("'a'");
addExpression("\"a\"");
addExpression("'a\"\"'");
addExpression("\"a''\"");
addExpression("?");
addExpression("a");
addExpression("this");
addExpression("this.canada");
addExpression("[1, 2, 3]");
addExpression("x = [1, 2, 3]");
addExpression("y = [1, 2, 3]; y.test = 4");
addExpression("z = [1, 2, 3]; z.test = 4; z");
addExpression("t = [1, 2, 3]; t.test = 4; !t");
addExpression("arguments[0]");
addExpression("encodeURI(\"\\\")");
addExpression("decodeURI(\"\\\")");
addExpression("decodeURIComponent(\"%\")");
addExpression("//");
addExpression("// 42");
addExpression("{}.foo");
addExpression("{}.foo()");
addExpression("({}).foo()");
addExpression("new Array(-1)");
addExpression("4.2.toExponential(-4.2)");
addExpression("throw new Error(\"bazinga\")");
addExpression("({ get error() { throw new Error(\"bazinga\") } }).error");
// https://bugzilla.mozilla.org/show_bug.cgi?id=1205353
// BZ#1205353 - wrong result for string replace with backslash-dollar.
gWatch.addExpression("'$$$'.replace(/\\$/, 'foo')");
gWatch.addExpression("'a'");
gWatch.addExpression("\"a\"");
gWatch.addExpression("'a\"\"'");
gWatch.addExpression("\"a''\"");
gWatch.addExpression("?");
gWatch.addExpression("a");
gWatch.addExpression("this");
gWatch.addExpression("this.canada");
gWatch.addExpression("[1, 2, 3]");
gWatch.addExpression("x = [1, 2, 3]");
gWatch.addExpression("y = [1, 2, 3]; y.test = 4");
gWatch.addExpression("z = [1, 2, 3]; z.test = 4; z");
gWatch.addExpression("t = [1, 2, 3]; t.test = 4; !t");
gWatch.addExpression("arguments[0]");
gWatch.addExpression("encodeURI(\"\\\")");
gWatch.addExpression("decodeURI(\"\\\")");
gWatch.addExpression("decodeURIComponent(\"%\")");
gWatch.addExpression("//");
gWatch.addExpression("// 42");
gWatch.addExpression("{}.foo");
gWatch.addExpression("{}.foo()");
gWatch.addExpression("({}).foo()");
gWatch.addExpression("new Array(-1)");
gWatch.addExpression("4.2.toExponential(-4.2)");
gWatch.addExpression("throw new Error(\"bazinga\")");
gWatch.addExpression("({ get error() { throw new Error(\"bazinga\") } }).error");
gWatch.addExpression("throw { get name() { throw \"bazinga\" } }");
addExpression("'$$$'.replace(/\\$/, 'foo')");
// Functions with parameters that aren't just a simple series of names can't
// be made strict mode code by adding 'use strict'. The resulting syntax
// error message currently contains U+022 QUOTATION MARK characters that
// DebuggerController.StackFrames.syncWatchExpressions at one time
// mishandled: test that handling here.
addExpression("function x(a = 3) { 'use strict'; } 'NOT EVALUATED'");
addExpression("function y(...b) { 'use strict'; } 'NOT EVALUATED'");
addExpression("function z([]) { 'use strict'; } 'NOT EVALUATED'");
addExpression("function w({}) { 'use strict'; } 'NOT EVALUATED'");
// Add a working expression to verify that earlier failing expressions don't
// halt stuff.
addExpression("42");
// For the moment, this watch-expression must be last: by throwing an object
// with a .name that throws, it (intentionally?) mucks with the mini-script
// consed up in DebuggerController.StackFrames.syncWatchExpressions for
// eventual evaluation, and subsequent `addExpression` calls will have no
// effect.
//
// This watch-expression appears initially to be added as a hidden
// expression -- but at first breakpoint it appears to be silently removed,
// hence the `totalExpressionsAdded - 1` in test1 (with lingering effects on
// the rest of this test).
addExpression("throw { get name() { throw \"bazinga\" } }");
is(totalExpressionsAdded, 33, "handy-dandy count-verifying assertion");
}
function performTest() {
@ -77,8 +116,8 @@ function test() {
is(gDebugger.document.querySelectorAll(".dbg-expression[hidden=true]").length, 0,
"There should be 0 hidden nodes in the watch expressions container");
is(gDebugger.document.querySelectorAll(".dbg-expression:not([hidden=true])").length, 28,
"There should be 28 visible nodes in the watch expressions container");
is(gDebugger.document.querySelectorAll(".dbg-expression:not([hidden=true])").length, totalExpressionsAdded,
"There should be " + totalExpressionsAdded + " visible nodes in the watch expressions container");
test1(function () {
test2(function () {
@ -106,13 +145,13 @@ function test() {
function finishTest() {
is(gDebugger.document.querySelectorAll(".dbg-expression[hidden=true]").length, 0,
"There should be 0 hidden nodes in the watch expressions container");
is(gDebugger.document.querySelectorAll(".dbg-expression:not([hidden=true])").length, 28,
"There should be 28 visible nodes in the watch expressions container");
is(gDebugger.document.querySelectorAll(".dbg-expression:not([hidden=true])").length, totalExpressionsAdded,
"There should be " + totalExpressionsAdded + " visible nodes in the watch expressions container");
}
function test1(aCallback) {
gDebugger.once(gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS, () => {
checkWatchExpressions(27, {
checkWatchExpressions(totalExpressionsAdded - 1, {
a: "ReferenceError: a is not defined",
this: { type: "object", class: "Object" },
prop: { type: "object", class: "String" },
@ -126,7 +165,7 @@ function test() {
function test2(aCallback) {
gDebugger.once(gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS, () => {
checkWatchExpressions(27, {
checkWatchExpressions(totalExpressionsAdded - 1, {
a: { type: "undefined" },
this: { type: "object", class: "Window" },
prop: { type: "undefined" },
@ -142,7 +181,7 @@ function test() {
function test3(aCallback) {
gDebugger.once(gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS, () => {
checkWatchExpressions(27, {
checkWatchExpressions(totalExpressionsAdded - 1, {
a: { type: "object", class: "Object" },
this: { type: "object", class: "Window" },
prop: { type: "undefined" },
@ -158,7 +197,7 @@ function test() {
function test4(aCallback) {
gDebugger.once(gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS, () => {
checkWatchExpressions(28, {
checkWatchExpressions(totalExpressionsAdded, {
a: 5,
this: { type: "object", class: "Window" },
prop: { type: "undefined" },
@ -173,7 +212,7 @@ function test() {
function test5(aCallback) {
gDebugger.once(gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS, () => {
checkWatchExpressions(28, {
checkWatchExpressions(totalExpressionsAdded, {
a: 5,
this: { type: "object", class: "Window" },
prop: { type: "undefined" },
@ -188,7 +227,7 @@ function test() {
function test6(aCallback) {
gDebugger.once(gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS, () => {
checkWatchExpressions(28, {
checkWatchExpressions(totalExpressionsAdded, {
a: 5,
this: { type: "object", class: "Window" },
prop: { type: "undefined" },
@ -203,7 +242,7 @@ function test() {
function test7(aCallback) {
gDebugger.once(gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS, () => {
checkWatchExpressions(28, {
checkWatchExpressions(totalExpressionsAdded, {
a: 5,
this: { type: "object", class: "Window" },
prop: { type: "undefined" },
@ -218,7 +257,7 @@ function test() {
function test8(aCallback) {
gDebugger.once(gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS, () => {
checkWatchExpressions(28, {
checkWatchExpressions(totalExpressionsAdded, {
a: 5,
this: { type: "object", class: "Window" },
prop: { type: "undefined" },
@ -257,8 +296,8 @@ function test() {
let label = gDebugger.L10N.getStr("watchExpressionsScopeLabel");
let scope = gVariables._currHierarchy.get(label);
ok(scope, "There should be a wach expressions scope in the variables view.");
is(scope._store.size, aTotal, "There should be " + aTotal + " evaluations availalble.");
ok(scope, "There should be a watch expressions scope in the variables view.");
is(scope._store.size, aTotal, "There should be " + aTotal + " evaluations available.");
let w1 = scope.get("'a'");
let w2 = scope.get("\"a\"");
@ -286,8 +325,16 @@ function test() {
let w24 = scope.get("4.2.toExponential(-4.2)");
let w25 = scope.get("throw new Error(\"bazinga\")");
let w26 = scope.get("({ get error() { throw new Error(\"bazinga\") } }).error");
let w27 = scope.get("throw { get name() { throw \"bazinga\" } }");
let w28 = scope.get("'$$$'.replace(/\\$/, 'foo')");
let w27 = scope.get("'$$$'.replace(/\\$/, 'foo')");
let w28 = scope.get("function x(a = 3) { 'use strict'; } 'NOT EVALUATED'");
let w29 = scope.get("function y(...b) { 'use strict'; } 'NOT EVALUATED'");
let w30 = scope.get("function z([]) { 'use strict'; } 'NOT EVALUATED'");
let w31 = scope.get("function w({}) { 'use strict'; } 'NOT EVALUATED'");
let w32 = scope.get("42");
// This doesn't *have* to be last -- these could be in any order -- but keep
// it last for consistency with `addExpressions`.
let w33 = scope.get("throw { get name() { throw \"bazinga\" } }");
ok(w1, "The first watch expression should be present in the scope.");
ok(w2, "The second watch expression should be present in the scope.");
@ -315,8 +362,15 @@ function test() {
ok(w24, "The 24th watch expression should be present in the scope.");
ok(w25, "The 25th watch expression should be present in the scope.");
ok(w26, "The 26th watch expression should be present in the scope.");
ok(!w27, "The 27th watch expression should not be present in the scope.");
ok(w27, "The 27th watch expression should be present in the scope.");
ok(w28, "The 28th watch expression should be present in the scope.");
ok(w29, "The 29th watch expression should be present in the scope.");
ok(w30, "The 30th watch expression should be present in the scope.");
ok(w31, "The 31st watch expression should be present in the scope.");
ok(w32, "The 32nd watch expression should be present in the scope.");
// Keep this last for consistency with `addExpressions`.
ok(!w33, "The 33rd watch expression should not be present in the scope.");
is(w1.value, "a", "The first value is correct.");
is(w2.value, "a", "The second value is correct.");
@ -361,8 +415,8 @@ function test() {
is(w14.value, expected_args, "The 14th value is correct.");
}
is(w15.value, "SyntaxError: unterminated string literal", "The 15th value is correct.");
is(w16.value, "SyntaxError: unterminated string literal", "The 16th value is correct.");
is(w15.value, "SyntaxError: \"\" literal not terminated before end of script", "The 15th value is correct.");
is(w16.value, "SyntaxError: \"\" literal not terminated before end of script", "The 16th value is correct.");
is(w17.value, "URIError: malformed URI sequence", "The 17th value is correct.");
is(w18.value.type, "undefined", "The 18th value type is correct.");
@ -378,6 +432,17 @@ function test() {
is(w24.value, "RangeError: precision -4 out of range", "The 24th value is correct.");
is(w25.value, "Error: bazinga", "The 25th value is correct.");
is(w26.value, "Error: bazinga", "The 26th value is correct.");
is(w28.value, "foo$$", "The 28th value is correct.");
is(w27.value, "foo$$", "The 27th value is correct.");
is(w28.value, "SyntaxError: \"use strict\" not allowed in function with default parameter",
"The 29th value is correct.");
is(w29.value, "SyntaxError: \"use strict\" not allowed in function with rest parameter",
"The 29th value is correct.");
is(w30.value, "SyntaxError: \"use strict\" not allowed in function with destructuring parameter",
"The 30th value is correct.");
is(w31.value, "SyntaxError: \"use strict\" not allowed in function with destructuring parameter",
"The 31st value is correct.");
is(w32.value, 42, "The 32nd value is correct.");
}
}

View File

@ -18,7 +18,7 @@ NS_INTERFACE_MAP_BEGIN(nsRefreshTimer)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsITimerCallback)
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
NS_INTERFACE_MAP_ENTRY(nsINamed)
NS_INTERFACE_MAP_END_THREADSAFE
NS_INTERFACE_MAP_END
nsRefreshTimer::nsRefreshTimer(nsDocShell* aDocShell,
nsIURI* aURI,

View File

@ -433,6 +433,8 @@ class ParentRunnable final
, public PAsmJSCacheEntryParent
{
public:
// We need to always declare refcounting because
// OpenDirectoryListener has pure-virtual refcounting.
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIRUNNABLE

View File

@ -39,6 +39,7 @@ DOM_PREF(NetworkInformationEnabled, "dom.netinfo.enabled")
DOM_PREF(FetchObserverEnabled, "dom.fetchObserver.enabled")
DOM_PREF(ResistFingerprintingEnabled, "privacy.resistFingerprinting")
DOM_PREF(DevToolsEnabled, "devtools.enabled")
DOM_PREF(PerformanceObserverEnabled, "dom.enable_performance_observer")
DOM_WEBIDL_PREF(ImageBitmapExtensionsEnabled)
DOM_WEBIDL_PREF(DOMCachesEnabled)
@ -54,3 +55,4 @@ DOM_WEBIDL_PREF(OffscreenCanvasEnabled)
DOM_WEBIDL_PREF(WebkitBlinkDirectoryPickerEnabled)
DOM_WEBIDL_PREF(NetworkInformationEnabled)
DOM_WEBIDL_PREF(FetchObserverEnabled)
DOM_WEBIDL_PREF(PerformanceObserverEnabled)

View File

@ -140,6 +140,8 @@ private:
, mTo(aTo)
{}
// We need to actually declare all of nsISupports, because
// Notification inherits from it but doesn't declare it.
NS_DECL_ISUPPORTS_INHERITED
NS_IMETHOD Run() override {
if (mTarget) {

View File

@ -145,7 +145,7 @@ class EncodingRunnable : public Runnable
virtual ~EncodingRunnable() {}
public:
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(EncodingRunnable, Runnable)
EncodingRunnable(const nsAString& aType,
const nsAString& aOptions,
@ -243,8 +243,6 @@ private:
bool mUsingCustomOptions;
};
NS_IMPL_ISUPPORTS_INHERITED0(EncodingRunnable, Runnable);
StaticRefPtr<nsIThreadPool> ImageEncoder::sThreadPool;
/* static */

View File

@ -871,7 +871,8 @@ CreateInterfacePrototypeObject(JSContext* cx, JS::Handle<JSObject*> global,
}
if (unscopableNames) {
JS::Rooted<JSObject*> unscopableObj(cx, JS_NewPlainObject(cx));
JS::Rooted<JSObject*> unscopableObj(cx,
JS_NewObjectWithGivenProto(cx, nullptr, nullptr));
if (!unscopableObj) {
return nullptr;
}

View File

@ -17851,9 +17851,17 @@ class CGEventClass(CGBindingImplClass):
CGBindingImplClass.__init__(self, descriptor, CGEventMethod, CGEventGetter, CGEventSetter, False, "WrapObjectInternal")
members = []
extraMethods = []
self.membersNeedingCC = []
self.membersNeedingTrace = []
for m in descriptor.interface.members:
if getattr(m, "originatingInterface",
descriptor.interface) != descriptor.interface:
continue
if m.isAttr():
if m.type.isAny():
self.membersNeedingTrace.append(m)
# Add a getter that doesn't need a JSContext. Note that we
# don't need to do this if our originating interface is not
# the descriptor's interface, because in that case we
@ -17872,9 +17880,16 @@ class CGEventClass(CGBindingImplClass):
aRetVal.set(${memberName});
""",
memberName=CGDictionary.makeMemberName(m.identifier.name))))
if getattr(m, "originatingInterface",
descriptor.interface) != descriptor.interface:
continue
elif (m.type.isObject() or
m.type.isSpiderMonkeyInterface()):
self.membersNeedingTrace.append(m)
elif typeNeedsRooting(m.type):
raise TypeError(
"Need to implement tracing for event member of type %s" %
m.type)
elif idlTypeNeedsCycleCollection(m.type):
self.membersNeedingCC.append(m)
nativeType = self.getNativeTypeForIDLType(m.type).define()
members.append(ClassMember(CGDictionary.makeMemberName(m.identifier.name),
nativeType,
@ -17883,20 +17898,39 @@ class CGEventClass(CGBindingImplClass):
parent = self.descriptor.interface.parent
self.parentType = self.descriptor.getDescriptor(parent.identifier.name).nativeType.split('::')[-1]
self.nativeType = self.descriptor.nativeType.split('::')[-1]
if self.needCC():
isupportsDecl = fill(
"""
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(${nativeType}, ${parentType})
""",
nativeType=self.nativeType,
parentType=self.parentType)
else:
isupportsDecl = fill(
"""
NS_INLINE_DECL_REFCOUNTING_INHERITED(${nativeType}, ${parentType})
""",
nativeType=self.nativeType,
parentType=self.parentType)
baseDeclarations = fill(
"""
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(${nativeType}, ${parentType})
$*{isupportsDecl}
protected:
virtual ~${nativeType}();
explicit ${nativeType}(mozilla::dom::EventTarget* aOwner);
""",
nativeType=self.descriptor.nativeType.split('::')[-1],
isupportsDecl=isupportsDecl,
nativeType=self.nativeType,
parentType=self.parentType)
className = descriptor.nativeType.split('::')[-1]
className = self.nativeType
asConcreteTypeMethod = ClassMethod("As%s" % className,
"%s*" % className,
[],
@ -17915,81 +17949,91 @@ class CGEventClass(CGBindingImplClass):
def getWrapObjectBody(self):
return "return %sBinding::Wrap(aCx, this, aGivenProto);\n" % self.descriptor.name
def needCC(self):
return (len(self.membersNeedingCC) != 0 or
len(self.membersNeedingTrace) != 0)
def implTraverse(self):
retVal = ""
for m in self.descriptor.interface.members:
# Unroll the type so we pick up sequences of interfaces too.
if m.isAttr() and idlTypeNeedsCycleCollection(m.type):
retVal += (" NS_IMPL_CYCLE_COLLECTION_TRAVERSE(" +
CGDictionary.makeMemberName(m.identifier.name) +
")\n")
for m in self.membersNeedingCC:
retVal += (" NS_IMPL_CYCLE_COLLECTION_TRAVERSE(%s)\n" %
CGDictionary.makeMemberName(m.identifier.name))
return retVal
def implUnlink(self):
retVal = ""
for m in self.descriptor.interface.members:
if m.isAttr():
name = CGDictionary.makeMemberName(m.identifier.name)
# Unroll the type so we pick up sequences of interfaces too.
if idlTypeNeedsCycleCollection(m.type):
retVal += " NS_IMPL_CYCLE_COLLECTION_UNLINK(" + name + ")\n"
elif m.type.isAny():
retVal += " tmp->" + name + ".setUndefined();\n"
elif m.type.isObject() or m.type.isSpiderMonkeyInterface():
retVal += " tmp->" + name + " = nullptr;\n"
for m in self.membersNeedingCC:
retVal += (" NS_IMPL_CYCLE_COLLECTION_UNLINK(%s)\n" %
CGDictionary.makeMemberName(m.identifier.name))
for m in self.membersNeedingTrace:
name = CGDictionary.makeMemberName(m.identifier.name)
if m.type.isAny():
retVal += " tmp->" + name + ".setUndefined();\n"
elif m.type.isObject() or m.type.isSpiderMonkeyInterface():
retVal += " tmp->" + name + " = nullptr;\n"
else:
raise TypeError("Unknown traceable member type %s" % m.type)
return retVal
def implTrace(self):
retVal = ""
for m in self.descriptor.interface.members:
if m.isAttr():
name = CGDictionary.makeMemberName(m.identifier.name)
if m.type.isAny() or m.type.isObject() or m.type.isSpiderMonkeyInterface():
retVal += " NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(" + name + ")\n"
elif typeNeedsRooting(m.type):
raise TypeError("Need to implement tracing for event "
"member of type %s" % m.type)
for m in self.membersNeedingTrace:
retVal += (" NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(%s)\n" %
CGDictionary.makeMemberName(m.identifier.name))
return retVal
def define(self):
dropJS = ""
for m in self.descriptor.interface.members:
if m.isAttr():
member = CGDictionary.makeMemberName(m.identifier.name)
if m.type.isAny():
dropJS += member + " = JS::UndefinedValue();\n"
elif m.type.isObject() or m.type.isSpiderMonkeyInterface():
dropJS += member + " = nullptr;\n"
for m in self.membersNeedingTrace:
member = CGDictionary.makeMemberName(m.identifier.name)
if m.type.isAny():
dropJS += member + " = JS::UndefinedValue();\n"
elif m.type.isObject() or m.type.isSpiderMonkeyInterface():
dropJS += member + " = nullptr;\n"
else:
raise TypeError("Unknown traceable member type %s" % m.type)
if dropJS != "":
dropJS += "mozilla::DropJSObjects(this);\n"
# Just override CGClass and do our own thing
nativeType = self.descriptor.nativeType.split('::')[-1]
ctorParams = ("aOwner, nullptr, nullptr" if self.parentType == "Event"
else "aOwner")
classImpl = fill(
if self.needCC():
classImpl = fill(
"""
NS_IMPL_CYCLE_COLLECTION_CLASS(${nativeType})
NS_IMPL_ADDREF_INHERITED(${nativeType}, ${parentType})
NS_IMPL_RELEASE_INHERITED(${nativeType}, ${parentType})
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(${nativeType}, ${parentType})
$*{traverse}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(${nativeType}, ${parentType})
$*{trace}
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(${nativeType}, ${parentType})
$*{unlink}
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(${nativeType})
NS_INTERFACE_MAP_END_INHERITING(${parentType})
""",
nativeType=self.nativeType,
parentType=self.parentType,
traverse=self.implTraverse(),
unlink=self.implUnlink(),
trace=self.implTrace())
else:
classImpl = ""
classImpl += fill(
"""
NS_IMPL_CYCLE_COLLECTION_CLASS(${nativeType})
NS_IMPL_ADDREF_INHERITED(${nativeType}, ${parentType})
NS_IMPL_RELEASE_INHERITED(${nativeType}, ${parentType})
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(${nativeType}, ${parentType})
$*{traverse}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(${nativeType}, ${parentType})
$*{trace}
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(${nativeType}, ${parentType})
$*{unlink}
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(${nativeType})
NS_INTERFACE_MAP_END_INHERITING(${parentType})
${nativeType}::${nativeType}(mozilla::dom::EventTarget* aOwner)
: ${parentType}(${ctorParams})
{
@ -18001,14 +18045,11 @@ class CGEventClass(CGBindingImplClass):
}
""",
ifaceName=self.descriptor.name,
nativeType=nativeType,
nativeType=self.nativeType,
ctorParams=ctorParams,
parentType=self.parentType,
traverse=self.implTraverse(),
unlink=self.implUnlink(),
trace=self.implTrace(),
dropJS=dropJS)
return classImpl + CGBindingImplClass.define(self)
def getNativeTypeForIDLType(self, type):

View File

@ -26,12 +26,6 @@ AnimationEvent::AnimationEvent(EventTarget* aOwner,
}
}
NS_INTERFACE_MAP_BEGIN(AnimationEvent)
NS_INTERFACE_MAP_END_INHERITING(Event)
NS_IMPL_ADDREF_INHERITED(AnimationEvent, Event)
NS_IMPL_RELEASE_INHERITED(AnimationEvent, Event)
//static
already_AddRefed<AnimationEvent>
AnimationEvent::Constructor(const GlobalObject& aGlobal,

View File

@ -21,7 +21,7 @@ public:
nsPresContext* aPresContext,
InternalAnimationEvent* aEvent);
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(AnimationEvent, Event)
static already_AddRefed<AnimationEvent>
Constructor(const GlobalObject& aGlobal,

View File

@ -9,12 +9,6 @@
namespace mozilla {
namespace dom {
NS_IMPL_ADDREF_INHERITED(BeforeUnloadEvent, Event)
NS_IMPL_RELEASE_INHERITED(BeforeUnloadEvent, Event)
NS_INTERFACE_MAP_BEGIN(BeforeUnloadEvent)
NS_INTERFACE_MAP_END_INHERITING(Event)
void
BeforeUnloadEvent::SetReturnValue(const nsAString& aReturnValue)
{

View File

@ -33,7 +33,7 @@ public:
return BeforeUnloadEventBinding::Wrap(aCx, this, aGivenProto);
}
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(BeforeUnloadEvent, Event)
void GetReturnValue(nsAString& aReturnValue);
void SetReturnValue(const nsAString& aReturnValue);

View File

@ -26,12 +26,6 @@ CommandEvent::CommandEvent(EventTarget* aOwner,
}
}
NS_INTERFACE_MAP_BEGIN(CommandEvent)
NS_INTERFACE_MAP_END_INHERITING(Event)
NS_IMPL_ADDREF_INHERITED(CommandEvent, Event)
NS_IMPL_RELEASE_INHERITED(CommandEvent, Event)
void
CommandEvent::GetCommand(nsAString& aCommand)
{

View File

@ -21,7 +21,7 @@ public:
nsPresContext* aPresContext,
WidgetCommandEvent* aEvent);
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(CommandEvent, Event)
virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
{

View File

@ -29,12 +29,6 @@ InputEvent::InputEvent(EventTarget* aOwner,
}
}
NS_IMPL_ADDREF_INHERITED(InputEvent, UIEvent)
NS_IMPL_RELEASE_INHERITED(InputEvent, UIEvent)
NS_INTERFACE_MAP_BEGIN(InputEvent)
NS_INTERFACE_MAP_END_INHERITING(UIEvent)
bool
InputEvent::IsComposing()
{

View File

@ -21,7 +21,7 @@ public:
nsPresContext* aPresContext,
InternalEditorInputEvent* aEvent);
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(InputEvent, UIEvent)
// Forward to base class
NS_FORWARD_TO_UIEVENT

View File

@ -31,12 +31,6 @@ KeyboardEvent::KeyboardEvent(EventTarget* aOwner,
}
}
NS_IMPL_ADDREF_INHERITED(KeyboardEvent, UIEvent)
NS_IMPL_RELEASE_INHERITED(KeyboardEvent, UIEvent)
NS_INTERFACE_MAP_BEGIN(KeyboardEvent)
NS_INTERFACE_MAP_END_INHERITING(UIEvent)
bool
KeyboardEvent::AltKey(CallerType aCallerType)
{

View File

@ -22,7 +22,7 @@ public:
nsPresContext* aPresContext,
WidgetKeyboardEvent* aEvent);
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(KeyboardEvent, UIEvent)
virtual KeyboardEvent* AsKeyboardEvent() override
{

View File

@ -32,12 +32,6 @@ MouseScrollEvent::MouseScrollEvent(EventTarget* aOwner,
mDetail = mEvent->AsMouseScrollEvent()->mDelta;
}
NS_IMPL_ADDREF_INHERITED(MouseScrollEvent, MouseEvent)
NS_IMPL_RELEASE_INHERITED(MouseScrollEvent, MouseEvent)
NS_INTERFACE_MAP_BEGIN(MouseScrollEvent)
NS_INTERFACE_MAP_END_INHERITING(MouseEvent)
void
MouseScrollEvent::InitMouseScrollEvent(const nsAString& aType,
bool aCanBubble,

View File

@ -20,7 +20,7 @@ public:
nsPresContext* aPresContext,
WidgetMouseScrollEvent* aEvent);
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(MouseScrollEvent, MouseEvent)
// Forward to base class
NS_FORWARD_TO_MOUSEEVENT

View File

@ -22,12 +22,6 @@ MutationEvent::MutationEvent(EventTarget* aOwner,
mEventIsInternal = (aEvent == nullptr);
}
NS_INTERFACE_MAP_BEGIN(MutationEvent)
NS_INTERFACE_MAP_END_INHERITING(Event)
NS_IMPL_ADDREF_INHERITED(MutationEvent, Event)
NS_IMPL_RELEASE_INHERITED(MutationEvent, Event)
already_AddRefed<nsINode>
MutationEvent::GetRelatedNode()
{

View File

@ -22,7 +22,7 @@ public:
nsPresContext* aPresContext,
InternalMutationEvent* aEvent);
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(MutationEvent, Event)
virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
{

View File

@ -33,12 +33,6 @@ SimpleGestureEvent::SimpleGestureEvent(EventTarget* aOwner,
}
}
NS_IMPL_ADDREF_INHERITED(SimpleGestureEvent, MouseEvent)
NS_IMPL_RELEASE_INHERITED(SimpleGestureEvent, MouseEvent)
NS_INTERFACE_MAP_BEGIN(SimpleGestureEvent)
NS_INTERFACE_MAP_END_INHERITING(MouseEvent)
uint32_t
SimpleGestureEvent::AllowedDirections() const
{

View File

@ -23,7 +23,7 @@ public:
nsPresContext* aPresContext,
WidgetSimpleGestureEvent* aEvent);
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(SimpleGestureEvent, MouseEvent)
virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
{

View File

@ -26,12 +26,6 @@ TransitionEvent::TransitionEvent(EventTarget* aOwner,
}
}
NS_INTERFACE_MAP_BEGIN(TransitionEvent)
NS_INTERFACE_MAP_END_INHERITING(Event)
NS_IMPL_ADDREF_INHERITED(TransitionEvent, Event)
NS_IMPL_RELEASE_INHERITED(TransitionEvent, Event)
// static
already_AddRefed<TransitionEvent>
TransitionEvent::Constructor(const GlobalObject& aGlobal,

View File

@ -21,7 +21,7 @@ public:
nsPresContext* aPresContext,
InternalTransitionEvent* aEvent);
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(TransitionEvent, Event)
static already_AddRefed<TransitionEvent>
Constructor(const GlobalObject& aGlobal,

View File

@ -36,12 +36,6 @@ WheelEvent::WheelEvent(EventTarget* aOwner,
}
}
NS_IMPL_ADDREF_INHERITED(WheelEvent, MouseEvent)
NS_IMPL_RELEASE_INHERITED(WheelEvent, MouseEvent)
NS_INTERFACE_MAP_BEGIN(WheelEvent)
NS_INTERFACE_MAP_END_INHERITING(MouseEvent)
void
WheelEvent::InitWheelEvent(const nsAString& aType,
bool aCanBubble,

View File

@ -21,7 +21,7 @@ public:
nsPresContext* aPresContext,
WidgetWheelEvent* aWheelEvent);
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(WheelEvent, MouseEvent)
// Forward to base class
NS_FORWARD_TO_MOUSEEVENT

View File

@ -473,7 +473,7 @@ FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput,
GlobalObject global(cx, jsGlobal);
RefPtr<Request> request = Request::Constructor(global, aInput, aInit, aRv);
if (NS_WARN_IF(aRv.Failed())) {
if (aRv.Failed()) {
return nullptr;
}

View File

@ -584,10 +584,12 @@ FetchBodyConsumer<Derived>::BeginConsumeBodyMainThread()
// Try to retarget, otherwise fall back to main thread.
nsCOMPtr<nsIThreadRetargetableRequest> rr = do_QueryInterface(pump);
if (rr) {
nsCOMPtr<nsIThreadRetargetableStreamListener> rl =
do_QueryInterface(listener);
if (rr && rl) {
nsCOMPtr<nsIEventTarget> sts = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
rv = rr->RetargetDeliveryTo(sts);
if (NS_WARN_IF(NS_FAILED(rv))) {
if (NS_FAILED(rv)) {
NS_WARNING("Retargeting failed");
}
}

View File

@ -718,7 +718,9 @@ FetchDriver::HttpFetch(const nsACString& aPreferredAlternativeDataType)
} else {
rv = chan->AsyncOpen2(this);
}
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv)) {
return rv;
}
// Step 4 onwards of "HTTP Fetch" is handled internally by Necko.

View File

@ -142,7 +142,7 @@ ParseURLFromChrome(const nsAString& aInput, ErrorResult& aRv)
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIURI> uri;
aRv = NS_NewURI(getter_AddRefs(uri), aInput, nullptr, nullptr);
if (NS_WARN_IF(aRv.Failed())) {
if (aRv.Failed()) {
aRv.ThrowTypeError<MSG_INVALID_URL>(aInput);
}
return uri.forget();
@ -328,7 +328,7 @@ Request::Constructor(const GlobalObject& aGlobal,
} else {
GetRequestURLFromWorker(aGlobal, input, requestURL, fragment, aRv);
}
if (NS_WARN_IF(aRv.Failed())) {
if (aRv.Failed()) {
return nullptr;
}
request = new InternalRequest(NS_ConvertUTF16toUTF8(requestURL), fragment);

View File

@ -10,8 +10,6 @@
namespace mozilla {
namespace dom {
NS_IMPL_ISUPPORTS_INHERITED0(EmptyBlobImpl, BlobImpl)
already_AddRefed<BlobImpl>
EmptyBlobImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType,

View File

@ -15,7 +15,7 @@ namespace dom {
class EmptyBlobImpl final : public BaseBlobImpl
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(EmptyBlobImpl, BaseBlobImpl)
explicit EmptyBlobImpl(const nsAString& aContentType)
: BaseBlobImpl(aContentType, 0 /* aLength */)

View File

@ -18,8 +18,6 @@
namespace mozilla {
namespace dom {
NS_IMPL_ISUPPORTS_INHERITED0(FileBlobImpl, BlobImpl)
FileBlobImpl::FileBlobImpl(nsIFile* aFile)
: BaseBlobImpl(EmptyString(), EmptyString(), UINT64_MAX, INT64_MAX)
, mFile(aFile)

View File

@ -17,7 +17,7 @@ namespace dom {
class FileBlobImpl : public BaseBlobImpl
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(FileBlobImpl, BaseBlobImpl)
// Create as a file
explicit FileBlobImpl(nsIFile* aFile);

View File

@ -47,8 +47,6 @@ nsresult MemoryBlobImpl::DataOwnerAdapter::Create(DataOwner* aDataOwner,
return NS_OK;
}
NS_IMPL_ISUPPORTS_INHERITED0(MemoryBlobImpl, BlobImpl)
already_AddRefed<BlobImpl>
MemoryBlobImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType,

View File

@ -23,7 +23,7 @@ namespace dom {
class MemoryBlobImpl final : public BaseBlobImpl
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(MemoryBlobImpl, BaseBlobImpl)
MemoryBlobImpl(void* aMemoryBuffer, uint64_t aLength, const nsAString& aName,
const nsAString& aContentType, int64_t aLastModifiedDate)

View File

@ -23,8 +23,6 @@
using namespace mozilla;
using namespace mozilla::dom;
NS_IMPL_ISUPPORTS_INHERITED0(MultipartBlobImpl, BlobImpl)
/* static */ already_AddRefed<MultipartBlobImpl>
MultipartBlobImpl::Create(nsTArray<RefPtr<BlobImpl>>&& aBlobImpls,
const nsAString& aName,

View File

@ -18,7 +18,7 @@ namespace dom {
class MultipartBlobImpl final : public BaseBlobImpl
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(MultipartBlobImpl, BaseBlobImpl)
// Create as a file
static already_AddRefed<MultipartBlobImpl>

View File

@ -213,6 +213,8 @@ class CreateBlobRunnable final : public Runnable
, public TemporaryIPCBlobChildCallback
{
public:
// We need to always declare refcounting because
// TemporaryIPCBlobChildCallback has pure-virtual refcounting.
NS_DECL_ISUPPORTS_INHERITED
CreateBlobRunnable(MutableBlobStorage* aBlobStorage,

View File

@ -41,8 +41,6 @@ HTMLBodyElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
return HTMLBodyElementBinding::Wrap(aCx, this, aGivenProto);
}
NS_IMPL_ISUPPORTS_INHERITED0(HTMLBodyElement, nsGenericHTMLElement)
NS_IMPL_ELEMENT_CLONE(HTMLBodyElement)
bool

View File

@ -32,7 +32,7 @@ public:
}
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLBodyElement, nsGenericHTMLElement)
NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLBodyElement, body);

View File

@ -25,8 +25,6 @@ HTMLFrameElement::~HTMLFrameElement()
}
NS_IMPL_ISUPPORTS_INHERITED0(HTMLFrameElement, nsGenericHTMLFrameElement)
NS_IMPL_ELEMENT_CLONE(HTMLFrameElement)
bool

View File

@ -23,7 +23,8 @@ public:
FromParser aFromParser = NOT_FROM_PARSER);
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLFrameElement,
nsGenericHTMLFrameElement)
NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLFrameElement, frame)

View File

@ -26,8 +26,6 @@ HTMLFrameSetElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
return HTMLFrameSetElementBinding::Wrap(aCx, this, aGivenProto);
}
NS_IMPL_ISUPPORTS_INHERITED0(HTMLFrameSetElement, nsGenericHTMLElement)
NS_IMPL_ELEMENT_CLONE(HTMLFrameSetElement)
nsresult

View File

@ -58,7 +58,8 @@ public:
NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLFrameSetElement, frameset)
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLFrameSetElement,
nsGenericHTMLElement)
void GetCols(DOMString& aCols)
{

View File

@ -21,8 +21,6 @@ HTMLHRElement::~HTMLHRElement()
{
}
NS_IMPL_ISUPPORTS_INHERITED0(HTMLHRElement, nsGenericHTMLElement)
NS_IMPL_ELEMENT_CLONE(HTMLHRElement)

View File

@ -24,7 +24,7 @@ public:
explicit HTMLHRElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLHRElement, nsGenericHTMLElement)
virtual bool ParseAttribute(int32_t aNamespaceID,
nsAtom* aAttribute,

View File

@ -37,8 +37,6 @@ HTMLIFrameElement::~HTMLIFrameElement()
{
}
NS_IMPL_ISUPPORTS_INHERITED0(HTMLIFrameElement, nsGenericHTMLFrameElement)
NS_IMPL_ELEMENT_CLONE(HTMLIFrameElement)
bool

View File

@ -23,7 +23,8 @@ public:
NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLIFrameElement, iframe)
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLIFrameElement,
nsGenericHTMLFrameElement)
// Element
virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override

View File

@ -22,8 +22,6 @@ HTMLLIElement::~HTMLLIElement()
{
}
NS_IMPL_ISUPPORTS_INHERITED0(HTMLLIElement, nsGenericHTMLElement)
NS_IMPL_ELEMENT_CLONE(HTMLLIElement)
// values that are handled case-insensitively

View File

@ -23,7 +23,7 @@ public:
}
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLLIElement, nsGenericHTMLElement)
virtual bool ParseAttribute(int32_t aNamespaceID,
nsAtom* aAttribute,

View File

@ -34,10 +34,6 @@ HTMLLabelElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
return HTMLLabelElementBinding::Wrap(aCx, this, aGivenProto);
}
// nsISupports
NS_IMPL_ISUPPORTS_INHERITED0(HTMLLabelElement, nsGenericHTMLElement)
// nsIDOMHTMLLabelElement
NS_IMPL_ELEMENT_CLONE(HTMLLabelElement)

View File

@ -29,7 +29,7 @@ public:
NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLLabelElement, label)
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLLabelElement, nsGenericHTMLElement)
// Element
virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override

Some files were not shown because too many files have changed in this diff Show More