author | arthur.iakab <aiakab@mozilla.com> |
Tue, 03 Apr 2018 12:31:23 +0300 | |
changeset 411442 | 4a3275936ddf871103b53e00608e2b8d5aee7e69 |
parent 411441 | 2ee160335e150f20df3471b60b5e58ce873e2ff6 (current diff) |
parent 411407 | efce674123ace94d821157b996f0d5caa7380620 (diff) |
child 411443 | 99a953f1823fcf96d6f312b356a11f245a9b0c78 |
child 411462 | 5ec55f7a95f94cf39d57cdf36abecab914ea48eb |
child 411525 | 801d1d90b2ffcca423d9cee10509169318890b8c |
push id | 101651 |
push user | aiakab@mozilla.com |
push date | Tue, 03 Apr 2018 09:42:02 +0000 |
treeherder | mozilla-inbound@99a953f1823f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | merge |
milestone | 61.0a1 |
first release with | nightly linux32
4a3275936ddf
/
61.0a1
/
20180403100105
/
files
nightly linux64
4a3275936ddf
/
61.0a1
/
20180403100105
/
files
nightly mac
4a3275936ddf
/
61.0a1
/
20180403100105
/
files
nightly win32
4a3275936ddf
/
61.0a1
/
20180403100105
/
files
nightly win64
4a3275936ddf
/
61.0a1
/
20180403100105
/
files
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
61.0a1
/
20180403100105
/
pushlog to previous
nightly linux64
61.0a1
/
20180403100105
/
pushlog to previous
nightly mac
61.0a1
/
20180403100105
/
pushlog to previous
nightly win32
61.0a1
/
20180403100105
/
pushlog to previous
nightly win64
61.0a1
/
20180403100105
/
pushlog to previous
|
dom/interfaces/base/nsIDOMScreen.idl | file | annotate | diff | comparison | revisions |
--- a/devtools/client/framework/components/toolbox-tab.js +++ b/devtools/client/framework/components/toolbox-tab.js @@ -57,16 +57,21 @@ class ToolboxTab extends Component { id: `toolbox-tab-${id}`, "data-id": id, title: tooltip, type: "button", "aria-pressed": currentToolId === id ? "true" : "false", tabIndex: focusedButton === id ? "0" : "-1", onFocus: () => focusButton(id), onMouseDown: () => selectTool(id), + onKeyDown: (evt) => { + if (evt.key === "Enter" || evt.key === " ") { + selectTool(id); + } + }, }, span( { className: "devtools-tab-line" } ), ...this.renderIcon(panelDefinition, isHighlighted), iconOnly ?
--- a/devtools/client/framework/test/browser_toolbox_keyboard_navigation.js +++ b/devtools/client/framework/test/browser_toolbox_keyboard_navigation.js @@ -76,8 +76,49 @@ add_task(async function () { EventUtils.synthesizeKey("KEY_Tab"); ok(!containsFocus(doc, toolbar), "Focus is outside of the toolbar"); // Move the focus back to the toolbar, ensure we land on the last active // descendant control. EventUtils.synthesizeKey("KEY_Tab", {shiftKey: true}); is(doc.activeElement.id, expectedFocusedControl.id, "New control is focused"); }); + +// Test that moving the focus of tab button and selecting it. +add_task(async function () { + info("Create a test tab and open the toolbox"); + let toolbox = await openNewTabAndToolbox(TEST_URL, "inspector"); + let doc = toolbox.doc; + + let toolbar = doc.querySelector(".toolbox-tabs"); + let tabButtons = toolbar.querySelectorAll(".devtools-tab, button"); + let win = tabButtons[0].ownerDocument.defaultView; + + // Put the keyboard focus onto the first tab button. + tabButtons[0].focus(); + ok(containsFocus(doc, toolbar), "Focus is within the toolbox"); + is(doc.activeElement.id, tabButtons[0].id, "First tab button is focused."); + + // Move the focused tab and select it by using enter key. + let onKeyEvent = once(win, "keydown"); + EventUtils.synthesizeKey("KEY_ArrowRight"); + await onKeyEvent; + + let onceSelected = toolbox.once("webconsole-selected"); + EventUtils.synthesizeKey("Enter"); + await onceSelected; + ok(doc.activeElement.id, tabButtons[1].id, "Changed tab button is focused."); + + // Webconsole steal the focus from button after sending "webconsole-selected" + // event. + tabButtons[1].focus(); + + // Return the focused tab with space key. + onKeyEvent = once(win, "keydown"); + EventUtils.synthesizeKey("KEY_ArrowLeft"); + await onKeyEvent; + + onceSelected = toolbox.once("inspector-selected"); + EventUtils.synthesizeKey(" "); + await onceSelected; + + ok(doc.activeElement.id, tabButtons[0].id, "Changed tab button is focused."); +});
--- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -2327,25 +2327,16 @@ nsGlobalWindowInner::GetScreen(ErrorResu aError.Throw(NS_ERROR_UNEXPECTED); return nullptr; } } return mScreen; } -nsIDOMScreen* -nsGlobalWindowInner::GetScreen() -{ - ErrorResult dummy; - nsIDOMScreen* screen = GetScreen(dummy); - dummy.SuppressException(); - return screen; -} - nsHistory* nsGlobalWindowInner::GetHistory(ErrorResult& aError) { if (!mHistory) { mHistory = new nsHistory(this); } return mHistory;
--- a/dom/base/nsGlobalWindowInner.h +++ b/dom/base/nsGlobalWindowInner.h @@ -774,17 +774,16 @@ public: already_AddRefed<nsICSSDeclaration> GetComputedStyle(mozilla::dom::Element& aElt, const nsAString& aPseudoElt, mozilla::ErrorResult& aError) override; already_AddRefed<mozilla::dom::MediaQueryList> MatchMedia( const nsAString& aQuery, mozilla::dom::CallerType aCallerType, mozilla::ErrorResult& aError); nsScreen* GetScreen(mozilla::ErrorResult& aError); - nsIDOMScreen* GetScreen() override; void MoveTo(int32_t aXPos, int32_t aYPos, mozilla::dom::CallerType aCallerType, mozilla::ErrorResult& aError); void MoveBy(int32_t aXDif, int32_t aYDif, mozilla::dom::CallerType aCallerType, mozilla::ErrorResult& aError); void ResizeTo(int32_t aWidth, int32_t aHeight, mozilla::dom::CallerType aCallerType,
--- a/dom/base/nsGlobalWindowOuter.cpp +++ b/dom/base/nsGlobalWindowOuter.cpp @@ -2591,20 +2591,20 @@ nsPIDOMWindowOuter::SetFrameElementInter } Navigator* nsGlobalWindowOuter::GetNavigator() { FORWARD_TO_INNER(Navigator, (), nullptr); } -nsIDOMScreen* +nsScreen* nsGlobalWindowOuter::GetScreen() { - FORWARD_TO_INNER(GetScreen, (), nullptr); + FORWARD_TO_INNER(GetScreen, (IgnoreErrors()), nullptr); } void nsPIDOMWindowOuter::MaybeActiveMediaComponents() { if (mMediaSuspend != nsISuspendedTypes::SUSPENDED_BLOCK) { return; } @@ -3703,48 +3703,47 @@ nsGlobalWindowOuter::CheckSecurityLeftAn #endif if (nsGlobalWindowOuter* rootWindow = nsGlobalWindowOuter::Cast(GetPrivateRoot())) { rootWindow->FlushPendingNotifications(FlushType::Layout); } nsCOMPtr<nsIBaseWindow> treeOwner = GetTreeOwnerWindow(); - nsCOMPtr<nsIDOMScreen> screen = GetScreen(); + RefPtr<nsScreen> screen = GetScreen(); if (treeOwner && screen) { - int32_t screenLeft, screenTop, screenWidth, screenHeight; int32_t winLeft, winTop, winWidth, winHeight; // Get the window size treeOwner->GetPositionAndSize(&winLeft, &winTop, &winWidth, &winHeight); // convert those values to CSS pixels // XXX four separate retrievals of the prescontext winLeft = DevToCSSIntPixels(winLeft); winTop = DevToCSSIntPixels(winTop); winWidth = DevToCSSIntPixels(winWidth); winHeight = DevToCSSIntPixels(winHeight); // Get the screen dimensions // XXX This should use nsIScreenManager once it's fully fleshed out. - screen->GetAvailLeft(&screenLeft); - screen->GetAvailWidth(&screenWidth); - screen->GetAvailHeight(&screenHeight); + int32_t screenLeft = screen->GetAvailLeft(IgnoreErrors()); + int32_t screenWidth = screen->GetAvailWidth(IgnoreErrors()); + int32_t screenHeight = screen->GetAvailHeight(IgnoreErrors()); #if defined(XP_MACOSX) /* The mac's coordinate system is different from the assumed Windows' system. It offsets by the height of the menubar so that a window placed at (0,0) will be entirely visible. Unfortunately that correction is made elsewhere (in Widget) and the meaning of the Avail... coordinates is overloaded. Here we allow a window to be placed at (0,0) because it does make sense to do so. */ - screen->GetTop(&screenTop); + int32_t screenTop = screen->GetTop(IgnoreErrors()); #else - screen->GetAvailTop(&screenTop); + int32_t screenTop = screen->GetAvailTop(IgnoreErrors()); #endif if (aLeft) { if (screenLeft+screenWidth < *aLeft+winWidth) *aLeft = screenLeft+screenWidth - winWidth; if (screenLeft > *aLeft) *aLeft = screenLeft; }
--- a/dom/base/nsGlobalWindowOuter.h +++ b/dom/base/nsGlobalWindowOuter.h @@ -631,17 +631,17 @@ public: nsIPrincipal& aSubjectPrincipal, mozilla::ErrorResult& aError); void PrintOuter(mozilla::ErrorResult& aError); mozilla::dom::Selection* GetSelectionOuter(); already_AddRefed<nsISelection> GetSelection() override; already_AddRefed<mozilla::dom::MediaQueryList> MatchMediaOuter( const nsAString& aQuery, mozilla::dom::CallerType aCallerType); - nsIDOMScreen* GetScreen() override; + nsScreen* GetScreen(); void MoveToOuter(int32_t aXPos, int32_t aYPos, mozilla::dom::CallerType aCallerType, mozilla::ErrorResult& aError); void MoveByOuter(int32_t aXDif, int32_t aYDif, mozilla::dom::CallerType aCallerType, mozilla::ErrorResult& aError); nsresult MoveBy(int32_t aXDif, int32_t aYDif) override; void ResizeToOuter(int32_t aWidth, int32_t aHeight,
--- a/dom/base/nsPIDOMWindow.h +++ b/dom/base/nsPIDOMWindow.h @@ -585,17 +585,16 @@ public: mMarkedCCGeneration = aGeneration; } uint32_t GetMarkedCCGeneration() { return mMarkedCCGeneration; } - virtual nsIDOMScreen* GetScreen() = 0; mozilla::dom::Navigator* Navigator(); virtual mozilla::dom::Location* GetLocation() = 0; virtual nsresult GetControllers(nsIControllers** aControllers) = 0; virtual already_AddRefed<nsIDOMWindowCollection> GetFrames() = 0; virtual nsresult GetInnerWidth(int32_t* aWidth) = 0; @@ -1089,17 +1088,16 @@ public: uint32_t GetMarkedCCGeneration() { return mMarkedCCGeneration; } // XXX(nika): These feel like they should be inner window only, but they're // called on the outer window. - virtual nsIDOMScreen* GetScreen() = 0; virtual mozilla::dom::Navigator* GetNavigator() = 0; virtual mozilla::dom::Location* GetLocation() = 0; virtual nsresult GetPrompter(nsIPrompt** aPrompt) = 0; virtual nsresult GetControllers(nsIControllers** aControllers) = 0; virtual already_AddRefed<nsISelection> GetSelection() = 0; virtual already_AddRefed<nsPIDOMWindowOuter> GetOpener() = 0;
--- a/dom/base/nsScreen.cpp +++ b/dom/base/nsScreen.cpp @@ -45,17 +45,16 @@ nsScreen::nsScreen(nsPIDOMWindowInner* a nsScreen::~nsScreen() { } // QueryInterface implementation for nsScreen NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsScreen) - NS_INTERFACE_MAP_ENTRY(nsIDOMScreen) NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper) NS_IMPL_ADDREF_INHERITED(nsScreen, DOMEventTargetHelper) NS_IMPL_RELEASE_INHERITED(nsScreen, DOMEventTargetHelper) NS_IMPL_CYCLE_COLLECTION_INHERITED(nsScreen, DOMEventTargetHelper, mScreenOrientation) @@ -75,32 +74,16 @@ nsScreen::GetPixelDepth(ErrorResult& aRv return -1; } uint32_t depth; context->GetDepth(depth); return depth; } -#define FORWARD_LONG_GETTER(_name) \ - NS_IMETHODIMP \ - nsScreen::Get ## _name(int32_t* aOut) \ - { \ - ErrorResult rv; \ - *aOut = Get ## _name(rv); \ - return rv.StealNSResult(); \ - } - -FORWARD_LONG_GETTER(AvailWidth) -FORWARD_LONG_GETTER(AvailHeight) - -FORWARD_LONG_GETTER(Top) -FORWARD_LONG_GETTER(AvailTop) -FORWARD_LONG_GETTER(AvailLeft) - nsPIDOMWindowOuter* nsScreen::GetOuter() const { if (nsPIDOMWindowInner* inner = GetOwner()) { return inner->GetOuterWindow(); } return nullptr;
--- a/dom/base/nsScreen.h +++ b/dom/base/nsScreen.h @@ -5,32 +5,29 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef nsScreen_h___ #define nsScreen_h___ #include "mozilla/Attributes.h" #include "mozilla/dom/ScreenOrientation.h" #include "mozilla/DOMEventTargetHelper.h" #include "mozilla/ErrorResult.h" -#include "nsIDOMScreen.h" #include "nsCOMPtr.h" #include "nsRect.h" class nsDeviceContext; // Script "screen" object class nsScreen : public mozilla::DOMEventTargetHelper - , public nsIDOMScreen { typedef mozilla::ErrorResult ErrorResult; public: static already_AddRefed<nsScreen> Create(nsPIDOMWindowInner* aWindow); NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSIDOMSCREEN NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsScreen, mozilla::DOMEventTargetHelper) NS_REALLY_FORWARD_NSIDOMEVENTTARGET(mozilla::DOMEventTargetHelper) nsPIDOMWindowInner* GetParentObject() const { return GetOwner(); }
--- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -2184,16 +2184,17 @@ class PropertyDefiner: lastCondition = getCondition(array[0], self.descriptor) specs = [] disablers = [] prefableSpecs = [] disablersTemplate = dedent( """ + // Can't be const because the pref-enabled boolean needs to be writable static PrefableDisablers %s_disablers%d = { true, %s, %s, %s }; """) prefableWithDisablersTemplate = ' { &%s_disablers%d, &%s_specs[%d] }' prefableWithoutDisablersTemplate = ' { nullptr, &%s_specs[%d] }' prefCacheTemplate = '&%s[%d].disablers->enabled' @@ -2252,18 +2253,17 @@ class PropertyDefiner: static ${specType} ${name}_specs[] = { ${specs} }; #if defined(__clang__) #pragma clang diagnostic pop #endif ${disablers} - // Can't be const because the pref-enabled boolean needs to be writable - static Prefable<${specType}> ${name}[] = { + static const Prefable<${specType}> ${name}[] = { ${prefableSpecs} }; """, specType=specType, name=name, disablers='\n'.join(disablers), specs=',\n'.join(specs),
--- a/dom/interfaces/base/domstubs.idl +++ b/dom/interfaces/base/domstubs.idl @@ -29,17 +29,16 @@ namespace dom { class DOMException; } } %} // Base interface nsIDOMWindow; interface nsIDOMWindowCollection; -interface nsIDOMScreen; // Events interface nsIDOMEvent; interface nsIDOMEventTarget; interface nsIDOMEventListener; // HTML interface nsIDOMHTMLHeadElement;
--- a/dom/interfaces/base/moz.build +++ b/dom/interfaces/base/moz.build @@ -12,17 +12,16 @@ XPIDL_SOURCES += [ 'nsIBrowser.idl', 'nsIBrowserDOMWindow.idl', 'nsIContentPermissionPrompt.idl', 'nsIContentPrefService2.idl', 'nsIContentProcess.idl', 'nsIContentURIGrouper.idl', 'nsIDOMChromeWindow.idl', 'nsIDOMGlobalPropertyInitializer.idl', - 'nsIDOMScreen.idl', 'nsIDOMWindow.idl', 'nsIDOMWindowCollection.idl', 'nsIDOMWindowUtils.idl', 'nsIFocusManager.idl', 'nsIIdleObserver.idl', 'nsIQueryContentEventResult.idl', 'nsIRemoteBrowser.idl', 'nsIServiceWorkerManager.idl',
deleted file mode 100644 --- a/dom/interfaces/base/nsIDOMScreen.idl +++ /dev/null @@ -1,16 +0,0 @@ -/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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/. */ - -#include "nsIDOMEventTarget.idl" - -[builtinclass, uuid(82c7924b-4b46-4e5a-a8d2-6edb5fc0a60d)] -interface nsIDOMScreen : nsIDOMEventTarget -{ - readonly attribute long top; - readonly attribute long availWidth; - readonly attribute long availHeight; - readonly attribute long availLeft; - readonly attribute long availTop; -};
--- a/editor/spellchecker/TextServicesDocument.cpp +++ b/editor/spellchecker/TextServicesDocument.cpp @@ -26,17 +26,16 @@ #include "nsIPlaintextEditor.h" // for nsIPlaintextEditor #include "nsISelection.h" // for nsISelection #include "nsISelectionController.h" // for nsISelectionController, etc #include "nsISupportsBase.h" // for nsISupports #include "nsISupportsUtils.h" // for NS_IF_ADDREF, NS_ADDREF, etc #include "nsITextServicesFilter.h" // for nsITextServicesFilter #include "mozilla/intl/WordBreaker.h" // for WordRange, WordBreaker #include "nsRange.h" // for nsRange -#include "nsStaticAtom.h" // for NS_STATIC_ATOM_SETUP, etc #include "nsString.h" // for nsString, nsAutoString #include "nscore.h" // for nsresult, NS_IMETHODIMP, etc #define LOCK_DOC(doc) #define UNLOCK_DOC(doc) namespace mozilla {
--- a/layout/style/nsCSSAnonBoxes.cpp +++ b/layout/style/nsCSSAnonBoxes.cpp @@ -4,76 +4,73 @@ * 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/. */ /* atom list for CSS anonymous boxes */ #include "mozilla/ArrayUtils.h" #include "nsCSSAnonBoxes.h" -#include "nsStaticAtom.h" using namespace mozilla; namespace mozilla { namespace detail { MOZ_PUSH_DISABLE_INTEGRAL_CONSTANT_OVERFLOW_WARNING extern constexpr CSSAnonBoxAtoms gCSSAnonBoxAtoms = { #define CSS_ANON_BOX(name_, value_) \ NS_STATIC_ATOM_INIT_STRING(value_) #include "nsCSSAnonBoxList.h" #undef CSS_ANON_BOX - - #define CSS_ANON_BOX(name_, value_) \ - NS_STATIC_ATOM_INIT_ATOM(CSSAnonBoxAtoms, name_, value_) - #include "nsCSSAnonBoxList.h" - #undef CSS_ANON_BOX + { + #define CSS_ANON_BOX(name_, value_) \ + NS_STATIC_ATOM_INIT_ATOM( \ + nsICSSAnonBoxPseudo, CSSAnonBoxAtoms, name_, value_) + #include "nsCSSAnonBoxList.h" + #undef CSS_ANON_BOX + } }; MOZ_POP_DISABLE_INTEGRAL_CONSTANT_OVERFLOW_WARNING } // namespace detail } // namespace mozilla +// Non-inheriting boxes must come first in nsCSSAnonBoxList.h so that +// `NonInheriting` values can index into this array and other similar arrays. +const nsStaticAtom* const nsCSSAnonBoxes::sAtoms = + mozilla::detail::gCSSAnonBoxAtoms.mAtoms; + #define CSS_ANON_BOX(name_, value_) \ - NS_STATIC_ATOM_SUBCLASS_DEFN_PTR(nsICSSAnonBoxPseudo, nsCSSAnonBoxes, name_) + NS_STATIC_ATOM_DEFN_PTR( \ + nsICSSAnonBoxPseudo, mozilla::detail::CSSAnonBoxAtoms, \ + mozilla::detail::gCSSAnonBoxAtoms, nsCSSAnonBoxes, name_) #include "nsCSSAnonBoxList.h" #undef CSS_ANON_BOX -static const nsStaticAtomSetup sCSSAnonBoxAtomSetup[] = { - // Non-inheriting boxes must come first in nsCSSAnonBoxList.h so that - // `NonInheriting` values can index into this array and other similar arrays. - #define CSS_ANON_BOX(name_, value_) \ - NS_STATIC_ATOM_SUBCLASS_SETUP( \ - mozilla::detail::gCSSAnonBoxAtoms, nsCSSAnonBoxes, name_) - #include "nsCSSAnonBoxList.h" - #undef CSS_ANON_BOX -}; - void nsCSSAnonBoxes::RegisterStaticAtoms() { - NS_RegisterStaticAtoms(sCSSAnonBoxAtomSetup); + NS_RegisterStaticAtoms(sAtoms, sAtomsLen); } bool nsCSSAnonBoxes::IsAnonBox(nsAtom *aAtom) { - return nsStaticAtomUtils::IsMember(aAtom, sCSSAnonBoxAtomSetup); + return nsStaticAtomUtils::IsMember(aAtom, sAtoms, sAtomsLen); } #ifdef MOZ_XUL /* static */ bool nsCSSAnonBoxes::IsTreePseudoElement(nsAtom* aPseudo) { MOZ_ASSERT(nsCSSAnonBoxes::IsAnonBox(aPseudo)); return StringBeginsWith(nsDependentAtomString(aPseudo), NS_LITERAL_STRING(":-moz-tree-")); } #endif /* static*/ nsCSSAnonBoxes::NonInheriting nsCSSAnonBoxes::NonInheritingTypeForPseudoTag(nsAtom* aPseudo) { MOZ_ASSERT(IsNonInheritingAnonBox(aPseudo)); - Maybe<uint32_t> index = - nsStaticAtomUtils::Lookup(aPseudo, sCSSAnonBoxAtomSetup); + Maybe<uint32_t> index = nsStaticAtomUtils::Lookup(aPseudo, sAtoms, sAtomsLen); MOZ_RELEASE_ASSERT(index.isSome()); return static_cast<NonInheriting>(*index); }
--- a/layout/style/nsCSSAnonBoxes.h +++ b/layout/style/nsCSSAnonBoxes.h @@ -7,32 +7,45 @@ /* atom list for CSS anonymous boxes */ #ifndef nsCSSAnonBoxes_h___ #define nsCSSAnonBoxes_h___ #include "nsAtom.h" #include "nsStaticAtom.h" -// Empty class derived from nsAtom so that function signatures can -// require an atom from this atom list. -class nsICSSAnonBoxPseudo : public nsAtom {}; +// Trivial subclass of nsStaticAtom so that function signatures can require an +// atom from this atom list. +class nsICSSAnonBoxPseudo : public nsStaticAtom +{ +public: + constexpr nsICSSAnonBoxPseudo(const char16_t* aStr, uint32_t aLength, + uint32_t aStringOffset) + : nsStaticAtom(aStr, aLength, aStringOffset) + {} +}; namespace mozilla { namespace detail { struct CSSAnonBoxAtoms { #define CSS_ANON_BOX(name_, value_) NS_STATIC_ATOM_DECL_STRING(name_, value_) #include "nsCSSAnonBoxList.h" #undef CSS_ANON_BOX - #define CSS_ANON_BOX(name_, value_) NS_STATIC_ATOM_DECL_ATOM(name_) - #include "nsCSSAnonBoxList.h" - #undef CSS_ANON_BOX + enum class Atoms { + #define CSS_ANON_BOX(name_, value_) \ + NS_STATIC_ATOM_ENUM(name_) + #include "nsCSSAnonBoxList.h" + #undef CSS_ANON_BOX + AtomsCount + }; + + const nsICSSAnonBoxPseudo mAtoms[static_cast<size_t>(Atoms::AtomsCount)]; }; extern const CSSAnonBoxAtoms gCSSAnonBoxAtoms; } // namespace detail } // namespace mozilla class nsCSSAnonBoxes { @@ -45,20 +58,26 @@ public: static bool IsTreePseudoElement(nsAtom* aPseudo); #endif static bool IsNonElement(nsAtom* aPseudo) { return aPseudo == mozText || aPseudo == oofPlaceholder || aPseudo == firstLetterContinuation; } -#define CSS_ANON_BOX(name_, value_) \ - NS_STATIC_ATOM_SUBCLASS_DECL_PTR(nsICSSAnonBoxPseudo, name_) -#include "nsCSSAnonBoxList.h" -#undef CSS_ANON_BOX +private: + static const nsStaticAtom* const sAtoms; + static constexpr size_t sAtomsLen = + mozilla::ArrayLength(mozilla::detail::gCSSAnonBoxAtoms.mAtoms); + +public: + #define CSS_ANON_BOX(name_, value_) \ + NS_STATIC_ATOM_DECL_PTR(nsICSSAnonBoxPseudo, name_) + #include "nsCSSAnonBoxList.h" + #undef CSS_ANON_BOX typedef uint8_t NonInheritingBase; enum class NonInheriting : NonInheritingBase { #define CSS_ANON_BOX(_name, _value) /* nothing */ #define CSS_NON_INHERITING_ANON_BOX(_name, _value) _name, #include "nsCSSAnonBoxList.h" #undef CSS_NON_INHERITING_ANON_BOX #undef CSS_ANON_BOX
--- a/layout/style/nsCSSPseudoElements.cpp +++ b/layout/style/nsCSSPseudoElements.cpp @@ -5,76 +5,70 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* atom list for CSS pseudo-elements */ #include "nsCSSPseudoElements.h" #include "mozilla/ArrayUtils.h" -#include "nsStaticAtom.h" #include "nsCSSAnonBoxes.h" #include "nsDOMString.h" using namespace mozilla; namespace mozilla { namespace detail { MOZ_PUSH_DISABLE_INTEGRAL_CONSTANT_OVERFLOW_WARNING extern constexpr CSSPseudoElementAtoms gCSSPseudoElementAtoms = { #define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \ NS_STATIC_ATOM_INIT_STRING(value_) #include "nsCSSPseudoElementList.h" #undef CSS_PSEUDO_ELEMENT - - #define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \ - NS_STATIC_ATOM_INIT_ATOM(CSSPseudoElementAtoms, name_, value_) - #include "nsCSSPseudoElementList.h" - #undef CSS_PSEUDO_ELEMENT + { + #define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \ + NS_STATIC_ATOM_INIT_ATOM( \ + nsICSSPseudoElement, CSSPseudoElementAtoms, name_, value_) + #include "nsCSSPseudoElementList.h" + #undef CSS_PSEUDO_ELEMENT + } }; MOZ_POP_DISABLE_INTEGRAL_CONSTANT_OVERFLOW_WARNING } // namespace detail } // namespace mozilla +const nsStaticAtom* const nsCSSPseudoElements::sAtoms = + mozilla::detail::gCSSPseudoElementAtoms.mAtoms; + #define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \ - NS_STATIC_ATOM_SUBCLASS_DEFN_PTR( \ - nsICSSPseudoElement, nsCSSPseudoElements, name_) + NS_STATIC_ATOM_DEFN_PTR( \ + nsICSSPseudoElement, mozilla::detail::CSSPseudoElementAtoms, \ + mozilla::detail::gCSSPseudoElementAtoms, nsCSSPseudoElements, name_); #include "nsCSSPseudoElementList.h" #undef CSS_PSEUDO_ELEMENT -// Array of nsStaticAtomSetup for each of the pseudo-elements. -static const nsStaticAtomSetup sCSSPseudoElementAtomSetup[] = { - #define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \ - NS_STATIC_ATOM_SUBCLASS_SETUP( \ - detail::gCSSPseudoElementAtoms, nsCSSPseudoElements, name_) - #include "nsCSSPseudoElementList.h" - #undef CSS_PSEUDO_ELEMENT -}; - -// Flags data for each of the pseudo-elements, which must be separate -// from the previous array since there's no place for it in -// nsStaticAtomSetup. +// Flags data for each of the pseudo-elements. /* static */ const uint32_t nsCSSPseudoElements::kPseudoElementFlags[] = { #define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \ flags_, #include "nsCSSPseudoElementList.h" #undef CSS_PSEUDO_ELEMENT }; void nsCSSPseudoElements::RegisterStaticAtoms() { - NS_RegisterStaticAtoms(sCSSPseudoElementAtomSetup); + NS_RegisterStaticAtoms(sAtoms, sAtomsLen); } bool nsCSSPseudoElements::IsPseudoElement(nsAtom *aAtom) { - return nsStaticAtomUtils::IsMember(aAtom, sCSSPseudoElementAtomSetup); + return nsStaticAtomUtils::IsMember(aAtom, sAtoms, sAtomsLen); } /* static */ bool nsCSSPseudoElements::IsCSS2PseudoElement(nsAtom *aAtom) { // We don't implement this using PseudoElementHasFlags because callers // want to pass things that could be anon boxes. NS_ASSERTION(nsCSSPseudoElements::IsPseudoElement(aAtom) || @@ -90,18 +84,17 @@ nsCSSPseudoElements::IsCSS2PseudoElement CSS_PSEUDO_ELEMENT_IS_CSS2), "result doesn't match flags"); return result; } /* static */ CSSPseudoElementType nsCSSPseudoElements::GetPseudoType(nsAtom *aAtom, EnabledState aEnabledState) { - Maybe<uint32_t> index = - nsStaticAtomUtils::Lookup(aAtom, sCSSPseudoElementAtomSetup); + Maybe<uint32_t> index = nsStaticAtomUtils::Lookup(aAtom, sAtoms, sAtomsLen); if (index.isSome()) { auto type = static_cast<Type>(*index); // ::moz-placeholder is an alias for ::placeholder if (type == CSSPseudoElementType::mozPlaceholder) { type = CSSPseudoElementType::placeholder; } return IsEnabled(type, aEnabledState) ? type : Type::NotPseudo; } @@ -121,19 +114,19 @@ nsCSSPseudoElements::GetPseudoType(nsAto } return Type::NotPseudo; } /* static */ nsAtom* nsCSSPseudoElements::GetPseudoAtom(Type aType) { - NS_ASSERTION(aType < Type::Count, "Unexpected type"); - return *sCSSPseudoElementAtomSetup[ - static_cast<CSSPseudoElementTypeBase>(aType)].mAtomp; + MOZ_ASSERT(aType < Type::Count, "Unexpected type"); + return const_cast<nsStaticAtom*>( + &sAtoms[static_cast<CSSPseudoElementTypeBase>(aType)]); } /* static */ already_AddRefed<nsAtom> nsCSSPseudoElements::GetPseudoAtom(const nsAString& aPseudoElement) { if (DOMStringIsNull(aPseudoElement) || aPseudoElement.IsEmpty() || aPseudoElement.First() != char16_t(':')) { return nullptr;
--- a/layout/style/nsCSSPseudoElements.h +++ b/layout/style/nsCSSPseudoElements.h @@ -51,16 +51,27 @@ // Can we use the ChromeOnly document.createElement(..., { pseudo: "::foo" }) // API for creating pseudo-implementing native anonymous content in JS with this // pseudo-element? #define CSS_PSEUDO_ELEMENT_IS_JS_CREATED_NAC (1<<6) // Does this pseudo-element act like an item for containers (such as flex and // grid containers) and thus needs parent display-based style fixup? #define CSS_PSEUDO_ELEMENT_IS_FLEX_OR_GRID_ITEM (1<<7) +// Trivial subclass of nsStaticAtom so that function signatures can require an +// atom from this atom list. +class nsICSSPseudoElement : public nsStaticAtom +{ +public: + constexpr nsICSSPseudoElement(const char16_t* aStr, uint32_t aLength, + uint32_t aStringOffset) + : nsStaticAtom(aStr, aLength, aStringOffset) + {} +}; + namespace mozilla { // The total count of CSSPseudoElement is less than 256, // so use uint8_t as its underlying type. typedef uint8_t CSSPseudoElementTypeBase; enum class CSSPseudoElementType : CSSPseudoElementTypeBase { // If the actual pseudo-elements stop being first here, change // GetPseudoType. @@ -83,32 +94,33 @@ namespace detail { struct CSSPseudoElementAtoms { #define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \ NS_STATIC_ATOM_DECL_STRING(name_, value_) #include "nsCSSPseudoElementList.h" #undef CSS_PSEUDO_ELEMENT - #define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \ - NS_STATIC_ATOM_DECL_ATOM(name_) - #include "nsCSSPseudoElementList.h" - #undef CSS_PSEUDO_ELEMENT + enum class Atoms { + #define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \ + NS_STATIC_ATOM_ENUM(name_) + #include "nsCSSPseudoElementList.h" + #undef CSS_PSEUDO_ELEMENT + AtomsCount + }; + + const nsICSSPseudoElement mAtoms[static_cast<size_t>(Atoms::AtomsCount)]; }; extern const CSSPseudoElementAtoms gCSSPseudoElementAtoms; } // namespace detail } // namespace mozilla -// Empty class derived from nsAtom so that function signatures can -// require an atom from this atom list. -class nsICSSPseudoElement : public nsAtom {}; - class nsCSSPseudoElements { typedef mozilla::CSSPseudoElementType Type; typedef mozilla::CSSEnabledState EnabledState; public: static void RegisterStaticAtoms(); @@ -119,20 +131,26 @@ public: // This must match EAGER_PSEUDO_COUNT in Rust code. static const size_t kEagerPseudoCount = 4; static bool IsEagerlyCascadedInServo(const Type aType) { return PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_IS_CSS2); } -#define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \ - NS_STATIC_ATOM_SUBCLASS_DECL_PTR(nsICSSPseudoElement, name_) -#include "nsCSSPseudoElementList.h" -#undef CSS_PSEUDO_ELEMENT +private: + static const nsStaticAtom* const sAtoms; + static constexpr size_t sAtomsLen = + mozilla::ArrayLength(mozilla::detail::gCSSPseudoElementAtoms.mAtoms); + +public: + #define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \ + NS_STATIC_ATOM_DECL_PTR(nsICSSPseudoElement, name_); + #include "nsCSSPseudoElementList.h" + #undef CSS_PSEUDO_ELEMENT static Type GetPseudoType(nsAtom* aAtom, EnabledState aEnabledState); // Get the atom for a given Type. aType must be < CSSPseudoElementType::Count. // This only ever returns static atoms, so it's fine to return a raw pointer. static nsAtom* GetPseudoAtom(Type aType); // Get the atom for a given pseudo-element string (e.g. "::before"). This can
--- a/layout/xul/nsMenuPopupFrame.cpp +++ b/layout/xul/nsMenuPopupFrame.cpp @@ -14,17 +14,16 @@ #include "nsNameSpaceManager.h" #include "nsViewManager.h" #include "nsWidgetsCID.h" #include "nsMenuFrame.h" #include "nsMenuBarFrame.h" #include "nsPopupSetFrame.h" #include "nsPIDOMWindow.h" #include "nsIDOMEvent.h" -#include "nsIDOMScreen.h" #include "nsIDOMXULMenuListElement.h" #include "nsIPresShell.h" #include "nsFrameManager.h" #include "nsIDocument.h" #include "nsRect.h" #include "nsIComponentManager.h" #include "nsBoxLayoutState.h" #include "nsIScrollableFrame.h"
--- a/parser/htmlparser/nsHTMLTags.cpp +++ b/parser/htmlparser/nsHTMLTags.cpp @@ -3,17 +3,16 @@ * 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/. */ #include "nsHTMLTags.h" #include "nsCRT.h" #include "nsDataHashtable.h" #include "nsReadableUtils.h" #include "nsString.h" -#include "nsStaticAtom.h" #include "nsUnicharUtils.h" #include "mozilla/HashFunctions.h" #include <algorithm> using namespace mozilla; // static array of unicode tag names #define HTML_TAG(_tag, _classname, _interfacename) (u"" #_tag),
--- a/parser/htmlparser/nsHTMLTags.h +++ b/parser/htmlparser/nsHTMLTags.h @@ -1,17 +1,16 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* 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/. */ #ifndef nsHTMLTags_h___ #define nsHTMLTags_h___ -#include "nsStaticAtom.h" #include "nsString.h" #include "nsDataHashtable.h" #include "nsHashKeys.h" /* Declare the enum list using the magic of preprocessing enum values are "eHTMLTag_foo" (where foo is the tag)
--- a/xpcom/ds/nsAtomTable.cpp +++ b/xpcom/ds/nsAtomTable.cpp @@ -274,17 +274,17 @@ class nsAtomTable public: nsAtomSubTable& SelectSubTable(AtomTableKey& aKey); void AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf, AtomsSizes& aSizes); void GC(GCKind aKind); already_AddRefed<nsAtom> Atomize(const nsAString& aUTF16String); already_AddRefed<nsAtom> Atomize(const nsACString& aUTF8String); already_AddRefed<nsAtom> AtomizeMainThread(const nsAString& aUTF16String); nsStaticAtom* GetStaticAtom(const nsAString& aUTF16String); - void RegisterStaticAtoms(const nsStaticAtomSetup* aSetup, uint32_t aCount); + void RegisterStaticAtoms(const nsStaticAtom* aAtoms, size_t aAtomsLen); // The result of this function may be imprecise if other threads are operating // on atoms concurrently. It's also slow, since it triggers a GC before // counting. size_t RacySlowCount(); // This hash table op is a static member of this class so that it can take // advantage of |friend| declarations. @@ -642,26 +642,23 @@ nsAtomSubTable::AddSizeOfExcludingThisLo aSizes.mTable += mTable.ShallowSizeOfExcludingThis(aMallocSizeOf); for (auto iter = mTable.Iter(); !iter.Done(); iter.Next()) { auto entry = static_cast<AtomTableEntry*>(iter.Get()); entry->mAtom->AddSizeOfIncludingThis(aMallocSizeOf, aSizes); } } void -nsAtomTable::RegisterStaticAtoms(const nsStaticAtomSetup* aSetup, - uint32_t aCount) +nsAtomTable::RegisterStaticAtoms(const nsStaticAtom* aAtoms, size_t aAtomsLen) { MOZ_ASSERT(NS_IsMainThread()); MOZ_RELEASE_ASSERT(!gStaticAtomsDone, "Static atom insertion is finished!"); - for (uint32_t i = 0; i < aCount; ++i) { - const nsStaticAtom* atom = aSetup[i].mAtom; - nsStaticAtom** atomp = aSetup[i].mAtomp; - + for (uint32_t i = 0; i < aAtomsLen; ++i) { + const nsStaticAtom* atom = &aAtoms[i]; MOZ_ASSERT(nsCRT::IsAscii(atom->String())); MOZ_ASSERT(NS_strlen(atom->String()) == atom->GetLength()); AtomTableKey key(atom); nsAtomSubTable& table = SelectSubTable(key); MutexAutoLock lock(table.mLock); AtomTableEntry* he = table.Add(key); @@ -671,25 +668,25 @@ nsAtomTable::RegisterStaticAtoms(const n // - Create a dynamic atom and then register a static atom with the same // string while the dynamic atom is alive. // Both cases can cause subtle bugs, and are disallowed. We're // programming in C++ here, not Smalltalk. nsAutoCString name; he->mAtom->ToUTF8String(name); MOZ_CRASH_UNSAFE_PRINTF("Atom for '%s' already exists", name.get()); } - he->mAtom = *atomp = const_cast<nsStaticAtom*>(atom); + he->mAtom = const_cast<nsStaticAtom*>(atom); } } void -RegisterStaticAtoms(const nsStaticAtomSetup* aSetup, uint32_t aCount) +NS_RegisterStaticAtoms(const nsStaticAtom* aAtoms, size_t aAtomsLen) { MOZ_ASSERT(gAtomTable); - gAtomTable->RegisterStaticAtoms(aSetup, aCount); + gAtomTable->RegisterStaticAtoms(aAtoms, aAtomsLen); } already_AddRefed<nsAtom> NS_Atomize(const char* aUTF8String) { MOZ_ASSERT(gAtomTable); return gAtomTable->Atomize(nsDependentCString(aUTF8String)); }
--- a/xpcom/ds/nsGkAtoms.cpp +++ b/xpcom/ds/nsGkAtoms.cpp @@ -9,35 +9,34 @@ namespace mozilla { namespace detail { MOZ_PUSH_DISABLE_INTEGRAL_CONSTANT_OVERFLOW_WARNING extern constexpr GkAtoms gGkAtoms = { #define GK_ATOM(name_, value_) NS_STATIC_ATOM_INIT_STRING(value_) #include "nsGkAtomList.h" #undef GK_ATOM - - #define GK_ATOM(name_, value_) \ - NS_STATIC_ATOM_INIT_ATOM(GkAtoms, name_, value_) - #include "nsGkAtomList.h" - #undef GK_ATOM + { + #define GK_ATOM(name_, value_) \ + NS_STATIC_ATOM_INIT_ATOM(nsStaticAtom, GkAtoms, name_, value_) + #include "nsGkAtomList.h" + #undef GK_ATOM + } }; MOZ_POP_DISABLE_INTEGRAL_CONSTANT_OVERFLOW_WARNING } // namespace detail } // namespace mozilla -#define GK_ATOM(name_, value_) NS_STATIC_ATOM_DEFN_PTR(nsGkAtoms, name_) +const nsStaticAtom* const nsGkAtoms::sAtoms = mozilla::detail::gGkAtoms.mAtoms; + +#define GK_ATOM(name_, value_) \ + NS_STATIC_ATOM_DEFN_PTR( \ + nsStaticAtom, mozilla::detail::GkAtoms, mozilla::detail::gGkAtoms, \ + nsGkAtoms, name_) #include "nsGkAtomList.h" #undef GK_ATOM -static const nsStaticAtomSetup sGkAtomSetup[] = { - #define GK_ATOM(name_, value_) \ - NS_STATIC_ATOM_SETUP(mozilla::detail::gGkAtoms, nsGkAtoms, name_) - #include "nsGkAtomList.h" - #undef GK_ATOM -}; - void nsGkAtoms::RegisterStaticAtoms() { - NS_RegisterStaticAtoms(sGkAtomSetup); + NS_RegisterStaticAtoms(sAtoms, sAtomsLen); }
--- a/xpcom/ds/nsGkAtoms.h +++ b/xpcom/ds/nsGkAtoms.h @@ -14,29 +14,39 @@ namespace mozilla { namespace detail { struct GkAtoms { #define GK_ATOM(name_, value_) NS_STATIC_ATOM_DECL_STRING(name_, value_) #include "nsGkAtomList.h" #undef GK_ATOM - #define GK_ATOM(name_, value_) NS_STATIC_ATOM_DECL_ATOM(name_) - #include "nsGkAtomList.h" - #undef GK_ATOM + enum class Atoms { + #define GK_ATOM(name_, value_) NS_STATIC_ATOM_ENUM(name_) + #include "nsGkAtomList.h" + #undef GK_ATOM + AtomsCount + }; + + const nsStaticAtom mAtoms[static_cast<size_t>(Atoms::AtomsCount)]; }; extern const GkAtoms gGkAtoms; } // namespace detail } // namespace mozilla class nsGkAtoms { +private: + static const nsStaticAtom* const sAtoms; + static constexpr size_t sAtomsLen = + mozilla::ArrayLength(mozilla::detail::gGkAtoms.mAtoms); + public: static void RegisterStaticAtoms(); - #define GK_ATOM(name_, value_) NS_STATIC_ATOM_DECL_PTR(name_) + #define GK_ATOM(name_, value_) NS_STATIC_ATOM_DECL_PTR(nsStaticAtom, name_) #include "nsGkAtomList.h" #undef GK_ATOM }; #endif /* nsGkAtoms_h___ */
--- a/xpcom/ds/nsStaticAtom.h +++ b/xpcom/ds/nsStaticAtom.h @@ -4,245 +4,259 @@ * 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/. */ #ifndef nsStaticAtom_h__ #define nsStaticAtom_h__ #include <stdint.h> #include "nsAtom.h" +#include "mozilla/ArrayUtils.h" #include "mozilla/Maybe.h" -// The following macros are used to define static atoms, typically in -// conjunction with a .h file that defines the names and values of the atoms. +// Static atoms are structured carefully to satisfy a lot of constraints. +// +// - We have ~2700 static atoms. They are divided across ~4 classes, with the +// majority in nsGkAtoms. +// +// - We want them to be constexpr so they end up in .rodata, and thus shared +// between processes, minimizing memory usage. +// +// - We need them to be in an array, so we can iterate over them (for +// registration and lookups). +// +// - Each static atom has a string literal associated with it. We can't use a +// pointer to the string literal because then the atoms won't end up in +// .rodata. Therefore the string literals and the atoms must be arranged in a +// way such that a numeric index can be used instead. This numeric index +// (nsStaticAtom::mStringOffset) must be computable at compile-time to keep +// the static atom constexpr. It should also not be too large (a uint32_t is +// reasonable). +// +// - Each static atom stores the hash value of its associated string literal; +// it's used in various ways. The hash value must be computed at +// compile-time, to keep the static atom constexpr. +// +// - As well as accessing each static atom via array indexing, we need an +// individual pointer, e.g. nsGkAtoms::foo. Ideally this would be constexpr +// so it doesn't take up any space in memory. Unfortunately MSVC's constexpr +// support is buggy and so this isn't possible yet. See bug 1449787. +// +// - The array of static atoms can't be in a .h file, because it's a huge +// constexpr expression, which would blow out compile times. But the +// individual pointers for the static atoms must be in a .h file so they are +// public. +// +// The macros below are used to define static atoms in a way that satisfies +// these constraints. They are used in conjunction with a .h file that defines +// the names and values of the atoms. // // For example, the .h file might be called MyAtomList.h and look like this: // // MY_ATOM(one, "one") // MY_ATOM(two, "two") // MY_ATOM(three, "three") // -// The code defining the static atoms should look something like this: -// -// ====> MyAtoms.h <==== -// -// namespace detail { -// -// struct MyAtoms -// { -// #define MY_ATOM(name_, value_) NS_STATIC_ATOM_DECL_STRING(name_, value_) -// #include "MyAtomList.h" -// #undef MY_ATOM -// -// #define MY_ATOM(name_, value_) NS_STATIC_ATOM_DECL_ATOM(name_) -// #include "MyAtomList.h" -// #undef MY_ATOM -// }; -// -// extern const MyAtoms gMyAtoms; -// -// } // namespace detail -// -// class nsMyAtoms -// { -// public: -// #define MY_ATOM(name_, value_) NS_STATIC_ATOM_DECL_PTR(name_) -// #include "MyAtomList.h" -// #undef MY_ATOM -// }; -// -// ====> MyAtoms.cpp <==== -// -// MOZ_PUSH_DISABLE_INTEGRAL_CONSTANT_OVERFLOW_WARNING -// static constexpr MyAtoms gMyAtoms = { -// #define MY_ATOM(name_, value_) NS_STATIC_ATOM_INIT_STRING(value_) -// #include "MyAtomList.h" -// #undef MY_ATOM -// -// #define MY_ATOM(name_, value_) NS_STATIC_ATOM_INIT_ATOM(MyAtoms, name_, value_) -// #include "MyAtomList.h" -// #undef MY_ATOM -// }; -// MOZ_POP_DISABLE_INTEGRAL_CONSTANT_OVERFLOW_WARNING -// -// #define MY_ATOM(name_, value_) NS_STATIC_ATOM_DEFN_PTR(nsMyAtoms, name_) -// #include "MyAtomList.h" -// #undef MY_ATOM -// -// static const nsStaticAtomSetup sMyAtomSetup[] = { -// #define MY_ATOM(name_, value_) NS_STATIC_ATOM_SETUP(mozilla::detail::gMyAtoms, nsMyAtoms, name_) -// #include "MyAtomList.h" -// #undef MY_ATOM -// }; -// -// The macros expand to the following: +// The code defining the static atoms should look something like the following. +// ("<<<"/"---"/">>>" markers are used below to indicate what the macros look +// like before and after expansion.) // // ====> MyAtoms.h <==== // // // A `detail` namespace is used because the things within it aren't // // directly referenced by external users of these static atoms. // namespace detail { // // // This `detail` class contains the atom strings and the atom objects. // // Because they are together in a class, the mStringOffset field of the // // atoms will be small and can be initialized at compile time. // struct MyAtoms // { +// <<< +// #define MY_ATOM(name_, value_) NS_STATIC_ATOM_DECL_STRING(name_, value_) +// #include "MyAtomList.h" +// #undef MY_ATOM +// --- // const char16_t one_string[4]; // const char16_t two_string[4]; // const char16_t three_string[6]; +// >>> // -// const nsStaticAtom one_atom; -// const nsStaticAtom two_atom; -// const nsStaticAtom three_atom; +// enum class Atoms { +// <<< +// #define MY_ATOM(name_, value_) NS_STATIC_ATOM_ENUM(name_) +// #include "MyAtomList.h" +// #undef MY_ATOM +// --- +// one, +// two, +// three, +// >>> +// AtomsCount +// }; +// +// const nsStaticAtom mAtoms[static_cast<size_t>(Atoms::AtomsCount)]; // }; // +// // The MyAtoms instance is `extern const` so it can be defined in a .cpp +// // file. // extern const MyAtoms gMyAtoms; // // } // namespace detail // // // This class holds the pointers to the individual atoms. // class nsMyAtoms // { +// private: +// // This is a useful handle to the array of atoms, used below and also +// // possibly by Rust code. +// static const nsStaticAtom* const sAtoms; +// +// // The number of atoms, used below. +// static constexpr size_t sAtomsLen = +// mozilla::ArrayLength(detail::gMyAtoms.mAtoms); +// // public: +// // The type is not `nsStaticAtom* const` -- even though these atoms are +// // immutable -- because they are often passed to functions with +// // `nsAtom*` parameters, i.e. that can be passed both dynamic and +// // static. +// <<< +// #define MY_ATOM(name_, value_) NS_STATIC_ATOM_DECL_PTR(nsStaticAtom, name_) +// #include "MyAtomList.h" +// #undef MY_ATOM +// --- // static nsStaticAtom* one; // static nsStaticAtom* two; // static nsStaticAtom* three; +// >>> // }; // // ====> MyAtoms.cpp <==== // +// namespace detail { +// // // Need to suppress some MSVC warning weirdness with WrappingMultiply(). // MOZ_PUSH_DISABLE_INTEGRAL_CONSTANT_OVERFLOW_WARNING // // Because this is `constexpr` it ends up in read-only memory where it can // // be shared between processes. -// extern constexpr MyAtoms gMyAtoms = { +// static constexpr MyAtoms gMyAtoms = { +// <<< +// #define MY_ATOM(name_, value_) NS_STATIC_ATOM_INIT_STRING(value_) +// #include "MyAtomList.h" +// #undef MY_ATOM +// --- // u"one", // u"two", // u"three", -// -// nsStaticAtom(u"one", 3, offsetof(MyAtoms, one_atom) - -// offsetof(MyAtoms, one_string)), -// nsStaticAtom(u"two", 3, offsetof(MyAtoms, two_atom) - -// offsetof(MyAtoms, two_string)), -// nsStaticAtom(u"three", 3, offsetof(MyAtoms, three_atom) - -// offsetof(MyAtoms, three_string)), +// >>> +// { +// <<< +// #define MY_ATOM(name_, value_) NS_STATIC_ATOM_INIT_ATOM(nsStaticAtom, MyAtoms, name_, value_) +// #include "MyAtomList.h" +// #undef MY_ATOM +// --- +// nsStaticAtom( +// u"one", 3, +// offsetof(MyAtoms, mAtoms[static_cast<size_t>(MyAtoms::Atoms::one)]) - +// offsetof(MyAtoms, one_string)), +// nsStaticAtom( +// u"two", 3, +// offsetof(MyAtoms, mAtoms[static_cast<size_t>(MyAtoms::Atoms::two)]) - +// offsetof(MyAtoms, two_string)), +// nsStaticAtom( +// u"three", 3, +// offsetof(MyAtoms, mAtoms[static_cast<size_t>(MyAtoms::Atoms::three)]) - +// offsetof(MyAtoms, three_string)), +// >>> +// } // }; // MOZ_POP_DISABLE_INTEGRAL_CONSTANT_OVERFLOW_WARNING // -// nsStaticAtom* MyAtoms::one; -// nsStaticAtom* MyAtoms::two; -// nsStaticAtom* MyAtoms::three; +// } // namespace detail +// +// const nsStaticAtom* const nsMyAtoms::sAtoms = +// mozilla::detail::gMyAtoms.mAtoms; // -// static const nsStaticAtomSetup sMyAtomSetup[] = { -// { &detail::gMyAtoms.one_atom, &nsMyAtoms::one }, -// { &detail::gMyAtoms.two_atom, &nsMyAtoms::two }, -// { &detail::gMyAtoms.three_atom, &nsMyAtoms::three }, -// }; +// <<< +// #define MY_ATOM(name_, value_) NS_STATIC_ATOM_DEFN_PTR(nsStaticAtom, detail::MyAtoms, detail::gMyAtoms, nsMyAtoms, name_) +// #include "MyAtomList.h" +// #undef MY_ATOM +// --- +// nsStaticAtom* nsMyAtoms::one = +// const_cast<nsStaticAtom*>(&detail::gMyAtoms.mAtoms[ +// static_cast<size_t>(detail::MyAtoms::Atoms::one)]); +// nsStaticAtom* nsMyAtoms::two = +// const_cast<nsStaticAtom*>(&detail::gMyAtoms.mAtoms[ +// static_cast<size_t>(detail::MyAtoms::Atoms::two)]); +// nsStaticAtom* nsMyAtoms::three = +// const_cast<nsStaticAtom*>(&detail::gMyAtoms.mAtoms[ +// static_cast<size_t>(detail::MyAtoms::Atoms::three)]); +// >>> // -// When RegisterStaticAtoms(sMyAtomSetup) is called it iterates over -// sMyAtomSetup[]. E.g. for the first atom it does roughly the following: -// - MyAtoms::one = one_atom -// - inserts one_atom into the atom table +// When NS_RegisterStaticAtoms(sAtoms, sAtomsLen) is called it iterates +// over the atoms, inserting them into the atom table. -// The declaration of the atom's string, which must be within the same `detail` -// class as NS_STATIC_ATOM_DECL_ATOM. +// The declaration of the atom's string. #define NS_STATIC_ATOM_DECL_STRING(name_, value_) \ const char16_t name_##_string[sizeof(value_)]; -// The declaration of the static atom itself, which must be within the same -// `detail` class as NS_STATIC_ATOM_DECL_STRING. -#define NS_STATIC_ATOM_DECL_ATOM(name_) \ - const nsStaticAtom name_##_atom; +// The enum value for the atom. +#define NS_STATIC_ATOM_ENUM(name_) \ + name_, -// The declaration of the pointer to the static atom, which must be within -// a class. -#define NS_STATIC_ATOM_DECL_PTR(name_) \ - static nsStaticAtom* name_; - -// Like NS_STATIC_ATOM_DECL, but for sub-classes of nsStaticAtom. -#define NS_STATIC_ATOM_SUBCLASS_DECL_PTR(type_, name_) \ +// The declaration of the pointer to the static atom. `type_` must be +// `nsStaticAtom` or a subclass thereof. +// XXX: Eventually this should be combined with NS_STATIC_ATOM_DEFN_PTR and the +// pointer should be made `constexpr`. See bug 1449787. +#define NS_STATIC_ATOM_DECL_PTR(type_, name_) \ static type_* name_; -// The initialization of the atom's string, which must be within a `constexpr` -// instance of the `detail` class. +// The initialization of the atom's string. #define NS_STATIC_ATOM_INIT_STRING(value_) \ u"" value_, -// The initialization of the static atom itself, which must be within a -// `constexpr` instance of the `detail` class. +// The initialization of the atom itself. `type_` must be `nsStaticAtom` or a +// subclass thereof. // // Note that |value_| is an 8-bit string, and so |sizeof(value_)| is equal // to the number of chars (including the terminating '\0'). The |u""| prefix // converts |value_| to a 16-bit string. -#define NS_STATIC_ATOM_INIT_ATOM(class_, name_, value_) \ - nsStaticAtom(u"" value_, \ - sizeof(value_) - 1, \ - offsetof(class_, name_##_atom) - \ - offsetof(class_, name_##_string)), - -// The definition of the pointer to the static atom. Initially null, it is -// set by RegisterStaticAtoms() to point to a heap-allocated nsStaticAtom. -#define NS_STATIC_ATOM_DEFN_PTR(class_, name_) \ - nsStaticAtom* class_::name_; - -// Like NS_STATIC_ATOM_DEFN, but for sub-classes of nsStaticAtom. -#define NS_STATIC_ATOM_SUBCLASS_DEFN_PTR(type_, class_, name_) \ - type_* class_::name_; +#define NS_STATIC_ATOM_INIT_ATOM(type_, detailClass_, name_, value_) \ + type_(u"" value_, \ + sizeof(value_) - 1, \ + offsetof(detailClass_, \ + mAtoms[static_cast<size_t>(detailClass_::Atoms::name_)]) - \ + offsetof(detailClass_, name_##_string)), -// The StaticAtomSetup. Used during start-up, and in some cases afterwards. -#define NS_STATIC_ATOM_SETUP(detailObj_, class_, name_) \ - { &detailObj_.name_##_atom, &class_::name_ }, - -// Like NS_STATIC_ATOM_SUBCLASS, but for sub-classes of nsStaticAtom. -#define NS_STATIC_ATOM_SUBCLASS_SETUP(detailObj_, class_, name_) \ - { &detailObj_.name_##_atom, \ - reinterpret_cast<nsStaticAtom**>(&class_::name_) }, - -// Holds data used to initialize large number of atoms during startup. Use -// NS_STATIC_ATOM_SETUP to initialize these structs. -struct nsStaticAtomSetup -{ - const nsStaticAtom* const mAtom; - nsStaticAtom** const mAtomp; -}; +// Definition of the pointer to the static atom. `type_` must be `nsStaticAtom` +// or a subclass thereof. +#define NS_STATIC_ATOM_DEFN_PTR(type_, detailClass_, detailObj_, class_, name_) \ + type_* class_::name_ = const_cast<type_*>( \ + &detailObj_.mAtoms[static_cast<size_t>(detailClass_::Atoms::name_)]); // Register an array of static atoms with the atom table. -template<uint32_t N> void -NS_RegisterStaticAtoms(const nsStaticAtomSetup (&aSetup)[N]) -{ - extern void RegisterStaticAtoms(const nsStaticAtomSetup* aSetup, - uint32_t aCount); - RegisterStaticAtoms(aSetup, N); -} +NS_RegisterStaticAtoms(const nsStaticAtom* aAtoms, size_t aAtomsLen); // This class holds basic operations on arrays of static atoms. class nsStaticAtomUtils { public: - template<uint32_t N> - static mozilla::Maybe<uint32_t> Lookup(nsAtom *aAtom, - const nsStaticAtomSetup (&aSetup)[N]) - { - return Lookup(aAtom, aSetup, N); - } - - template<uint32_t N> - static bool IsMember(nsAtom *aAtom, const nsStaticAtomSetup (&aSetup)[N]) - { - return Lookup(aAtom, aSetup, N).isSome(); - } - -private: static mozilla::Maybe<uint32_t> Lookup(nsAtom* aAtom, - const nsStaticAtomSetup* aSetup, + const nsStaticAtom* aAtoms, uint32_t aCount) { for (uint32_t i = 0; i < aCount; i++) { - if (aAtom == *(aSetup[i].mAtomp)) { + if (aAtom == &aAtoms[i]) { return mozilla::Some(i); } } return mozilla::Nothing(); } + + static bool IsMember(nsAtom* aAtom, const nsStaticAtom* aAtoms, + uint32_t aCount) + { + return Lookup(aAtom, aAtoms, aCount).isSome(); + } }; #endif
--- a/xpcom/io/nsDirectoryService.cpp +++ b/xpcom/io/nsDirectoryService.cpp @@ -7,17 +7,16 @@ #include "mozilla/ArrayUtils.h" #include "nsCOMPtr.h" #include "nsAutoPtr.h" #include "nsDirectoryService.h" #include "nsLocalFile.h" #include "nsDebug.h" #include "nsGkAtoms.h" -#include "nsStaticAtom.h" #include "nsEnumeratorUtils.h" #include "nsICategoryManager.h" #include "nsISimpleEnumerator.h" #include "nsIStringEnumerator.h" #if defined(XP_WIN) #include <windows.h> @@ -98,56 +97,54 @@ nsDirectoryService::Create(nsISupports* namespace mozilla { namespace detail { MOZ_PUSH_DISABLE_INTEGRAL_CONSTANT_OVERFLOW_WARNING extern constexpr DirectoryAtoms gDirectoryAtoms = { #define DIR_ATOM(name_, value_) NS_STATIC_ATOM_INIT_STRING(value_) #include "nsDirectoryServiceAtomList.h" #undef DIR_ATOM - - #define DIR_ATOM(name_, value_) \ - NS_STATIC_ATOM_INIT_ATOM(DirectoryAtoms, name_, value_) - #include "nsDirectoryServiceAtomList.h" - #undef DIR_ATOM + { + #define DIR_ATOM(name_, value_) \ + NS_STATIC_ATOM_INIT_ATOM(nsStaticAtom, DirectoryAtoms, name_, value_) + #include "nsDirectoryServiceAtomList.h" + #undef DIR_ATOM + } }; MOZ_POP_DISABLE_INTEGRAL_CONSTANT_OVERFLOW_WARNING } // namespace detail } // namespace mozilla +const nsStaticAtom* const nsDirectoryService::sAtoms = + mozilla::detail::gDirectoryAtoms.mAtoms; + #define DIR_ATOM(name_, value_) \ - NS_STATIC_ATOM_DEFN_PTR(nsDirectoryService, name_) + NS_STATIC_ATOM_DEFN_PTR( \ + nsStaticAtom, mozilla::detail::DirectoryAtoms, \ + mozilla::detail::gDirectoryAtoms, nsDirectoryService, name_) #include "nsDirectoryServiceAtomList.h" #undef DIR_ATOM -static const nsStaticAtomSetup sDirectoryServiceAtomSetup[] = { - #define DIR_ATOM(name_, value_) \ - NS_STATIC_ATOM_SETUP( \ - mozilla::detail::gDirectoryAtoms, nsDirectoryService, name_) - #include "nsDirectoryServiceAtomList.h" - #undef DIR_ATOM -}; - NS_IMETHODIMP nsDirectoryService::Init() { NS_NOTREACHED("nsDirectoryService::Init() for internal use only!"); return NS_OK; } void nsDirectoryService::RealInit() { NS_ASSERTION(!gService, "nsDirectoryService::RealInit Mustn't initialize twice!"); gService = new nsDirectoryService(); - NS_RegisterStaticAtoms(sDirectoryServiceAtomSetup); + NS_RegisterStaticAtoms(sAtoms, sAtomsLen); // Let the list hold the only reference to the provider. nsAppFileLocationProvider* defaultProvider = new nsAppFileLocationProvider; gService->mProviders.AppendElement(defaultProvider); } nsDirectoryService::~nsDirectoryService() {
--- a/xpcom/io/nsDirectoryService.h +++ b/xpcom/io/nsDirectoryService.h @@ -25,19 +25,24 @@ namespace mozilla { namespace detail { struct DirectoryAtoms { #define DIR_ATOM(name_, value_) NS_STATIC_ATOM_DECL_STRING(name_, value_) #include "nsDirectoryServiceAtomList.h" #undef DIR_ATOM - #define DIR_ATOM(name_, value_) NS_STATIC_ATOM_DECL_ATOM(name_) - #include "nsDirectoryServiceAtomList.h" - #undef DIR_ATOM + enum class Atoms { + #define DIR_ATOM(name_, value_) NS_STATIC_ATOM_ENUM(name_) + #include "nsDirectoryServiceAtomList.h" + #undef DIR_ATOM + AtomsCount + }; + + const nsStaticAtom mAtoms[static_cast<size_t>(Atoms::AtomsCount)]; }; extern const DirectoryAtoms gDirectoryAtoms; } // namespace detail } // namespace mozilla class nsDirectoryService final @@ -69,15 +74,19 @@ public: private: ~nsDirectoryService(); nsresult GetCurrentProcessDirectory(nsIFile** aFile); nsInterfaceHashtable<nsCStringHashKey, nsIFile> mHashtable; nsTArray<nsCOMPtr<nsIDirectoryServiceProvider>> mProviders; + static const nsStaticAtom* const sAtoms; + static constexpr size_t sAtomsLen = + mozilla::ArrayLength(mozilla::detail::gDirectoryAtoms.mAtoms); + public: - #define DIR_ATOM(name_, value_) NS_STATIC_ATOM_DECL_PTR(name_) + #define DIR_ATOM(name_, value_) NS_STATIC_ATOM_DECL_PTR(nsStaticAtom, name_) #include "nsDirectoryServiceAtomList.h" #undef DIR_ATOM }; #endif
--- a/xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp +++ b/xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp @@ -20,17 +20,16 @@ #include "nsIDOMEventTarget.h" #include "nsIDOMGeoPositionError.h" #include "nsIDOMHTMLInputElement.h" #include "nsIDOMNode.h" #include "nsIDOMNodeList.h" #include "nsIDOMOfflineResourceList.h" #include "nsIDOMParser.h" #include "nsIDOMRange.h" -#include "nsIDOMScreen.h" #include "nsIDOMSerializer.h" #include "nsIDOMXMLDocument.h" #include "nsIDOMXULElement.h" #include "nsIListBoxObject.h" #include "nsIMessageManager.h" #include "nsISelection.h" #include "nsITreeBoxObject.h" #include "nsIWebBrowserPersistable.h" @@ -64,17 +63,16 @@ #include "mozilla/dom/NodeBinding.h" #include "mozilla/dom/EventBinding.h" #include "mozilla/dom/OfflineResourceListBinding.h" #include "mozilla/dom/PositionErrorBinding.h" #include "mozilla/dom/RangeBinding.h" #ifdef MOZ_WEBRTC #include "mozilla/dom/RTCDataChannelBinding.h" #endif -#include "mozilla/dom/ScreenBinding.h" #include "mozilla/dom/SelectionBinding.h" #include "mozilla/dom/StorageEventBinding.h" #include "mozilla/dom/StyleSheetBinding.h" #include "mozilla/dom/StyleSheetListBinding.h" #include "mozilla/dom/SVGElementBinding.h" #include "mozilla/dom/TimeEventBinding.h" #include "mozilla/dom/TreeBoxObjectBinding.h" #include "mozilla/dom/XMLDocumentBinding.h" @@ -153,17 +151,16 @@ const ComponentsInterfaceShimEntry kComp DEFINE_SHIM(NodeList), DEFINE_SHIM(Node), DEFINE_SHIM(OfflineResourceList), DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIDOMParser, DOMParser), DEFINE_SHIM(Range), #ifdef MOZ_WEBRTC DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIDOMDataChannel, RTCDataChannel), #endif - DEFINE_SHIM(Screen), DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIDOMSerializer, XMLSerializer), DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsITreeBoxObject, TreeBoxObject), DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIWebBrowserPersistable, FrameLoader), DEFINE_SHIM(XMLDocument), DEFINE_SHIM(XULElement), DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsISelection, Selection), };
--- a/xpcom/string/nsSubstring.cpp +++ b/xpcom/string/nsSubstring.cpp @@ -18,17 +18,16 @@ #include <stdlib.h> #include "nsAString.h" #include "nsString.h" #include "nsStringBuffer.h" #include "nsDependentString.h" #include "nsPrintfCString.h" #include "nsMemory.h" #include "prprf.h" -#include "nsStaticAtom.h" #include "nsCOMPtr.h" #include "mozilla/IntegerPrintfMacros.h" #ifdef XP_WIN #include <windows.h> #include <process.h> #define getpid() _getpid() #define pthread_self() GetCurrentThreadId()
--- a/xpcom/tests/gtest/TestAtoms.cpp +++ b/xpcom/tests/gtest/TestAtoms.cpp @@ -5,17 +5,16 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/ArrayUtils.h" #include "nsAtom.h" #include "nsString.h" #include "UTFStrings.h" #include "nsIServiceManager.h" -#include "nsStaticAtom.h" #include "nsThreadUtils.h" #include "gtest/gtest.h" using namespace mozilla; int32_t NS_GetUnusedAtomCount(void);
--- a/xpfe/appshell/nsXULWindow.cpp +++ b/xpfe/appshell/nsXULWindow.cpp @@ -15,26 +15,27 @@ #include "nsString.h" #include "nsWidgetsCID.h" #include "nsThreadUtils.h" #include "nsNetCID.h" #include "nsQueryObject.h" #include "mozilla/Sprintf.h" //Interfaces needed to be included +#include "nsGlobalWindowOuter.h" #include "nsIAppShell.h" #include "nsIAppShellService.h" #include "nsIServiceManager.h" #include "nsIContentViewer.h" #include "nsIDocument.h" #include "nsIDOMDocument.h" #include "nsIDOMElement.h" #include "nsIDOMXULElement.h" #include "nsPIDOMWindow.h" -#include "nsIDOMScreen.h" +#include "nsScreen.h" #include "nsIEmbeddingSiteWindow.h" #include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestorUtils.h" #include "nsIIOService.h" #include "nsILoadContext.h" #include "nsIObserverService.h" #include "nsIWindowMediator.h" #include "nsIScreenManager.h" @@ -1023,33 +1024,35 @@ NS_IMETHODIMP nsXULWindow::EnsureAuthPro if (wwatch) wwatch->GetNewAuthPrompter(ourWindow, getter_AddRefs(mAuthPrompter)); } return mAuthPrompter ? NS_OK : NS_ERROR_FAILURE; } NS_IMETHODIMP nsXULWindow::GetAvailScreenSize(int32_t* aAvailWidth, int32_t* aAvailHeight) { - nsresult rv; - nsCOMPtr<mozIDOMWindowProxy> domWindow; GetWindowDOMWindow(getter_AddRefs(domWindow)); NS_ENSURE_STATE(domWindow); - auto* window = nsPIDOMWindowOuter::From(domWindow); - NS_ENSURE_STATE(window); + auto* window = nsGlobalWindowOuter::Cast(domWindow); - nsCOMPtr<nsIDOMScreen> screen = window->GetScreen(); + RefPtr<nsScreen> screen = window->GetScreen(); NS_ENSURE_STATE(screen); - rv = screen->GetAvailWidth(aAvailWidth); - NS_ENSURE_SUCCESS(rv, rv); + ErrorResult rv; + *aAvailWidth = screen->GetAvailWidth(rv); + if (NS_WARN_IF(rv.Failed())) { + return rv.StealNSResult(); + } - rv = screen->GetAvailHeight(aAvailHeight); - NS_ENSURE_SUCCESS(rv, rv); + *aAvailHeight = screen->GetAvailHeight(rv); + if (NS_WARN_IF(rv.Failed())) { + return rv.StealNSResult(); + } return NS_OK; } // Rounds window size to 1000x1000, or, if there isn't enough available // screen space, to a multiple of 200x100. NS_IMETHODIMP nsXULWindow::ForceRoundedDimensions() {