Backed out changeset b71c8c052463 (bug 1943846) for causing mass failures. CLOSED...
[gecko.git] / editor / libeditor / HTMLEditHelpers.cpp
blob343c818b2e825b03f19d8e49cb84ab58c078d9c6
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"
16 #include "nsINode.h"
17 #include "nsRange.h"
19 class nsISupports;
21 namespace mozilla {
23 using namespace dom;
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
99 // removable.
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
106 // removable.
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,
119 std::move(aValue));
122 bool EditorInlineStyle::IsRepresentedBy(const nsIContent& aContent) const {
123 MOZ_ASSERT(!IsStyleToClearAllInlineStyles());
125 if (!aContent.IsHTMLElement()) {
126 return false;
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) {
134 return true;
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))) {
142 return true;
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)) {
147 return true;
149 return false;
152 Result<bool, nsresult> EditorInlineStyle::IsSpecifiedBy(
153 const HTMLEditor& aHTMLEditor, Element& aElement) const {
154 MOZ_ASSERT(!IsStyleToClearAllInlineStyles());
155 if (!IsCSSSettable(aElement) && !IsCSSRemovable(aElement)) {
156 return false;
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,
164 nsGkAtoms::del)) {
165 return true;
167 return CSSEditUtils::HaveSpecifiedCSSEquivalentStyles(aHTMLEditor, aElement,
168 *this);
171 } // namespace mozilla