1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "HTMLEditHelpers.h"
8 #include "CSSEditUtils.h"
9 #include "HTMLEditor.h"
10 #include "HTMLEditUtils.h"
11 #include "PendingStyles.h"
13 #include "mozilla/ContentIterator.h"
14 #include "mozilla/OwningNonNull.h"
15 #include "nsIContent.h"
25 template void DOMIterator::AppendAllNodesToArray(
26 nsTArray
<OwningNonNull
<nsIContent
>>& aArrayOfNodes
) const;
27 template void DOMIterator::AppendAllNodesToArray(
28 nsTArray
<OwningNonNull
<HTMLBRElement
>>& aArrayOfNodes
) const;
29 template void DOMIterator::AppendNodesToArray(
30 BoolFunctor aFunctor
, nsTArray
<OwningNonNull
<nsIContent
>>& aArrayOfNodes
,
31 void* aClosure
) const;
32 template void DOMIterator::AppendNodesToArray(
33 BoolFunctor aFunctor
, nsTArray
<OwningNonNull
<Element
>>& aArrayOfNodes
,
34 void* aClosure
) const;
35 template void DOMIterator::AppendNodesToArray(
36 BoolFunctor aFunctor
, nsTArray
<OwningNonNull
<Text
>>& aArrayOfNodes
,
37 void* aClosure
) const;
39 /******************************************************************************
40 * some helper classes for iterating the dom tree
41 *****************************************************************************/
43 DOMIterator::DOMIterator(nsINode
& aNode
) : mIter(&mPostOrderIter
) {
44 DebugOnly
<nsresult
> rv
= mIter
->Init(&aNode
);
45 MOZ_ASSERT(NS_SUCCEEDED(rv
));
48 nsresult
DOMIterator::Init(nsRange
& aRange
) { return mIter
->Init(&aRange
); }
50 nsresult
DOMIterator::Init(const RawRangeBoundary
& aStartRef
,
51 const RawRangeBoundary
& aEndRef
) {
52 return mIter
->Init(aStartRef
, aEndRef
);
55 DOMIterator::DOMIterator() : mIter(&mPostOrderIter
) {}
57 template <class NodeClass
>
58 void DOMIterator::AppendAllNodesToArray(
59 nsTArray
<OwningNonNull
<NodeClass
>>& aArrayOfNodes
) const {
60 for (; !mIter
->IsDone(); mIter
->Next()) {
61 if (NodeClass
* node
= NodeClass::FromNode(mIter
->GetCurrentNode())) {
62 aArrayOfNodes
.AppendElement(*node
);
67 template <class NodeClass
>
68 void DOMIterator::AppendNodesToArray(
69 BoolFunctor aFunctor
, nsTArray
<OwningNonNull
<NodeClass
>>& aArrayOfNodes
,
70 void* aClosure
/* = nullptr */) const {
71 for (; !mIter
->IsDone(); mIter
->Next()) {
72 NodeClass
* node
= NodeClass::FromNode(mIter
->GetCurrentNode());
73 if (node
&& aFunctor(*node
, aClosure
)) {
74 aArrayOfNodes
.AppendElement(*node
);
79 DOMSubtreeIterator::DOMSubtreeIterator() { mIter
= &mSubtreeIter
; }
81 nsresult
DOMSubtreeIterator::Init(nsRange
& aRange
) {
82 return mIter
->Init(&aRange
);
85 /******************************************************************************
86 * mozilla::EditorElementStyle
87 *****************************************************************************/
89 bool EditorElementStyle::IsCSSSettable(const nsStaticAtom
& aTagName
) const {
90 return CSSEditUtils::IsCSSEditableStyle(aTagName
, *this);
93 bool EditorElementStyle::IsCSSSettable(const Element
& aElement
) const {
94 return CSSEditUtils::IsCSSEditableStyle(aElement
, *this);
97 bool EditorElementStyle::IsCSSRemovable(const nsStaticAtom
& aTagName
) const {
98 // <font size> cannot be applied with CSS font-size for now, but it should be
100 return EditorElementStyle::IsCSSSettable(aTagName
) ||
101 (IsInlineStyle() && AsInlineStyle().IsStyleOfFontSize());
104 bool EditorElementStyle::IsCSSRemovable(const Element
& aElement
) const {
105 // <font size> cannot be applied with CSS font-size for now, but it should be
107 return EditorElementStyle::IsCSSSettable(aElement
) ||
108 (IsInlineStyle() && AsInlineStyle().IsStyleOfFontSize());
111 /******************************************************************************
112 * mozilla::EditorInlineStyle
113 *****************************************************************************/
115 PendingStyleCache
EditorInlineStyle::ToPendingStyleCache(
116 nsAString
&& aValue
) const {
117 return PendingStyleCache(*mHTMLProperty
,
118 mAttribute
? mAttribute
->AsStatic() : nullptr,
122 bool EditorInlineStyle::IsRepresentedBy(const nsIContent
& aContent
) const {
123 MOZ_ASSERT(!IsStyleToClearAllInlineStyles());
125 if (!aContent
.IsHTMLElement()) {
128 const Element
& element
= *aContent
.AsElement();
129 if (mHTMLProperty
== element
.NodeInfo()->NameAtom() ||
130 mHTMLProperty
== GetSimilarElementNameAtom()) {
131 // <a> cannot be nested. Therefore, if we're the style of <a>, we should
132 // treat existing it even if the attribute does not match.
133 if (mHTMLProperty
== nsGkAtoms::a
) {
136 return !mAttribute
|| element
.HasAttr(mAttribute
);
138 // Special case for linking or naming an <a> element.
139 if ((mHTMLProperty
== nsGkAtoms::href
&& HTMLEditUtils::IsLink(&element
)) ||
140 (mHTMLProperty
== nsGkAtoms::name
&&
141 HTMLEditUtils::IsNamedAnchor(&element
))) {
144 // If the style is font size, it's also represented by <big> or <small>.
145 if (mHTMLProperty
== nsGkAtoms::font
&& mAttribute
== nsGkAtoms::size
&&
146 aContent
.IsAnyOfHTMLElements(nsGkAtoms::big
, nsGkAtoms::small
)) {
152 Result
<bool, nsresult
> EditorInlineStyle::IsSpecifiedBy(
153 const HTMLEditor
& aHTMLEditor
, Element
& aElement
) const {
154 MOZ_ASSERT(!IsStyleToClearAllInlineStyles());
155 if (!IsCSSSettable(aElement
) && !IsCSSRemovable(aElement
)) {
158 // Special case in the CSS mode. We should treat <u>, <s>, <strike>, <ins>
159 // and <del> specifies text-decoration (bug 1802668).
160 if (aHTMLEditor
.IsCSSEnabled() &&
161 IsStyleOfTextDecoration(IgnoreSElement::No
) &&
162 aElement
.IsAnyOfHTMLElements(nsGkAtoms::u
, nsGkAtoms::s
,
163 nsGkAtoms::strike
, nsGkAtoms::ins
,
167 return CSSEditUtils::HaveSpecifiedCSSEquivalentStyles(aHTMLEditor
, aElement
,
171 } // namespace mozilla