Bug 1707290 [wpt PR 28671] - Auto-expand details elements for find-in-page, a=testonly
[gecko.git] / dom / xul / XULTooltipElement.cpp
blob40eb36d29ea303dfd9a07c62b81ffcb95ff88470
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 "nsCOMPtr.h"
8 #include "mozilla/dom/Event.h"
9 #include "mozilla/dom/XULTooltipElement.h"
10 #include "mozilla/dom/NodeInfo.h"
11 #include "mozilla/EventDispatcher.h"
12 #include "nsContentCreatorFunctions.h"
13 #include "nsContentUtils.h"
14 #include "nsCTooltipTextProvider.h"
15 #include "nsITooltipTextProvider.h"
16 #include "nsServiceManagerUtils.h"
17 #include "nsThreadUtils.h"
19 namespace mozilla {
20 namespace dom {
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;
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 description->SetAttr(kNameSpaceID_None, nsGkAtoms::flex, u"true"_ns, false);
45 ErrorResult error;
46 AppendChild(*description, error);
48 return error.StealNSResult();
51 nsresult XULTooltipElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
52 const nsAttrValue* aValue,
53 const nsAttrValue* aOldValue,
54 nsIPrincipal* aSubjectPrincipal,
55 bool aNotify) {
56 if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::label) {
57 // When the label attribute of this node changes propagate the text down
58 // into child description element.
59 nsCOMPtr<nsIContent> description = GetFirstChild();
60 if (description && description->IsXULElement(nsGkAtoms::description)) {
61 nsAutoString value;
62 if (aValue) {
63 aValue->ToString(value);
65 nsContentUtils::AddScriptRunner(NS_NewRunnableFunction(
66 "XULTooltipElement::AfterSetAttr", [description, value]() {
67 Element* descriptionElement = description->AsElement();
68 descriptionElement->SetTextContent(value, IgnoreErrors());
69 }));
72 return nsXULElement::AfterSetAttr(aNameSpaceID, aName, aValue, aOldValue,
73 aSubjectPrincipal, aNotify);
76 nsresult XULTooltipElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
77 if (aVisitor.mEvent->mMessage == eXULPopupShowing &&
78 aVisitor.mEvent->IsTrusted() && !aVisitor.mEvent->DefaultPrevented() &&
79 AttrValueIs(kNameSpaceID_None, nsGkAtoms::page, nsGkAtoms::_true,
80 eCaseMatters) &&
81 !AttrValueIs(kNameSpaceID_None, nsGkAtoms::titletip, nsGkAtoms::_true,
82 eCaseMatters)) {
83 // When the tooltip node has the "page" attribute set to "true" the
84 // tooltip text provider is used to find the tooltip text from page where
85 // mouse is hovering over.
86 nsCOMPtr<nsITooltipTextProvider> textProvider =
87 do_GetService(NS_DEFAULTTOOLTIPTEXTPROVIDER_CONTRACTID);
88 nsString text;
89 nsString direction;
90 bool shouldChange = false;
91 if (textProvider) {
92 textProvider->GetNodeText(GetTriggerNode(), getter_Copies(text),
93 getter_Copies(direction), &shouldChange);
95 if (shouldChange) {
96 SetAttr(kNameSpaceID_None, nsGkAtoms::label, text, true);
97 SetAttr(kNameSpaceID_None, nsGkAtoms::direction, direction, true);
98 } else {
99 aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
100 aVisitor.mEvent->PreventDefault();
103 return NS_OK;
106 } // namespace dom
107 } // namespace mozilla