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"
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);
32 nsresult
XULTooltipElement::Init() {
33 // Create the default child label node that will contain the text of the
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);
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
,
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
)) {
63 aValue
->ToString(value
);
65 nsContentUtils::AddScriptRunner(NS_NewRunnableFunction(
66 "XULTooltipElement::AfterSetAttr", [description
, value
]() {
67 Element
* descriptionElement
= description
->AsElement();
68 descriptionElement
->SetTextContent(value
, IgnoreErrors());
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
,
81 !AttrValueIs(kNameSpaceID_None
, nsGkAtoms::titletip
, nsGkAtoms::_true
,
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
);
90 bool shouldChange
= false;
92 textProvider
->GetNodeText(GetTriggerNode(), getter_Copies(text
),
93 getter_Copies(direction
), &shouldChange
);
96 SetAttr(kNameSpaceID_None
, nsGkAtoms::label
, text
, true);
97 SetAttr(kNameSpaceID_None
, nsGkAtoms::direction
, direction
, true);
99 aVisitor
.mEventStatus
= nsEventStatus_eConsumeNoDefault
;
100 aVisitor
.mEvent
->PreventDefault();
107 } // namespace mozilla