tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

XULMenuBarElement.cpp (3490B)


      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/. */
      6 
      7 #include "XULMenuBarElement.h"
      8 
      9 #include "MenuBarListener.h"
     10 #include "XULButtonElement.h"
     11 #include "mozilla/Assertions.h"
     12 #include "mozilla/AsyncEventDispatcher.h"
     13 #include "mozilla/Try.h"
     14 #include "mozilla/dom/BindContext.h"
     15 #include "nsXULPopupManager.h"
     16 
     17 namespace mozilla::dom {
     18 
     19 NS_IMPL_CYCLE_COLLECTION_CLASS(XULMenuBarElement)
     20 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(XULMenuBarElement,
     21                                                XULMenuParentElement)
     22  if (tmp->mListener) {
     23    tmp->mListener->Detach();
     24    tmp->mListener = nullptr;
     25  }
     26 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     27 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(XULMenuBarElement,
     28                                                  XULMenuParentElement)
     29  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mListener)
     30 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     31 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(XULMenuBarElement,
     32                                               XULMenuParentElement)
     33 
     34 XULMenuBarElement::XULMenuBarElement(
     35    already_AddRefed<class NodeInfo>&& aNodeInfo)
     36    : XULMenuParentElement(std::move(aNodeInfo)) {}
     37 
     38 XULMenuBarElement::~XULMenuBarElement() { MOZ_DIAGNOSTIC_ASSERT(!mListener); }
     39 
     40 void XULMenuBarElement::SetActive(bool aActiveFlag) {
     41  // If the activity is not changed, there is nothing to do.
     42  if (mIsActive == aActiveFlag) {
     43    return;
     44  }
     45 
     46  // We can't activate a menubar outside of the document.
     47  if (!IsInComposedDoc()) {
     48    MOZ_ASSERT(!mIsActive, "How?");
     49    return;
     50  }
     51 
     52  if (!aActiveFlag) {
     53    // If there is a request to deactivate the menu bar, check to see whether
     54    // there is a menu popup open for the menu bar. In this case, don't
     55    // deactivate the menu bar.
     56    if (auto* activeChild = GetActiveMenuChild()) {
     57      if (activeChild->IsMenuPopupOpen()) {
     58        return;
     59      }
     60    }
     61  }
     62 
     63  mIsActive = aActiveFlag;
     64  if (nsXULPopupManager* pm = nsXULPopupManager::GetInstance()) {
     65    pm->SetActiveMenuBar(this, aActiveFlag);
     66  }
     67  if (!aActiveFlag) {
     68    mActiveByKeyboard = false;
     69    SetActiveMenuChild(nullptr);
     70  }
     71 
     72  RefPtr dispatcher = new AsyncEventDispatcher(
     73      this, aActiveFlag ? u"DOMMenuBarActive"_ns : u"DOMMenuBarInactive"_ns,
     74      CanBubble::eYes, ChromeOnlyDispatch::eNo);
     75  DebugOnly<nsresult> rv = dispatcher->PostDOMEvent();
     76  NS_ASSERTION(NS_SUCCEEDED(rv), "AsyncEventDispatcher failed to dispatch");
     77 }
     78 
     79 nsresult XULMenuBarElement::BindToTree(BindContext& aContext,
     80                                       nsINode& aParent) {
     81  MOZ_TRY(XULMenuParentElement::BindToTree(aContext, aParent));
     82  MOZ_DIAGNOSTIC_ASSERT(!mListener);
     83  if (aContext.InComposedDoc()) {
     84    mListener = new MenuBarListener(*this);
     85  }
     86  return NS_OK;
     87 }
     88 
     89 void XULMenuBarElement::UnbindFromTree(UnbindContext& aContext) {
     90  if (mListener) {
     91    mListener->Detach();
     92    mListener = nullptr;
     93  }
     94  if (NS_WARN_IF(mIsActive)) {
     95    // Clean up silently when getting removed from the document while active.
     96    mIsActive = false;
     97    if (nsXULPopupManager* pm = nsXULPopupManager::GetInstance()) {
     98      pm->SetActiveMenuBar(this, false);
     99    }
    100  }
    101  return XULMenuParentElement::UnbindFromTree(aContext);
    102 }
    103 
    104 }  // namespace mozilla::dom