tor-browser

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

HTMLSummaryElement.cpp (3813B)


      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 "mozilla/dom/HTMLSummaryElement.h"
      8 
      9 #include "mozilla/EventDispatcher.h"
     10 #include "mozilla/MouseEvents.h"
     11 #include "mozilla/Preferences.h"
     12 #include "mozilla/TextEvents.h"
     13 #include "mozilla/dom/HTMLDetailsElement.h"
     14 #include "mozilla/dom/HTMLElementBinding.h"
     15 #include "mozilla/dom/HTMLUnknownElement.h"
     16 #include "nsFocusManager.h"
     17 
     18 NS_IMPL_NS_NEW_HTML_ELEMENT(Summary)
     19 
     20 namespace mozilla::dom {
     21 
     22 HTMLSummaryElement::~HTMLSummaryElement() = default;
     23 
     24 NS_IMPL_ELEMENT_CLONE(HTMLSummaryElement)
     25 
     26 nsresult HTMLSummaryElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
     27  nsresult rv = NS_OK;
     28  if (!aVisitor.mPresContext) {
     29    return rv;
     30  }
     31 
     32  if (aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault) {
     33    return rv;
     34  }
     35 
     36  if (!IsMainSummary()) {
     37    return rv;
     38  }
     39 
     40  WidgetEvent* const event = aVisitor.mEvent;
     41  nsCOMPtr<Element> target =
     42      do_QueryInterface(event->GetOriginalDOMEventTarget());
     43  if (nsContentUtils::IsInInteractiveHTMLContent(target, this)) {
     44    return NS_OK;
     45  }
     46 
     47  if (event->HasMouseEventMessage()) {
     48    WidgetMouseEvent* mouseEvent = event->AsMouseEvent();
     49 
     50    if (mouseEvent->IsLeftClickEvent()) {
     51      RefPtr<HTMLDetailsElement> details = GetDetails();
     52      MOZ_ASSERT(details,
     53                 "Expected to find details since this is the main summary!");
     54 
     55      // When dispatching a synthesized mouse click event to a details element
     56      // with 'display: none', both Chrome and Safari do not toggle the 'open'
     57      // attribute. We had tried to be compatible with this behavior, but found
     58      // more inconsistency in test cases in bug 1245424. So we stop doing that.
     59      details->ToggleOpen();
     60      aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
     61      return NS_OK;
     62    }
     63  }  // event->HasMouseEventMessage()
     64 
     65  if (event->HasKeyEventMessage() && event->IsTrusted()) {
     66    HandleKeyboardActivation(aVisitor);
     67  }
     68  return rv;
     69 }
     70 
     71 bool HTMLSummaryElement::IsHTMLFocusable(IsFocusableFlags aFlags,
     72                                         bool* aIsFocusable,
     73                                         int32_t* aTabIndex) {
     74  bool disallowOverridingFocusability =
     75      nsGenericHTMLElement::IsHTMLFocusable(aFlags, aIsFocusable, aTabIndex);
     76 
     77  if (disallowOverridingFocusability || !IsMainSummary()) {
     78    return disallowOverridingFocusability;
     79  }
     80 
     81  // The main summary element is focusable.
     82  *aIsFocusable = true;
     83 
     84  // Give a chance to allow the subclass to override aIsFocusable.
     85  return false;
     86 }
     87 
     88 int32_t HTMLSummaryElement::TabIndexDefault() {
     89  // Make the main summary be able to navigate via tab, and be focusable.
     90  // See nsGenericHTMLElement::IsHTMLFocusable().
     91  return IsMainSummary() ? 0 : nsGenericHTMLElement::TabIndexDefault();
     92 }
     93 
     94 bool HTMLSummaryElement::IsMainSummary() const {
     95  HTMLDetailsElement* details = GetDetails();
     96  if (!details) {
     97    return false;
     98  }
     99 
    100  return details->GetFirstSummary() == this ||
    101         GetContainingShadow() == details->GetShadowRoot();
    102 }
    103 
    104 HTMLDetailsElement* HTMLSummaryElement::GetDetails() const {
    105  if (auto* details = HTMLDetailsElement::FromNodeOrNull(GetParent())) {
    106    return details;
    107  }
    108  if (!HasBeenInUAWidget()) {
    109    return nullptr;
    110  }
    111  return HTMLDetailsElement::FromNodeOrNull(GetContainingShadowHost());
    112 }
    113 
    114 JSObject* HTMLSummaryElement::WrapNode(JSContext* aCx,
    115                                       JS::Handle<JSObject*> aGivenProto) {
    116  return HTMLElement_Binding::Wrap(aCx, this, aGivenProto);
    117 }
    118 
    119 }  // namespace mozilla::dom