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/. */
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::dom
{
21 nsXULElement
* NS_NewXULTooltipElement(
22 already_AddRefed
<mozilla::dom::NodeInfo
>&& aNodeInfo
) {
23 RefPtr
<mozilla::dom::NodeInfo
> nodeInfo(aNodeInfo
);
24 auto* nim
= nodeInfo
->NodeInfoManager();
25 RefPtr
<XULTooltipElement
> tooltip
=
26 new (nim
) XULTooltipElement(nodeInfo
.forget());
27 NS_ENSURE_SUCCESS(tooltip
->Init(), nullptr);
31 nsresult
XULTooltipElement::Init() {
32 // Create the default child label node that will contain the text of the
34 RefPtr
<mozilla::dom::NodeInfo
> nodeInfo
;
35 nodeInfo
= mNodeInfo
->NodeInfoManager()->GetNodeInfo(
36 nsGkAtoms::description
, nullptr, kNameSpaceID_XUL
, nsINode::ELEMENT_NODE
);
37 nsCOMPtr
<Element
> description
;
38 nsresult rv
= NS_NewXULElement(getter_AddRefs(description
), nodeInfo
.forget(),
39 dom::NOT_FROM_PARSER
);
40 NS_ENSURE_SUCCESS(rv
, rv
);
41 description
->SetAttr(kNameSpaceID_None
, nsGkAtoms::_class
,
42 u
"tooltip-label"_ns
, false);
44 AppendChild(*description
, error
);
46 return error
.StealNSResult();
49 void XULTooltipElement::AfterSetAttr(int32_t aNameSpaceID
, nsAtom
* aName
,
50 const nsAttrValue
* aValue
,
51 const nsAttrValue
* aOldValue
,
52 nsIPrincipal
* aSubjectPrincipal
,
54 if (aNameSpaceID
== kNameSpaceID_None
&& aName
== nsGkAtoms::label
) {
55 // When the label attribute of this node changes propagate the text down
56 // into child description element.
57 nsCOMPtr
<nsIContent
> description
= GetFirstChild();
58 if (description
&& description
->IsXULElement(nsGkAtoms::description
)) {
61 aValue
->ToString(value
);
63 nsContentUtils::AddScriptRunner(NS_NewRunnableFunction(
64 "XULTooltipElement::AfterSetAttr", [description
, value
]() {
65 Element
* descriptionElement
= description
->AsElement();
66 descriptionElement
->SetTextContent(value
, IgnoreErrors());
70 return nsXULElement::AfterSetAttr(aNameSpaceID
, aName
, aValue
, aOldValue
,
71 aSubjectPrincipal
, aNotify
);
74 nsresult
XULTooltipElement::PostHandleEvent(EventChainPostVisitor
& aVisitor
) {
75 if (aVisitor
.mEvent
->mMessage
== eXULPopupShowing
&&
76 aVisitor
.mEvent
->IsTrusted() && !aVisitor
.mEvent
->DefaultPrevented() &&
77 AttrValueIs(kNameSpaceID_None
, nsGkAtoms::page
, nsGkAtoms::_true
,
79 !AttrValueIs(kNameSpaceID_None
, nsGkAtoms::titletip
, nsGkAtoms::_true
,
81 // When the tooltip node has the "page" attribute set to "true" the
82 // tooltip text provider is used to find the tooltip text from page where
83 // mouse is hovering over.
84 nsCOMPtr
<nsITooltipTextProvider
> textProvider
=
85 do_GetService(NS_DEFAULTTOOLTIPTEXTPROVIDER_CONTRACTID
);
88 bool shouldChange
= false;
90 textProvider
->GetNodeText(GetTriggerNode(), getter_Copies(text
),
91 getter_Copies(direction
), &shouldChange
);
94 SetAttr(kNameSpaceID_None
, nsGkAtoms::label
, text
, true);
95 SetAttr(kNameSpaceID_None
, nsGkAtoms::direction
, direction
, true);
97 aVisitor
.mEventStatus
= nsEventStatus_eConsumeNoDefault
;
98 aVisitor
.mEvent
->PreventDefault();
104 } // namespace mozilla::dom