mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Merge inbound to mozilla-central. a=merge
This commit is contained in:
commit
d03ad8843e
@ -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
|
||||
|
||||
|
@ -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; }
|
||||
|
@ -31,8 +31,6 @@ ApplicationAccessible::ApplicationAccessible() :
|
||||
MOZ_ASSERT(mAppInfo, "no application info");
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(ApplicationAccessible, Accessible)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIAccessible
|
||||
|
||||
|
@ -32,7 +32,7 @@ public:
|
||||
|
||||
ApplicationAccessible();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_INLINE_DECL_REFCOUNTING_INHERITED(ApplicationAccessible, AccessibleWrap)
|
||||
|
||||
// Accessible
|
||||
virtual void Shutdown() override;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -56,8 +56,6 @@ HyperTextAccessible::
|
||||
mGenericTypes |= eHyperText;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(HyperTextAccessible, Accessible)
|
||||
|
||||
role
|
||||
HyperTextAccessible::NativeRole()
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -50,12 +50,6 @@ OuterDocAccessible::~OuterDocAccessible()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsISupports
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(OuterDocAccessible,
|
||||
Accessible)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Accessible public (DON'T add methods here)
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -52,7 +52,7 @@ using namespace mozilla::dom;
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsISupports
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(RootAccessible, DocAccessible)
|
||||
NS_IMPL_ISUPPORTS_INHERITED(RootAccessible, DocAccessible, nsIDOMEventListener)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor/destructor
|
||||
|
@ -15,8 +15,6 @@ HTMLCanvasAccessible::
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(HTMLCanvasAccessible, HyperTextAccessible)
|
||||
|
||||
role
|
||||
HTMLCanvasAccessible::NativeRole()
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -285,9 +285,6 @@ HTMLTextFieldAccessible::
|
||||
mType = eHTMLTextFieldType;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(HTMLTextFieldAccessible,
|
||||
HyperTextAccessible)
|
||||
|
||||
role
|
||||
HTMLTextFieldAccessible::NativeRole()
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -33,11 +33,6 @@ HTMLImageMapAccessible::
|
||||
UpdateChildAreas(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// HTMLImageMapAccessible: nsISupports
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(HTMLImageMapAccessible, ImageAccessible)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// HTMLImageMapAccessible: Accessible public
|
||||
|
||||
|
@ -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;
|
||||
|
@ -27,8 +27,6 @@ HTMLLinkAccessible::
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(HTMLLinkAccessible, HyperTextAccessible)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIAccessible
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -26,8 +26,6 @@ XULAlertAccessible::~XULAlertAccessible()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(XULAlertAccessible, Accessible)
|
||||
|
||||
role
|
||||
XULAlertAccessible::NativeRole()
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -54,8 +54,6 @@ XULButtonAccessible::~XULButtonAccessible()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// XULButtonAccessible: nsISupports
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(XULButtonAccessible, Accessible)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// XULButtonAccessible: nsIAccessible
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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; }
|
||||
|
@ -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");
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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"
|
||||
|
@ -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]
|
||||
|
@ -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();
|
||||
});
|
@ -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">
|
||||
|
214
browser/modules/BrowserErrorReporter.jsm
Normal file
214
browser/modules/BrowserErrorReporter.jsm
Normal 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);
|
||||
}
|
||||
}
|
@ -123,6 +123,7 @@ EXTRA_JS_MODULES += [
|
||||
'AboutHome.jsm',
|
||||
'AboutNewTab.jsm',
|
||||
'AttributionCode.jsm',
|
||||
'BrowserErrorReporter.jsm',
|
||||
'BrowserUITelemetry.jsm',
|
||||
'BrowserUsageTelemetry.jsm',
|
||||
'ContentClick.jsm',
|
||||
|
@ -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]
|
||||
|
@ -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>
|
387
browser/modules/test/browser/browser_BrowserErrorReporter.js
Normal file
387
browser/modules/test/browser/browser_BrowserErrorReporter.js
Normal 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.",
|
||||
);
|
||||
});
|
||||
});
|
@ -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.
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -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.");
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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):
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -22,7 +22,7 @@ public:
|
||||
nsPresContext* aPresContext,
|
||||
WidgetKeyboardEvent* aEvent);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_INLINE_DECL_REFCOUNTING_INHERITED(KeyboardEvent, UIEvent)
|
||||
|
||||
virtual KeyboardEvent* AsKeyboardEvent() override
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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 */)
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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>
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -25,8 +25,6 @@ HTMLFrameElement::~HTMLFrameElement()
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(HTMLFrameElement, nsGenericHTMLFrameElement)
|
||||
|
||||
NS_IMPL_ELEMENT_CLONE(HTMLFrameElement)
|
||||
|
||||
bool
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -21,8 +21,6 @@ HTMLHRElement::~HTMLHRElement()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(HTMLHRElement, nsGenericHTMLElement)
|
||||
|
||||
NS_IMPL_ELEMENT_CLONE(HTMLHRElement)
|
||||
|
||||
|
||||
|
@ -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,
|
||||
|
@ -37,8 +37,6 @@ HTMLIFrameElement::~HTMLIFrameElement()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(HTMLIFrameElement, nsGenericHTMLFrameElement)
|
||||
|
||||
NS_IMPL_ELEMENT_CLONE(HTMLIFrameElement)
|
||||
|
||||
bool
|
||||
|
@ -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
|
||||
|
@ -22,8 +22,6 @@ HTMLLIElement::~HTMLLIElement()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(HTMLLIElement, nsGenericHTMLElement)
|
||||
|
||||
NS_IMPL_ELEMENT_CLONE(HTMLLIElement)
|
||||
|
||||
// values that are handled case-insensitively
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user