Bug 1835529 [wpt PR 40276] - Update wpt metadata, a=testonly
[gecko.git] / dom / xul / XULMenuBarElement.cpp
blobffb7adc7842b57f7f419dd58bcae5273cd835110
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "XULMenuBarElement.h"
8 #include "MenuBarListener.h"
9 #include "XULButtonElement.h"
10 #include "nsXULPopupManager.h"
11 #include "mozilla/Assertions.h"
12 #include "mozilla/dom/BindContext.h"
13 #include "mozilla/AsyncEventDispatcher.h"
15 namespace mozilla::dom {
17 NS_IMPL_CYCLE_COLLECTION_CLASS(XULMenuBarElement)
18 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(XULMenuBarElement,
19 XULMenuParentElement)
20 if (tmp->mListener) {
21 tmp->mListener->Detach();
22 tmp->mListener = nullptr;
24 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
25 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(XULMenuBarElement,
26 XULMenuParentElement)
27 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mListener)
28 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
29 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(XULMenuBarElement,
30 XULMenuParentElement)
32 XULMenuBarElement::XULMenuBarElement(
33 already_AddRefed<class NodeInfo>&& aNodeInfo)
34 : XULMenuParentElement(std::move(aNodeInfo)) {}
36 XULMenuBarElement::~XULMenuBarElement() { MOZ_DIAGNOSTIC_ASSERT(!mListener); }
38 void XULMenuBarElement::SetActive(bool aActiveFlag) {
39 // If the activity is not changed, there is nothing to do.
40 if (mIsActive == aActiveFlag) {
41 return;
44 // We can't activate a menubar outside of the document.
45 if (!IsInComposedDoc()) {
46 MOZ_ASSERT(!mIsActive, "How?");
47 return;
50 if (!aActiveFlag) {
51 // If there is a request to deactivate the menu bar, check to see whether
52 // there is a menu popup open for the menu bar. In this case, don't
53 // deactivate the menu bar.
54 if (auto* activeChild = GetActiveMenuChild()) {
55 if (activeChild->IsMenuPopupOpen()) {
56 return;
61 mIsActive = aActiveFlag;
62 if (nsXULPopupManager* pm = nsXULPopupManager::GetInstance()) {
63 pm->SetActiveMenuBar(this, aActiveFlag);
65 if (!aActiveFlag) {
66 mActiveByKeyboard = false;
67 SetActiveMenuChild(nullptr);
70 RefPtr dispatcher = new AsyncEventDispatcher(
71 this, aActiveFlag ? u"DOMMenuBarActive"_ns : u"DOMMenuBarInactive"_ns,
72 CanBubble::eYes, ChromeOnlyDispatch::eNo);
73 DebugOnly<nsresult> rv = dispatcher->PostDOMEvent();
74 NS_ASSERTION(NS_SUCCEEDED(rv), "AsyncEventDispatcher failed to dispatch");
77 nsresult XULMenuBarElement::BindToTree(BindContext& aContext,
78 nsINode& aParent) {
79 MOZ_TRY(XULMenuParentElement::BindToTree(aContext, aParent));
80 MOZ_DIAGNOSTIC_ASSERT(!mListener);
81 if (aContext.InComposedDoc()) {
82 mListener = new MenuBarListener(*this);
84 return NS_OK;
87 void XULMenuBarElement::UnbindFromTree(bool aNullParent) {
88 if (mListener) {
89 mListener->Detach();
90 mListener = nullptr;
92 if (NS_WARN_IF(mIsActive)) {
93 // Clean up silently when getting removed from the document while active.
94 mIsActive = false;
95 if (nsXULPopupManager* pm = nsXULPopupManager::GetInstance()) {
96 pm->SetActiveMenuBar(this, false);
99 return XULMenuParentElement::UnbindFromTree(aNullParent);
102 } // namespace mozilla::dom