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 "mozilla/dom/HTMLMarqueeElement.h"
8 #include "nsGenericHTMLElement.h"
9 #include "nsStyleConsts.h"
10 #include "nsMappedAttributes.h"
11 #include "mozilla/AsyncEventDispatcher.h"
12 #include "mozilla/dom/HTMLMarqueeElementBinding.h"
13 #include "mozilla/dom/CustomEvent.h"
14 // This is to pick up the definition of FunctionStringCallback:
15 #include "mozilla/dom/DataTransferItemBinding.h"
16 #include "mozilla/dom/ShadowRoot.h"
18 NS_IMPL_NS_NEW_HTML_ELEMENT(Marquee
)
20 namespace mozilla::dom
{
22 HTMLMarqueeElement::~HTMLMarqueeElement() = default;
24 NS_IMPL_ELEMENT_CLONE(HTMLMarqueeElement
)
26 static const nsAttrValue::EnumTable kBehaviorTable
[] = {
27 {"scroll", 1}, {"slide", 2}, {"alternate", 3}, {nullptr, 0}};
29 // Default behavior value is "scroll".
30 static const nsAttrValue::EnumTable
* kDefaultBehavior
= &kBehaviorTable
[0];
32 static const nsAttrValue::EnumTable kDirectionTable
[] = {
33 {"left", 1}, {"right", 2}, {"up", 3}, {"down", 4}, {nullptr, 0}};
35 // Default direction value is "left".
36 static const nsAttrValue::EnumTable
* kDefaultDirection
= &kDirectionTable
[0];
38 bool HTMLMarqueeElement::IsEventAttributeNameInternal(nsAtom
* aName
) {
39 return nsContentUtils::IsEventAttributeName(
40 aName
, EventNameType_HTML
| EventNameType_HTMLMarqueeOnly
);
43 JSObject
* HTMLMarqueeElement::WrapNode(JSContext
* aCx
,
44 JS::Handle
<JSObject
*> aGivenProto
) {
45 return dom::HTMLMarqueeElement_Binding::Wrap(aCx
, this, aGivenProto
);
48 nsresult
HTMLMarqueeElement::BindToTree(BindContext
& aContext
,
50 nsresult rv
= nsGenericHTMLElement::BindToTree(aContext
, aParent
);
51 NS_ENSURE_SUCCESS(rv
, rv
);
53 if (IsInComposedDoc()) {
54 AttachAndSetUAShadowRoot();
60 void HTMLMarqueeElement::UnbindFromTree(bool aNullParent
) {
61 if (IsInComposedDoc()) {
62 // We don't want to unattach the shadow root because it used to
64 NotifyUAWidgetTeardown(UnattachShadowRoot::No
);
67 nsGenericHTMLElement::UnbindFromTree(aNullParent
);
70 void HTMLMarqueeElement::GetBehavior(nsAString
& aValue
) {
71 GetEnumAttr(nsGkAtoms::behavior
, kDefaultBehavior
->tag
, aValue
);
74 void HTMLMarqueeElement::GetDirection(nsAString
& aValue
) {
75 GetEnumAttr(nsGkAtoms::direction
, kDefaultDirection
->tag
, aValue
);
78 bool HTMLMarqueeElement::ParseAttribute(int32_t aNamespaceID
,
80 const nsAString
& aValue
,
81 nsIPrincipal
* aMaybeScriptedPrincipal
,
82 nsAttrValue
& aResult
) {
83 if (aNamespaceID
== kNameSpaceID_None
) {
84 if ((aAttribute
== nsGkAtoms::width
) || (aAttribute
== nsGkAtoms::height
)) {
85 return aResult
.ParseHTMLDimension(aValue
);
87 if (aAttribute
== nsGkAtoms::bgcolor
) {
88 return aResult
.ParseColor(aValue
);
90 if (aAttribute
== nsGkAtoms::behavior
) {
91 return aResult
.ParseEnumValue(aValue
, kBehaviorTable
, false,
94 if (aAttribute
== nsGkAtoms::direction
) {
95 return aResult
.ParseEnumValue(aValue
, kDirectionTable
, false,
98 if (aAttribute
== nsGkAtoms::hspace
|| aAttribute
== nsGkAtoms::vspace
) {
99 return aResult
.ParseHTMLDimension(aValue
);
102 if (aAttribute
== nsGkAtoms::loop
) {
103 return aResult
.ParseIntValue(aValue
);
106 if (aAttribute
== nsGkAtoms::scrollamount
||
107 aAttribute
== nsGkAtoms::scrolldelay
) {
108 return aResult
.ParseNonNegativeIntValue(aValue
);
112 return nsGenericHTMLElement::ParseAttribute(aNamespaceID
, aAttribute
, aValue
,
113 aMaybeScriptedPrincipal
, aResult
);
116 void HTMLMarqueeElement::AfterSetAttr(int32_t aNameSpaceID
, nsAtom
* aName
,
117 const nsAttrValue
* aValue
,
118 const nsAttrValue
* aOldValue
,
119 nsIPrincipal
* aMaybeScriptedPrincipal
,
121 if (IsInComposedDoc() && aNameSpaceID
== kNameSpaceID_None
&&
122 aName
== nsGkAtoms::direction
) {
123 NotifyUAWidgetSetupOrChange();
125 return nsGenericHTMLElement::AfterSetAttr(
126 aNameSpaceID
, aName
, aValue
, aOldValue
, aMaybeScriptedPrincipal
, aNotify
);
129 void HTMLMarqueeElement::MapAttributesIntoRule(
130 const nsMappedAttributes
* aAttributes
, MappedDeclarations
& aDecls
) {
131 nsGenericHTMLElement::MapImageMarginAttributeInto(aAttributes
, aDecls
);
132 nsGenericHTMLElement::MapImageSizeAttributesInto(aAttributes
, aDecls
);
133 nsGenericHTMLElement::MapCommonAttributesInto(aAttributes
, aDecls
);
134 nsGenericHTMLElement::MapBGColorInto(aAttributes
, aDecls
);
138 HTMLMarqueeElement::IsAttributeMapped(const nsAtom
* aAttribute
) const {
139 static const MappedAttributeEntry
* const map
[] = {
140 sImageMarginSizeAttributeMap
, sBackgroundColorAttributeMap
,
141 sCommonAttributeMap
};
142 return FindAttributeDependence(aAttribute
, map
);
145 nsMapRuleToAttributesFunc
HTMLMarqueeElement::GetAttributeMappingFunction()
147 return &MapAttributesIntoRule
;
150 void HTMLMarqueeElement::DispatchEventToShadowRoot(
151 const nsAString
& aEventTypeArg
) {
152 // Dispatch the event to the UA Widget Shadow Root, make it inaccessible to
154 RefPtr
<nsINode
> shadow
= GetShadowRoot();
156 RefPtr
<Event
> event
= new Event(shadow
, nullptr, nullptr);
157 event
->InitEvent(aEventTypeArg
, false, false);
158 event
->SetTrusted(true);
159 shadow
->DispatchEvent(*event
, IgnoreErrors());
162 void HTMLMarqueeElement::Start() {
163 if (GetShadowRoot()) {
164 DispatchEventToShadowRoot(u
"marquee-start"_ns
);
168 void HTMLMarqueeElement::Stop() {
169 if (GetShadowRoot()) {
170 DispatchEventToShadowRoot(u
"marquee-stop"_ns
);
174 } // namespace mozilla::dom