diff --git a/editor/libeditor/HTMLStyleEditor.cpp b/editor/libeditor/HTMLStyleEditor.cpp
index c986fe3a56e3..59873adef8d8 100644
--- a/editor/libeditor/HTMLStyleEditor.cpp
+++ b/editor/libeditor/HTMLStyleEditor.cpp
@@ -1581,51 +1581,51 @@ nsresult HTMLEditor::RemoveInlinePropertyInternal(nsAtom* aProperty,
return rv;
}
- if (startOfRange.GetContainer() == endOfRange.GetContainer() &&
- startOfRange.IsInTextNode()) {
- // If parent block has the removing style, we should create ``
- // element to remove the style even in HTML mode since Chrome does it.
- if (!CSSEditUtils::IsCSSEditableProperty(startOfRange.GetContainer(),
- aProperty, aAttribute)) {
- continue;
- }
- // The HTML style defined by aProperty/aAttribute has a CSS
- // equivalence in this implementation for startOfRange.
- if (!CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
- startOfRange.GetContainer(), aProperty, aAttribute,
- EmptyString(), CSSEditUtils::eComputed)) {
- continue;
- }
- // startOfRange's computed style indicates the CSS equivalence to the
- // HTML style to remove is applied; but we found no element in the
- // ancestors of startOfRange carrying specified styles; assume it
- // comes from a rule and try to insert a span "inverting" the style
- if (!CSSEditUtils::IsCSSInvertible(*aProperty, aAttribute)) {
- continue;
- }
- SetInlinePropertyOnTextNode(
- MOZ_KnownLive(*startOfRange.GetContainerAsText()),
- startOfRange.Offset(), endOfRange.Offset(), *aProperty, aAttribute,
- NS_LITERAL_STRING("-moz-editor-invert-value"));
- if (NS_WARN_IF(Destroyed())) {
- return NS_ERROR_EDITOR_DESTROYED;
- }
- continue;
- }
-
// Collect editable nodes which are entirely contained in the range.
AutoTArray, 64> arrayOfContents;
- ContentSubtreeIterator subtreeIter;
- if (NS_SUCCEEDED(subtreeIter.Init(range))) {
- for (; !subtreeIter.IsDone(); subtreeIter.Next()) {
- nsCOMPtr node = subtreeIter.GetCurrentNode();
- if (NS_WARN_IF(!node)) {
- return NS_ERROR_FAILURE;
- }
- if (node->IsContent() && IsEditable(node)) {
- arrayOfContents.AppendElement(*node->AsContent());
+ if (startOfRange.GetContainer() == endOfRange.GetContainer() &&
+ startOfRange.IsInTextNode()) {
+ if (!IsEditable(startOfRange.GetContainer())) {
+ continue;
+ }
+ arrayOfContents.AppendElement(*startOfRange.GetContainerAsText());
+ } else if (startOfRange.IsInTextNode() && endOfRange.IsInTextNode() &&
+ startOfRange.GetContainer()->GetNextSibling() ==
+ endOfRange.GetContainer()) {
+ if (IsEditable(startOfRange.GetContainer())) {
+ arrayOfContents.AppendElement(*startOfRange.GetContainerAsText());
+ }
+ if (IsEditable(endOfRange.GetContainer())) {
+ arrayOfContents.AppendElement(*endOfRange.GetContainerAsText());
+ }
+ if (arrayOfContents.IsEmpty()) {
+ continue;
+ }
+ } else {
+ // Append first node if it's a text node but selected not entirely.
+ if (startOfRange.IsInTextNode() && !startOfRange.IsStartOfContainer() &&
+ IsEditable(startOfRange.GetContainer())) {
+ arrayOfContents.AppendElement(*startOfRange.GetContainerAsText());
+ }
+ // Append all entirely selected nodes.
+ ContentSubtreeIterator subtreeIter;
+ if (NS_SUCCEEDED(subtreeIter.Init(range))) {
+ for (; !subtreeIter.IsDone(); subtreeIter.Next()) {
+ nsCOMPtr node = subtreeIter.GetCurrentNode();
+ if (NS_WARN_IF(!node)) {
+ return NS_ERROR_FAILURE;
+ }
+ if (node->IsContent() && IsEditable(node)) {
+ arrayOfContents.AppendElement(*node->AsContent());
+ }
}
}
+ // Append last node if it's a text node but selected not entirely.
+ if (startOfRange.GetContainer() != endOfRange.GetContainer() &&
+ endOfRange.IsInTextNode() && !endOfRange.IsEndOfContainer() &&
+ IsEditable(endOfRange.GetContainer())) {
+ arrayOfContents.AppendElement(*endOfRange.GetContainerAsText());
+ }
}
for (auto& content : arrayOfContents) {
@@ -1655,14 +1655,37 @@ nsresult HTMLEditor::RemoveInlinePropertyInternal(nsAtom* aProperty,
if (!CSSEditUtils::IsCSSInvertible(*aProperty, aAttribute)) {
continue;
}
- DebugOnly rvIgnored = SetInlinePropertyOnNode(
- content, *aProperty, aAttribute,
+ if (!content->IsText()) {
+ DebugOnly rvIgnored = SetInlinePropertyOnNode(
+ content, *aProperty, aAttribute,
+ NS_LITERAL_STRING("-moz-editor-invert-value"));
+ if (NS_WARN_IF(Destroyed())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
+ NS_WARNING_ASSERTION(NS_FAILED(rvIgnored),
+ "SetInlinePropertyOnNode() failed, but ignored");
+ continue;
+ }
+ // If current node is a text node, we need to create `` element
+ // for it to overwrite parent style. Unfortunately, all browsers
+ // don't join text nodes when removing a style. Therefore, there
+ // may be multiple text nodes as adjacent siblings. That's the
+ // reason why we need to handle text nodes in this loop.
+ uint32_t startOffset =
+ content == startOfRange.GetContainer() ? startOfRange.Offset() : 0;
+ uint32_t endOffset = content == endOfRange.GetContainer()
+ ? endOfRange.Offset()
+ : content->Length();
+ nsresult rv = SetInlinePropertyOnTextNode(
+ MOZ_KnownLive(*content->AsText()), startOffset, endOffset,
+ *aProperty, aAttribute,
NS_LITERAL_STRING("-moz-editor-invert-value"));
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
- NS_WARNING_ASSERTION(NS_FAILED(rvIgnored),
- "SetInlinePropertyOnNode() failed, but ignored");
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
}
}
}
diff --git a/testing/web-platform/meta/editing/run/bold.html.ini b/testing/web-platform/meta/editing/run/bold.html.ini
index 6783177f1b8f..90e5f0f90756 100644
--- a/testing/web-platform/meta/editing/run/bold.html.ini
+++ b/testing/web-platform/meta/editing/run/bold.html.ini
@@ -167,30 +167,6 @@
[[["bold",""\]\] "foo[barbaz}" queryCommandState("bold") after]
expected: FAIL
- [[["stylewithcss","true"\],["bold",""\]\] "{foobar\]baz
" compare innerHTML]
- expected: FAIL
-
- [[["stylewithcss","true"\],["bold",""\]\] "{foobar\]baz
" queryCommandState("bold") after]
- expected: FAIL
-
- [[["stylewithcss","false"\],["bold",""\]\] "{foobar\]baz
" compare innerHTML]
- expected: FAIL
-
- [[["stylewithcss","false"\],["bold",""\]\] "{foobar\]baz
" queryCommandState("bold") after]
- expected: FAIL
-
- [[["stylewithcss","true"\],["bold",""\]\] "foo[barbaz
}" compare innerHTML]
- expected: FAIL
-
- [[["stylewithcss","true"\],["bold",""\]\] "foo[barbaz
}" queryCommandState("bold") after]
- expected: FAIL
-
- [[["stylewithcss","false"\],["bold",""\]\] "foo[barbaz
}" compare innerHTML]
- expected: FAIL
-
- [[["stylewithcss","false"\],["bold",""\]\] "foo[barbaz
}" queryCommandState("bold") after]
- expected: FAIL
-
[[["stylewithcss","true"\],["bold",""\]\] "[foobarbaz\]
" compare innerHTML]
expected: FAIL