summaryrefslogtreecommitdiffstats
path: root/editor/libeditor/HTMLEditHelpers.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/libeditor/HTMLEditHelpers.cpp')
-rw-r--r--editor/libeditor/HTMLEditHelpers.cpp176
1 files changed, 176 insertions, 0 deletions
diff --git a/editor/libeditor/HTMLEditHelpers.cpp b/editor/libeditor/HTMLEditHelpers.cpp
new file mode 100644
index 0000000000..b75167221a
--- /dev/null
+++ b/editor/libeditor/HTMLEditHelpers.cpp
@@ -0,0 +1,176 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "HTMLEditHelpers.h"
+
+#include "CSSEditUtils.h"
+#include "EditorDOMPoint.h"
+#include "HTMLEditor.h"
+#include "PendingStyles.h"
+#include "WSRunObject.h"
+
+#include "mozilla/ContentIterator.h"
+#include "mozilla/OwningNonNull.h"
+#include "mozilla/dom/HTMLBRElement.h"
+#include "mozilla/dom/Text.h"
+#include "nsIContent.h"
+#include "nsINode.h"
+#include "nsRange.h"
+
+class nsISupports;
+
+namespace mozilla {
+
+using namespace dom;
+
+template void DOMIterator::AppendAllNodesToArray(
+ nsTArray<OwningNonNull<nsIContent>>& aArrayOfNodes) const;
+template void DOMIterator::AppendAllNodesToArray(
+ nsTArray<OwningNonNull<HTMLBRElement>>& aArrayOfNodes) const;
+template void DOMIterator::AppendNodesToArray(
+ BoolFunctor aFunctor, nsTArray<OwningNonNull<nsIContent>>& aArrayOfNodes,
+ void* aClosure) const;
+template void DOMIterator::AppendNodesToArray(
+ BoolFunctor aFunctor, nsTArray<OwningNonNull<Element>>& aArrayOfNodes,
+ void* aClosure) const;
+template void DOMIterator::AppendNodesToArray(
+ BoolFunctor aFunctor, nsTArray<OwningNonNull<Text>>& aArrayOfNodes,
+ void* aClosure) const;
+
+/******************************************************************************
+ * some helper classes for iterating the dom tree
+ *****************************************************************************/
+
+DOMIterator::DOMIterator(nsINode& aNode) : mIter(&mPostOrderIter) {
+ DebugOnly<nsresult> rv = mIter->Init(&aNode);
+ MOZ_ASSERT(NS_SUCCEEDED(rv));
+}
+
+nsresult DOMIterator::Init(nsRange& aRange) { return mIter->Init(&aRange); }
+
+nsresult DOMIterator::Init(const RawRangeBoundary& aStartRef,
+ const RawRangeBoundary& aEndRef) {
+ return mIter->Init(aStartRef, aEndRef);
+}
+
+DOMIterator::DOMIterator() : mIter(&mPostOrderIter) {}
+
+template <class NodeClass>
+void DOMIterator::AppendAllNodesToArray(
+ nsTArray<OwningNonNull<NodeClass>>& aArrayOfNodes) const {
+ for (; !mIter->IsDone(); mIter->Next()) {
+ if (NodeClass* node = NodeClass::FromNode(mIter->GetCurrentNode())) {
+ aArrayOfNodes.AppendElement(*node);
+ }
+ }
+}
+
+template <class NodeClass>
+void DOMIterator::AppendNodesToArray(
+ BoolFunctor aFunctor, nsTArray<OwningNonNull<NodeClass>>& aArrayOfNodes,
+ void* aClosure /* = nullptr */) const {
+ for (; !mIter->IsDone(); mIter->Next()) {
+ NodeClass* node = NodeClass::FromNode(mIter->GetCurrentNode());
+ if (node && aFunctor(*node, aClosure)) {
+ aArrayOfNodes.AppendElement(*node);
+ }
+ }
+}
+
+DOMSubtreeIterator::DOMSubtreeIterator() : DOMIterator() {
+ mIter = &mSubtreeIter;
+}
+
+nsresult DOMSubtreeIterator::Init(nsRange& aRange) {
+ return mIter->Init(&aRange);
+}
+
+/******************************************************************************
+ * mozilla::EditorElementStyle
+ *****************************************************************************/
+
+bool EditorElementStyle::IsCSSSettable(const nsStaticAtom& aTagName) const {
+ return CSSEditUtils::IsCSSEditableStyle(aTagName, *this);
+}
+
+bool EditorElementStyle::IsCSSSettable(const Element& aElement) const {
+ return CSSEditUtils::IsCSSEditableStyle(aElement, *this);
+}
+
+bool EditorElementStyle::IsCSSRemovable(const nsStaticAtom& aTagName) const {
+ // <font size> cannot be applied with CSS font-size for now, but it should be
+ // removable.
+ return EditorElementStyle::IsCSSSettable(aTagName) ||
+ (IsInlineStyle() && AsInlineStyle().IsStyleOfFontSize());
+}
+
+bool EditorElementStyle::IsCSSRemovable(const Element& aElement) const {
+ // <font size> cannot be applied with CSS font-size for now, but it should be
+ // removable.
+ return EditorElementStyle::IsCSSSettable(aElement) ||
+ (IsInlineStyle() && AsInlineStyle().IsStyleOfFontSize());
+}
+
+/******************************************************************************
+ * mozilla::EditorInlineStyle
+ *****************************************************************************/
+
+PendingStyleCache EditorInlineStyle::ToPendingStyleCache(
+ nsAString&& aValue) const {
+ return PendingStyleCache(*mHTMLProperty,
+ mAttribute ? mAttribute->AsStatic() : nullptr,
+ std::move(aValue));
+}
+
+bool EditorInlineStyle::IsRepresentedBy(const nsIContent& aContent) const {
+ MOZ_ASSERT(!IsStyleToClearAllInlineStyles());
+
+ if (!aContent.IsHTMLElement()) {
+ return false;
+ }
+ const Element& element = *aContent.AsElement();
+ if (mHTMLProperty == element.NodeInfo()->NameAtom() ||
+ mHTMLProperty == GetSimilarElementNameAtom()) {
+ // <a> cannot be nested. Therefore, if we're the style of <a>, we should
+ // treat existing it even if the attribute does not match.
+ if (mHTMLProperty == nsGkAtoms::a) {
+ return true;
+ }
+ return !mAttribute || element.HasAttr(kNameSpaceID_None, mAttribute);
+ }
+ // Special case for linking or naming an <a> element.
+ if ((mHTMLProperty == nsGkAtoms::href && HTMLEditUtils::IsLink(&element)) ||
+ (mHTMLProperty == nsGkAtoms::name &&
+ HTMLEditUtils::IsNamedAnchor(&element))) {
+ return true;
+ }
+ // If the style is font size, it's also represented by <big> or <small>.
+ if (mHTMLProperty == nsGkAtoms::font && mAttribute == nsGkAtoms::size &&
+ aContent.IsAnyOfHTMLElements(nsGkAtoms::big, nsGkAtoms::small)) {
+ return true;
+ }
+ return false;
+}
+
+Result<bool, nsresult> EditorInlineStyle::IsSpecifiedBy(
+ const HTMLEditor& aHTMLEditor, Element& aElement) const {
+ MOZ_ASSERT(!IsStyleToClearAllInlineStyles());
+ if (!IsCSSSettable(aElement) && !IsCSSRemovable(aElement)) {
+ return false;
+ }
+ // Special case in the CSS mode. We should treat <u>, <s>, <strike>, <ins>
+ // and <del> specifies text-decoration (bug 1802668).
+ if (aHTMLEditor.IsCSSEnabled() &&
+ IsStyleOfTextDecoration(IgnoreSElement::No) &&
+ aElement.IsAnyOfHTMLElements(nsGkAtoms::u, nsGkAtoms::s,
+ nsGkAtoms::strike, nsGkAtoms::ins,
+ nsGkAtoms::del)) {
+ return true;
+ }
+ return CSSEditUtils::HaveSpecifiedCSSEquivalentStyles(aHTMLEditor, aElement,
+ *this);
+}
+
+} // namespace mozilla