tor-browser

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

PopoverData.cpp (3332B)


      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 "PopoverData.h"
      8 
      9 #include "mozilla/dom/CloseWatcher.h"
     10 #include "mozilla/dom/CloseWatcherManager.h"
     11 #include "mozilla/dom/Document.h"
     12 #include "nsGenericHTMLElement.h"
     13 #include "nsIDOMEventListener.h"
     14 
     15 namespace mozilla::dom {
     16 
     17 class PopoverCloseWatcherListener : public nsIDOMEventListener {
     18 public:
     19  NS_DECL_ISUPPORTS
     20 
     21  explicit PopoverCloseWatcherListener(nsGenericHTMLElement* aPopover) {
     22    mPopover = do_GetWeakReference(aPopover);
     23  };
     24 
     25  NS_IMETHODIMP MOZ_CAN_RUN_SCRIPT HandleEvent(Event* aEvent) override {
     26    RefPtr<nsINode> node = do_QueryReferent(mPopover);
     27    if (RefPtr<nsGenericHTMLElement> popover =
     28            nsGenericHTMLElement::FromNodeOrNull(node)) {
     29      nsAutoString eventType;
     30      aEvent->GetType(eventType);
     31      if (eventType.EqualsLiteral("close")) {
     32        popover->HidePopover(IgnoreErrors());
     33      }
     34    }
     35    return NS_OK;
     36  }
     37 
     38 private:
     39  virtual ~PopoverCloseWatcherListener() = default;
     40  nsWeakPtr mPopover;
     41 };
     42 NS_IMPL_ISUPPORTS(PopoverCloseWatcherListener, nsIDOMEventListener)
     43 
     44 void PopoverData::EnsureCloseWatcher(nsGenericHTMLElement* aElement) {
     45  if (!mCloseWatcher) {
     46    RefPtr<Document> doc = aElement->OwnerDoc();
     47    if (doc->IsActive() && doc->IsCurrentActiveDocument()) {
     48      if (RefPtr<nsPIDOMWindowInner> window = doc->GetInnerWindow()) {
     49        mCloseWatcher = new CloseWatcher(window);
     50        RefPtr<PopoverCloseWatcherListener> eventListener =
     51            new PopoverCloseWatcherListener(aElement);
     52        mCloseWatcher->AddSystemEventListener(u"close"_ns, eventListener,
     53                                              false /* aUseCapture */,
     54                                              false /* aWantsUntrusted */);
     55 
     56        mCloseWatcher->AddToWindowsCloseWatcherManager();
     57      }
     58    }
     59  }
     60 }
     61 
     62 CloseWatcher* PopoverData::GetCloseWatcher() { return mCloseWatcher; }
     63 
     64 // https://html.spec.whatwg.org/#hide-popover-algorithm
     65 // Step 6.2
     66 void PopoverData::DestroyCloseWatcher() {
     67  // 6.2. If element's popover close watcher is not null, then:
     68  if (mCloseWatcher) {
     69    // 6.2.1. Destroy element's popover close watcher.
     70    mCloseWatcher->Destroy();
     71    // 6.2.2. Set element's popover close watcher to null.
     72    mCloseWatcher = nullptr;
     73  }
     74 };
     75 
     76 PopoverToggleEventTask::PopoverToggleEventTask(nsWeakPtr aElement,
     77                                               nsWeakPtr aSource,
     78                                               PopoverVisibilityState aOldState)
     79    : Runnable("PopoverToggleEventTask"),
     80      mElement(std::move(aElement)),
     81      mSource(std::move(aSource)),
     82      mOldState(aOldState) {}
     83 
     84 NS_IMETHODIMP
     85 PopoverToggleEventTask::Run() {
     86  nsCOMPtr<Element> element = do_QueryReferent(mElement);
     87  nsCOMPtr<Element> source = do_QueryReferent(mSource);
     88  if (!element) {
     89    return NS_OK;
     90  }
     91  if (auto* htmlElement = nsGenericHTMLElement::FromNode(element)) {
     92    MOZ_KnownLive(htmlElement)
     93        ->RunPopoverToggleEventTask(this, mOldState, source);
     94  }
     95  return NS_OK;
     96 };
     97 
     98 }  // namespace mozilla::dom