no bug - Import translations from android-l10n r=release a=l10n CLOSED TREE
[gecko.git] / dom / xul / XULMenuBarElement.cpp
blob1ec36d38593bfa78e7be5305b55e0dd62886e83e
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"
14 #include "mozilla/Try.h"
16 namespace mozilla::dom {
18 NS_IMPL_CYCLE_COLLECTION_CLASS(XULMenuBarElement)
19 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(XULMenuBarElement,
20 XULMenuParentElement)
21 if (tmp->mListener) {
22 tmp->mListener->Detach();
23 tmp->mListener = nullptr;
25 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
26 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(XULMenuBarElement,
27 XULMenuParentElement)
28 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mListener)
29 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
30 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(XULMenuBarElement,
31 XULMenuParentElement)
33 XULMenuBarElement::XULMenuBarElement(
34 already_AddRefed<class NodeInfo>&& aNodeInfo)
35 : XULMenuParentElement(std::move(aNodeInfo)) {}
37 XULMenuBarElement::~XULMenuBarElement() { MOZ_DIAGNOSTIC_ASSERT(!mListener); }
39 void XULMenuBarElement::SetActive(bool aActiveFlag) {
40 // If the activity is not changed, there is nothing to do.
41 if (mIsActive == aActiveFlag) {
42 return;
45 // We can't activate a menubar outside of the document.
46 if (!IsInComposedDoc()) {
47 MOZ_ASSERT(!mIsActive, "How?");
48 return;
51 if (!aActiveFlag) {
52 // If there is a request to deactivate the menu bar, check to see whether
53 // there is a menu popup open for the menu bar. In this case, don't
54 // deactivate the menu bar.
55 if (auto* activeChild = GetActiveMenuChild()) {
56 if (activeChild->IsMenuPopupOpen()) {
57 return;
62 mIsActive = aActiveFlag;
63 if (nsXULPopupManager* pm = nsXULPopupManager::GetInstance()) {
64 pm->SetActiveMenuBar(this, aActiveFlag);
66 if (!aActiveFlag) {
67 mActiveByKeyboard = false;
68 SetActiveMenuChild(nullptr);
71 RefPtr dispatcher = new AsyncEventDispatcher(
72 this, aActiveFlag ? u"DOMMenuBarActive"_ns : u"DOMMenuBarInactive"_ns,
73 CanBubble::eYes, ChromeOnlyDispatch::eNo);
74 DebugOnly<nsresult> rv = dispatcher->PostDOMEvent();
75 NS_ASSERTION(NS_SUCCEEDED(rv), "AsyncEventDispatcher failed to dispatch");
78 nsresult XULMenuBarElement::BindToTree(BindContext& aContext,
79 nsINode& aParent) {
80 MOZ_TRY(XULMenuParentElement::BindToTree(aContext, aParent));
81 MOZ_DIAGNOSTIC_ASSERT(!mListener);
82 if (aContext.InComposedDoc()) {
83 mListener = new MenuBarListener(*this);
85 return NS_OK;
88 void XULMenuBarElement::UnbindFromTree(UnbindContext& aContext) {
89 if (mListener) {
90 mListener->Detach();
91 mListener = nullptr;
93 if (NS_WARN_IF(mIsActive)) {
94 // Clean up silently when getting removed from the document while active.
95 mIsActive = false;
96 if (nsXULPopupManager* pm = nsXULPopupManager::GetInstance()) {
97 pm->SetActiveMenuBar(this, false);
100 return XULMenuParentElement::UnbindFromTree(aContext);
103 } // namespace mozilla::dom