Bug 1801028 - part 10: Make `HTMLEditor::RemoveStyleInside` take `EditorInlineStyle` r=m_kato

Depends on D162509

Differential Revision: https://phabricator.services.mozilla.com/D162510
This commit is contained in:
Masayuki Nakano 2022-11-25 06:26:04 +00:00
Родитель 513d9c0f27
Коммит 86439634a2
2 изменённых файлов: 37 добавлений и 35 удалений

Просмотреть файл

@ -3905,7 +3905,7 @@ class HTMLEditor final : public EditorBase,
nsresult PromoteRangeIfStartsOrEndsInNamedAnchor(nsRange& aRange);
/**
* RemoveStyleInside() removes elements which represent aProperty/aAttribute
* RemoveStyleInside() removes elements which represent aStyleToRemove
* and removes CSS style. This handles aElement and all its descendants
* (including leaf text nodes) recursively.
* TODO: Rename this to explain that this maybe remove aElement from the DOM
@ -3916,7 +3916,7 @@ class HTMLEditor final : public EditorBase,
* @return A suggest point to put caret.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<EditorDOMPoint, nsresult>
RemoveStyleInside(Element& aElement, nsAtom* aProperty, nsAtom* aAttribute,
RemoveStyleInside(Element& aElement, const EditorInlineStyle& aStyleToRemove,
SpecifiedStyle aSpecifiedStyle);
/**

Просмотреть файл

@ -891,9 +891,8 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::SetInlinePropertyOnNode(
EditorDOMPoint pointToPutCaret;
if (aContent.IsElement()) {
Result<EditorDOMPoint, nsresult> removeStyleResult =
RemoveStyleInside(MOZ_KnownLive(*aContent.AsElement()),
MOZ_KnownLive(&aStyleToSet.HTMLPropertyRef()),
aStyleToSet.mAttribute, SpecifiedStyle::Preserve);
RemoveStyleInside(MOZ_KnownLive(*aContent.AsElement()), aStyleToSet,
SpecifiedStyle::Preserve);
if (MOZ_UNLIKELY(removeStyleResult.isErr())) {
NS_WARNING("HTMLEditor::RemoveStyleInside() failed");
return removeStyleResult.propagateErr();
@ -1403,8 +1402,7 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::ClearStyleAt(
// It's grabbed by unwrappedSplitResultAtStartOfNextNode.
Result<EditorDOMPoint, nsresult> removeStyleResult =
RemoveStyleInside(MOZ_KnownLive(*previousElementOfSplitPoint),
aStyleToRemove.mHTMLProperty,
aStyleToRemove.mAttribute, aSpecifiedStyle);
aStyleToRemove, aSpecifiedStyle);
if (MOZ_UNLIKELY(removeStyleResult.isErr())) {
NS_WARNING("HTMLEditor::RemoveStyleInside() failed");
return removeStyleResult;
@ -1416,7 +1414,7 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::ClearStyleAt(
}
Result<EditorDOMPoint, nsresult> HTMLEditor::RemoveStyleInside(
Element& aElement, nsAtom* aProperty, nsAtom* aAttribute,
Element& aElement, const EditorInlineStyle& aStyleToRemove,
SpecifiedStyle aSpecifiedStyle) {
// First, handle all descendants.
AutoTArray<OwningNonNull<nsIContent>, 32> arrayOfChildContents;
@ -1426,9 +1424,8 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::RemoveStyleInside(
if (!child->IsElement()) {
continue;
}
Result<EditorDOMPoint, nsresult> removeStyleResult =
RemoveStyleInside(MOZ_KnownLive(*child->AsElement()), aProperty,
aAttribute, aSpecifiedStyle);
Result<EditorDOMPoint, nsresult> removeStyleResult = RemoveStyleInside(
MOZ_KnownLive(*child->AsElement()), aStyleToRemove, aSpecifiedStyle);
if (MOZ_UNLIKELY(removeStyleResult.isErr())) {
NS_WARNING("HTMLEditor::RemoveStyleInside() failed");
return removeStyleResult;
@ -1440,18 +1437,19 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::RemoveStyleInside(
// Next, remove the element or its attribute.
auto ShouldRemoveHTMLStyle = [&]() {
if (aProperty) {
if (!aStyleToRemove.IsStyleToClearAllInlineStyles()) {
return
// If the element is a presentation element of aProperty
aElement.NodeInfo()->NameAtom() == aProperty ||
// If the element is a presentation element of the style
aElement.NodeInfo()->NameAtom() == aStyleToRemove.mHTMLProperty ||
// or an `<a>` element with `href` attribute
(aProperty == nsGkAtoms::href && HTMLEditUtils::IsLink(&aElement)) ||
(aStyleToRemove.mHTMLProperty == nsGkAtoms::href &&
HTMLEditUtils::IsLink(&aElement)) ||
// or an `<a>` element with `name` attribute
(aProperty == nsGkAtoms::name &&
(aStyleToRemove.mHTMLProperty == nsGkAtoms::name &&
HTMLEditUtils::IsNamedAnchor(&aElement));
}
// XXX Why do we check if aElement is editable only when aProperty is
// nullptr?
// XXX Why do we check if aElement is editable only when we're removing all
// styles?
if (EditorUtils::IsEditableContent(aElement, EditorType::HTML)) {
// or removing all styles and the element is a presentation element.
return HTMLEditUtils::IsRemovableInlineStyleElement(aElement);
@ -1460,13 +1458,14 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::RemoveStyleInside(
};
if (ShouldRemoveHTMLStyle()) {
// If aAttribute is nullptr, we want to remove any matching inline styles
// entirely.
if (!aAttribute) {
// If aStyleToRemove.mAttribute is nullptr, we want to remove any matching
// inline styles entirely.
if (!aStyleToRemove.mAttribute) {
// If some style rules are specified to aElement, we need to keep them
// as far as possible.
// XXX Why don't we clone `id` attribute?
if (aProperty && aSpecifiedStyle != SpecifiedStyle::Discard &&
if (!aStyleToRemove.IsStyleToClearAllInlineStyles() &&
aSpecifiedStyle != SpecifiedStyle::Discard &&
(aElement.HasAttr(kNameSpaceID_None, nsGkAtoms::style) ||
aElement.HasAttr(kNameSpaceID_None, nsGkAtoms::_class))) {
// Move `style` attribute and `class` element to span element before
@ -1520,10 +1519,10 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::RemoveStyleInside(
pointToPutCaret = unwrapElementResult.unwrap();
}
}
// If aAttribute is specified, we want to remove only the attribute
// unless it's the last attribute of aElement.
else if (aElement.HasAttr(kNameSpaceID_None, aAttribute)) {
if (IsOnlyAttribute(&aElement, aAttribute)) {
// If aStyleToRemove.mAttribute is specified, we want to remove only the
// attribute unless it's the last attribute of aElement.
else if (aElement.HasAttr(kNameSpaceID_None, aStyleToRemove.mAttribute)) {
if (IsOnlyAttribute(&aElement, aStyleToRemove.mAttribute)) {
Result<EditorDOMPoint, nsresult> unwrapElementResult =
RemoveContainerWithTransaction(aElement);
if (MOZ_UNLIKELY(unwrapElementResult.isErr())) {
@ -1534,7 +1533,8 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::RemoveStyleInside(
pointToPutCaret = unwrapElementResult.unwrap();
}
} else {
nsresult rv = RemoveAttributeWithTransaction(aElement, *aAttribute);
nsresult rv = RemoveAttributeWithTransaction(
aElement, *aStyleToRemove.mAttribute);
if (NS_WARN_IF(Destroyed())) {
return Err(NS_ERROR_EDITOR_DESTROYED);
}
@ -1549,10 +1549,12 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::RemoveStyleInside(
// Then, remove CSS style if specified.
// XXX aElement may have already been removed from the DOM tree. Why
// do we keep handling aElement here??
if (CSSEditUtils::IsCSSEditableProperty(&aElement, aProperty, aAttribute)) {
if (CSSEditUtils::IsCSSEditableProperty(
&aElement, aStyleToRemove.mHTMLProperty, aStyleToRemove.mAttribute)) {
Result<bool, nsresult> elementHasSpecifiedCSSEquivalentStylesOrError =
CSSEditUtils::HaveSpecifiedCSSEquivalentStyles(*this, aElement,
aProperty, aAttribute);
CSSEditUtils::HaveSpecifiedCSSEquivalentStyles(
*this, aElement, aStyleToRemove.mHTMLProperty,
aStyleToRemove.mAttribute);
if (elementHasSpecifiedCSSEquivalentStylesOrError.isErr()) {
NS_WARNING("CSSEditUtils::HaveSpecifiedCSSEquivalentStyles() failed");
return elementHasSpecifiedCSSEquivalentStylesOrError.propagateErr();
@ -1565,7 +1567,8 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::RemoveStyleInside(
// guaranteed by the caller because of MOZ_CAN_RUN_SCRIPT method.
nsresult rv =
CSSEditUtils::RemoveCSSEquivalentToHTMLStyleWithTransaction(
*this, MOZ_KnownLive(*styledElement), aProperty, aAttribute,
*this, MOZ_KnownLive(*styledElement),
aStyleToRemove.mHTMLProperty, aStyleToRemove.mAttribute,
nullptr);
if (rv == NS_ERROR_EDITOR_DESTROYED) {
NS_WARNING(
@ -1601,7 +1604,8 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::RemoveStyleInside(
}
}
if (aProperty != nsGkAtoms::font || aAttribute != nsGkAtoms::size ||
if (aStyleToRemove.mHTMLProperty != nsGkAtoms::font ||
aStyleToRemove.mAttribute != nsGkAtoms::size ||
!aElement.IsAnyOfHTMLElements(nsGkAtoms::big, nsGkAtoms::small)) {
return pointToPutCaret;
}
@ -2397,9 +2401,7 @@ nsresult HTMLEditor::RemoveInlinePropertiesAsSubAction(
if (content->IsElement()) {
Result<EditorDOMPoint, nsresult> removeStyleResult =
RemoveStyleInside(MOZ_KnownLive(*content->AsElement()),
styleToRemove.mHTMLProperty,
styleToRemove.mAttribute,
SpecifiedStyle::Preserve);
styleToRemove, SpecifiedStyle::Preserve);
if (MOZ_UNLIKELY(removeStyleResult.isErr())) {
NS_WARNING("HTMLEditor::RemoveStyleInside() failed");
return removeStyleResult.unwrapErr();