tor-browser

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

XULTooltipElement.cpp (4280B)


      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/XULTooltipElement.h"
      8 
      9 #include "mozilla/EventDispatcher.h"
     10 #include "mozilla/dom/Event.h"
     11 #include "mozilla/dom/NodeInfo.h"
     12 #include "nsCOMPtr.h"
     13 #include "nsCTooltipTextProvider.h"
     14 #include "nsContentCreatorFunctions.h"
     15 #include "nsContentUtils.h"
     16 #include "nsITooltipTextProvider.h"
     17 #include "nsServiceManagerUtils.h"
     18 #include "nsThreadUtils.h"
     19 
     20 namespace mozilla::dom {
     21 
     22 nsXULElement* NS_NewXULTooltipElement(
     23    already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo) {
     24  RefPtr<mozilla::dom::NodeInfo> nodeInfo(aNodeInfo);
     25  auto* nim = nodeInfo->NodeInfoManager();
     26  RefPtr<XULTooltipElement> tooltip =
     27      new (nim) XULTooltipElement(nodeInfo.forget());
     28  NS_ENSURE_SUCCESS(tooltip->Init(), nullptr);
     29  return tooltip;
     30 }
     31 
     32 nsresult XULTooltipElement::Init() {
     33  // Create the default child label node that will contain the text of the
     34  // tooltip.
     35  RefPtr<mozilla::dom::NodeInfo> nodeInfo;
     36  nodeInfo = mNodeInfo->NodeInfoManager()->GetNodeInfo(
     37      nsGkAtoms::description, nullptr, kNameSpaceID_XUL, nsINode::ELEMENT_NODE);
     38  nsCOMPtr<Element> description;
     39  nsresult rv = NS_NewXULElement(getter_AddRefs(description), nodeInfo.forget(),
     40                                 dom::NOT_FROM_PARSER);
     41  NS_ENSURE_SUCCESS(rv, rv);
     42  description->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
     43                       u"tooltip-label"_ns, false);
     44  ErrorResult error;
     45  AppendChild(*description, error);
     46 
     47  return error.StealNSResult();
     48 }
     49 
     50 void XULTooltipElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
     51                                     const nsAttrValue* aValue,
     52                                     const nsAttrValue* aOldValue,
     53                                     nsIPrincipal* aSubjectPrincipal,
     54                                     bool aNotify) {
     55  if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::label) {
     56    // When the label attribute of this node changes propagate the text down
     57    // into child description element.
     58    nsCOMPtr<nsIContent> description = GetFirstChild();
     59    if (description && description->IsXULElement(nsGkAtoms::description)) {
     60      nsAutoString value;
     61      if (aValue) {
     62        aValue->ToString(value);
     63      }
     64      nsContentUtils::AddScriptRunner(NS_NewRunnableFunction(
     65          "XULTooltipElement::AfterSetAttr", [description, value]() {
     66            Element* descriptionElement = description->AsElement();
     67            descriptionElement->SetTextContent(value, IgnoreErrors());
     68          }));
     69    }
     70  }
     71  return nsXULElement::AfterSetAttr(aNameSpaceID, aName, aValue, aOldValue,
     72                                    aSubjectPrincipal, aNotify);
     73 }
     74 
     75 nsresult XULTooltipElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
     76  if (aVisitor.mEvent->mMessage == eXULPopupShowing &&
     77      aVisitor.mEvent->IsTrusted() && !aVisitor.mEvent->DefaultPrevented() &&
     78      AttrValueIs(kNameSpaceID_None, nsGkAtoms::page, nsGkAtoms::_true,
     79                  eCaseMatters) &&
     80      !AttrValueIs(kNameSpaceID_None, nsGkAtoms::titletip, nsGkAtoms::_true,
     81                   eCaseMatters)) {
     82    // When the tooltip node has the "page" attribute set to "true" the
     83    // tooltip text provider is used to find the tooltip text from page where
     84    // mouse is hovering over.
     85    nsCOMPtr<nsITooltipTextProvider> textProvider =
     86        do_GetService(NS_DEFAULTTOOLTIPTEXTPROVIDER_CONTRACTID);
     87    nsString text;
     88    nsString direction;
     89    bool shouldChange = false;
     90    if (textProvider) {
     91      textProvider->GetNodeText(GetTriggerNode(), getter_Copies(text),
     92                                getter_Copies(direction), &shouldChange);
     93    }
     94    if (shouldChange) {
     95      SetAttr(kNameSpaceID_None, nsGkAtoms::label, text, true);
     96      SetAttr(kNameSpaceID_None, nsGkAtoms::direction, direction, true);
     97    } else {
     98      aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
     99      aVisitor.mEvent->PreventDefault();
    100    }
    101  }
    102  return NS_OK;
    103 }
    104 
    105 }  // namespace mozilla::dom