Bug 1808886 - Make the style editor treat <font> related styles as exclusive styles r=m_kato

Currently, Gecko does not support updating `font-size` style even in the CSS
mode.  Therefore, `CSSEditUtils` claims that `<font size="...">` style is not
CSS editable.  Supporting it requires a lot of new code but currently we don't
have any reports about this poor support.  Therefore, we should only try to
make the style editor remove `font-size` properties around selection at setting
`<font size="...">` style for now.

Additionally, Blink and WebKit does not allow to nest multiple `<font>` elements
and `<span>` elements which specify `font-size`, `font-family` or `color`.  When
setting one of the styles, they split ancestors which are related to the style
at range boundaries.  Then, unwrap the unnecessary elements.  This makes the
DOM tree simpler, thus, the later handling will be simpler.  Therefore, it's
worthwhile to follow them.

Unfortunately, there are some logic differences when handling styles in elements
having `id` attribute.  Therefore, there are some new test failures, but I guess
that it does not cause any problems in web apps in the wild because it's hard to
manage editable identified elements in cross browsers and I have no idea of
motivations to do it.

Depends on D166617

Differential Revision: https://phabricator.services.mozilla.com/D167011
This commit is contained in:
Masayuki Nakano 2023-01-20 03:45:58 +00:00
parent 9d80c8d3b3
commit c750faea02
15 changed files with 413 additions and 216 deletions

View File

@ -208,6 +208,11 @@ const CSSEditUtils::CSSEquivTable fontFaceEquivTable[] = {
ProcessSameValue, nullptr, nullptr, nullptr},
CSS_EQUIV_TABLE_NONE};
const CSSEditUtils::CSSEquivTable fontSizeEquivTable[] = {
{CSSEditUtils::eCSSEditableProperty_font_size, true, false,
ProcessSameValue, nullptr, nullptr, nullptr},
CSS_EQUIV_TABLE_NONE};
const CSSEditUtils::CSSEquivTable bgcolorEquivTable[] = {
{CSSEditUtils::eCSSEditableProperty_background_color, true, false,
ProcessSameValue, nullptr, nullptr, nullptr},
@ -812,13 +817,17 @@ void CSSEditUtils::GetCSSDeclarations(
if (!attributeOrStyle) {
return nullptr;
}
if (nsGkAtoms::font == htmlProperty &&
attributeOrStyle == nsGkAtoms::color) {
return fontColorEquivTable;
}
if (nsGkAtoms::font == htmlProperty &&
attributeOrStyle == nsGkAtoms::face) {
return fontFaceEquivTable;
if (nsGkAtoms::font == htmlProperty) {
if (attributeOrStyle == nsGkAtoms::color) {
return fontColorEquivTable;
}
if (attributeOrStyle == nsGkAtoms::face) {
return fontFaceEquivTable;
}
if (attributeOrStyle == nsGkAtoms::size) {
return fontSizeEquivTable;
}
MOZ_ASSERT(attributeOrStyle == nsGkAtoms::bgcolor);
}
if (attributeOrStyle == nsGkAtoms::bgcolor) {
return bgcolorEquivTable;
@ -877,7 +886,7 @@ Result<size_t, nsresult> CSSEditUtils::SetCSSEquivalentToStyle(
WithTransaction aWithTransaction, HTMLEditor& aHTMLEditor,
nsStyledElement& aStyledElement, const EditorElementStyle& aStyleToSet,
const nsAString* aValue) {
MOZ_DIAGNOSTIC_ASSERT(aStyleToSet.IsCSSEditable(aStyledElement));
MOZ_DIAGNOSTIC_ASSERT(aStyleToSet.IsCSSSettable(aStyledElement));
// we can apply the styles only if the node is an element and if we have
// an equivalence for the requested HTML style in this implementation
@ -905,7 +914,7 @@ nsresult CSSEditUtils::RemoveCSSEquivalentToStyle(
WithTransaction aWithTransaction, HTMLEditor& aHTMLEditor,
nsStyledElement& aStyledElement, const EditorElementStyle& aStyleToRemove,
const nsAString* aValue) {
MOZ_DIAGNOSTIC_ASSERT(aStyleToRemove.IsCSSEditable(aStyledElement));
MOZ_DIAGNOSTIC_ASSERT(aStyleToRemove.IsCSSRemovable(aStyledElement));
// we can apply the styles only if the node is an element and if we have
// an equivalence for the requested HTML style in this implementation
@ -941,7 +950,8 @@ nsresult CSSEditUtils::GetCSSEquivalentTo(Element& aElement,
StyleType aStyleType) {
MOZ_ASSERT_IF(aStyle.IsInlineStyle(),
!aStyle.AsInlineStyle().IsStyleToClearAllInlineStyles());
MOZ_DIAGNOSTIC_ASSERT(aStyle.IsCSSEditable(aElement));
MOZ_DIAGNOSTIC_ASSERT(aStyle.IsCSSSettable(aElement) ||
aStyle.IsCSSRemovable(aElement));
aOutValue.Truncate();
AutoTArray<CSSDeclaration, 4> cssDeclarations;
@ -1130,6 +1140,27 @@ Result<bool, nsresult> CSSEditUtils::IsCSSEquivalentTo(
isSet = true;
}
return isSet;
} else if (aStyle.IsStyleOfFontSize()) {
if (htmlValueString.IsEmpty()) {
return true;
}
switch (nsContentUtils::ParseLegacyFontSize(htmlValueString)) {
case 1:
return aInOutValue.EqualsLiteral("x-small");
case 2:
return aInOutValue.EqualsLiteral("small");
case 3:
return aInOutValue.EqualsLiteral("medium");
case 4:
return aInOutValue.EqualsLiteral("large");
case 5:
return aInOutValue.EqualsLiteral("x-large");
case 6:
return aInOutValue.EqualsLiteral("xx-large");
case 7:
return aInOutValue.EqualsLiteral("xxx-large");
}
return false;
} else if (aStyle.mAttribute == nsGkAtoms::align) {
isSet = true;
} else {

View File

@ -91,14 +91,28 @@ nsresult DOMSubtreeIterator::Init(nsRange& aRange) {
* mozilla::EditorElementStyle
*****************************************************************************/
bool EditorElementStyle::IsCSSEditable(const nsStaticAtom& aTagName) const {
bool EditorElementStyle::IsCSSSettable(const nsStaticAtom& aTagName) const {
return CSSEditUtils::IsCSSEditableStyle(aTagName, *this);
}
bool EditorElementStyle::IsCSSEditable(const Element& aElement) const {
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
*****************************************************************************/
@ -143,7 +157,7 @@ bool EditorInlineStyle::IsRepresentedBy(const nsIContent& aContent) const {
Result<bool, nsresult> EditorInlineStyle::IsSpecifiedBy(
const HTMLEditor& aHTMLEditor, Element& aElement) const {
MOZ_ASSERT(!IsStyleToClearAllInlineStyles());
if (!IsCSSEditable(aElement)) {
if (!IsCSSSettable(aElement) && !IsCSSRemovable(aElement)) {
return false;
}
// Special case in the CSS mode. We should treat <u>, <s>, <strike>, <ins>

View File

@ -15,6 +15,7 @@
#include "EditorDOMPoint.h"
#include "EditorForwards.h"
#include "EditorUtils.h" // for CaretPoint
#include "HTMLEditHelpers.h"
#include "JoinSplitNodeDirection.h"
#include "mozilla/AlreadyAddRefed.h"
@ -923,8 +924,19 @@ class MOZ_STACK_CLASS EditorElementStyle {
aAttribute == nsGkAtoms::valign || aAttribute == nsGkAtoms::width;
}
[[nodiscard]] bool IsCSSEditable(const nsStaticAtom& aTagName) const;
[[nodiscard]] bool IsCSSEditable(const dom::Element& aElement) const;
/**
* Returns true if the style can be represented by CSS and it's possible to
* apply the style with CSS.
*/
[[nodiscard]] bool IsCSSSettable(const nsStaticAtom& aTagName) const;
[[nodiscard]] bool IsCSSSettable(const dom::Element& aElement) const;
/**
* Returns true if the style can be represented by CSS and it's possible to
* remove the style with CSS.
*/
[[nodiscard]] bool IsCSSRemovable(const nsStaticAtom& aTagName) const;
[[nodiscard]] bool IsCSSRemovable(const dom::Element& aElement) const;
nsStaticAtom* Style() const { return mStyle; }
@ -1005,6 +1017,13 @@ struct MOZ_STACK_CLASS EditorInlineStyle : public EditorElementStyle {
return mHTMLProperty == nsGkAtoms::font && mAttribute != nsGkAtoms::bgcolor;
}
/**
* Returns true if the style is font-size or <font size="...">.
*/
[[nodiscard]] bool IsStyleOfFontSize() const {
return mHTMLProperty == nsGkAtoms::font && mAttribute == nsGkAtoms::size;
}
/**
* Returns true if the style is conflict with vertical-align even though
* they are not mapped to vertical-align in the CSS mode.
@ -1045,16 +1064,10 @@ struct MOZ_STACK_CLASS EditorInlineStyle : public EditorElementStyle {
explicit EditorInlineStyle(const nsStaticAtom& aHTMLProperty,
nsAtom* aAttribute = nullptr)
// Needs const_cast hack here because the struct users may want
// non-const nsStaticAtom pointer due to bug 1794954
: mHTMLProperty(const_cast<nsStaticAtom*>(&aHTMLProperty)),
mAttribute(aAttribute) {}
: EditorInlineStyle(aHTMLProperty, aAttribute, HasValue::No) {}
EditorInlineStyle(const nsStaticAtom& aHTMLProperty,
RefPtr<nsAtom>&& aAttribute)
// Needs const_cast hack here because the struct users may want
// non-const nsStaticAtom pointer due to bug 1794954
: mHTMLProperty(const_cast<nsStaticAtom*>(&aHTMLProperty)),
mAttribute(std::move(aAttribute)) {}
: EditorInlineStyle(aHTMLProperty, aAttribute, HasValue::No) {}
/**
* Returns the instance which means remove all inline styles.
@ -1068,6 +1081,33 @@ struct MOZ_STACK_CLASS EditorInlineStyle : public EditorElementStyle {
mAttribute == aOther.mAttribute;
}
bool MaybeHasValue() const { return mMaybeHasValue; }
inline EditorInlineStyleAndValue& AsInlineStyleAndValue();
inline const EditorInlineStyleAndValue& AsInlineStyleAndValue() const;
protected:
const bool mMaybeHasValue = false;
enum class HasValue { No, Yes };
EditorInlineStyle(const nsStaticAtom& aHTMLProperty, nsAtom* aAttribute,
HasValue aHasValue)
// Needs const_cast hack here because the struct users may want
// non-const nsStaticAtom pointer due to bug 1794954
: mHTMLProperty(const_cast<nsStaticAtom*>(&aHTMLProperty)),
mAttribute(aAttribute),
mMaybeHasValue(aHasValue == HasValue::Yes) {}
EditorInlineStyle(const nsStaticAtom& aHTMLProperty,
RefPtr<nsAtom>&& aAttribute, HasValue aHasValue)
// Needs const_cast hack here because the struct users may want
// non-const nsStaticAtom pointer due to bug 1794954
: mHTMLProperty(const_cast<nsStaticAtom*>(&aHTMLProperty)),
mAttribute(std::move(aAttribute)),
mMaybeHasValue(aHasValue == HasValue::Yes) {}
EditorInlineStyle(const EditorInlineStyle& aStyle, HasValue aHasValue)
: mHTMLProperty(aStyle.mHTMLProperty),
mAttribute(aStyle.mAttribute),
mMaybeHasValue(aHasValue == HasValue::Yes) {}
private:
EditorInlineStyle() = default;
@ -1096,25 +1136,25 @@ struct MOZ_STACK_CLASS EditorInlineStyleAndValue : public EditorInlineStyle {
EditorInlineStyleAndValue() = delete;
explicit EditorInlineStyleAndValue(nsStaticAtom& aHTMLProperty)
: EditorInlineStyle(aHTMLProperty) {}
: EditorInlineStyle(aHTMLProperty, nullptr, HasValue::No) {}
EditorInlineStyleAndValue(nsStaticAtom& aHTMLProperty, nsAtom& aAttribute,
const nsAString& aValue)
: EditorInlineStyle(aHTMLProperty, &aAttribute),
: EditorInlineStyle(aHTMLProperty, &aAttribute, HasValue::Yes),
mAttributeValue(aValue) {}
EditorInlineStyleAndValue(nsStaticAtom& aHTMLProperty,
RefPtr<nsAtom>&& aAttribute,
const nsAString& aValue)
: EditorInlineStyle(aHTMLProperty, std::move(aAttribute)),
: EditorInlineStyle(aHTMLProperty, std::move(aAttribute), HasValue::Yes),
mAttributeValue(aValue) {
MOZ_ASSERT(mAttribute);
}
EditorInlineStyleAndValue(nsStaticAtom& aHTMLProperty, nsAtom& aAttribute,
nsString&& aValue)
: EditorInlineStyle(aHTMLProperty, &aAttribute),
: EditorInlineStyle(aHTMLProperty, &aAttribute, HasValue::Yes),
mAttributeValue(std::move(aValue)) {}
EditorInlineStyleAndValue(nsStaticAtom& aHTMLProperty,
RefPtr<nsAtom>&& aAttribute, nsString&& aValue)
: EditorInlineStyle(aHTMLProperty, std::move(aAttribute)),
: EditorInlineStyle(aHTMLProperty, std::move(aAttribute), HasValue::Yes),
mAttributeValue(aValue) {}
[[nodiscard]] static EditorInlineStyleAndValue ToInvert(
@ -1154,9 +1194,21 @@ struct MOZ_STACK_CLASS EditorInlineStyleAndValue : public EditorInlineStyle {
EditorInlineStyleAndValue(const EditorInlineStyle& aStyle,
const nsAString& aValue)
: EditorInlineStyle(aStyle), mAttributeValue(aValue) {}
: EditorInlineStyle(aStyle, HasValue::Yes), mAttributeValue(aValue) {}
using EditorInlineStyle::AsInlineStyleAndValue;
using EditorInlineStyle::HasValue;
};
inline EditorInlineStyleAndValue& EditorInlineStyle::AsInlineStyleAndValue() {
return reinterpret_cast<EditorInlineStyleAndValue&>(*this);
}
inline const EditorInlineStyleAndValue&
EditorInlineStyle::AsInlineStyleAndValue() const {
return reinterpret_cast<const EditorInlineStyleAndValue&>(*this);
}
} // namespace mozilla
#endif // #ifndef HTMLEditHelpers_h

View File

@ -6695,7 +6695,7 @@ Result<CreateElementResult, nsresult> HTMLEditor::AlignNodesAndDescendants(
nsStyledElement* styledListOrListItemElement =
nsStyledElement::FromNode(listOrListItemElement);
if (styledListOrListItemElement &&
EditorElementStyle::Align().IsCSSEditable(
EditorElementStyle::Align().IsCSSSettable(
*styledListOrListItemElement)) {
// MOZ_KnownLive(*styledListOrListItemElement): An element of
// aArrayOfContents which is array of OwningNonNull.
@ -9219,7 +9219,7 @@ nsresult HTMLEditor::GetInlineStyles(
if (property == nsGkAtoms::size) {
isSet = HTMLEditUtils::IsInlineStyleSetByElement(aElement, style, nullptr,
&value);
} else if (style.IsCSSEditable(aElement)) {
} else if (style.IsCSSSettable(aElement)) {
Result<bool, nsresult> isComputedCSSEquivalentToStyleOrError =
CSSEditUtils::IsComputedCSSEquivalentTo(*this, aElement, style,
value);
@ -9279,7 +9279,7 @@ nsresult HTMLEditor::ReapplyCachedStyles() {
bool isFirst = false, isAny = false, isAll = false;
nsAutoString currentValue;
const EditorInlineStyle inlineStyle = styleCacheBeforeEdit.ToInlineStyle();
if (useCSS && inlineStyle.IsCSSEditable(*startContainerElement)) {
if (useCSS && inlineStyle.IsCSSSettable(*startContainerElement)) {
// check computed style first in css case
// MOZ_KnownLive(styleCacheBeforeEdit.*) because they are nsStaticAtom
// and its instances are alive until shutting down.

View File

@ -5747,7 +5747,7 @@ nsresult HTMLEditor::SetAttributeOrEquivalent(Element* aElement,
if (EditorElementStyle::IsHTMLStyle(aAttribute)) {
const EditorElementStyle elementStyle =
EditorElementStyle::Create(*aAttribute);
if (styledElement && elementStyle.IsCSSEditable(*styledElement)) {
if (styledElement && elementStyle.IsCSSRemovable(*styledElement)) {
// MOZ_KnownLive(*styledElement): It's aElement and its lifetime must
// be guaranteed by the caller because of MOZ_CAN_RUN_SCRIPT method.
nsresult rv = CSSEditUtils::RemoveCSSEquivalentToStyle(
@ -5776,7 +5776,7 @@ nsresult HTMLEditor::SetAttributeOrEquivalent(Element* aElement,
if (EditorElementStyle::IsHTMLStyle(aAttribute)) {
const EditorElementStyle elementStyle =
EditorElementStyle::Create(*aAttribute);
if (styledElement && elementStyle.IsCSSEditable(*styledElement)) {
if (styledElement && elementStyle.IsCSSSettable(*styledElement)) {
// MOZ_KnownLive(*styledElement): It's aElement and its lifetime must
// be guaranteed by the caller because of MOZ_CAN_RUN_SCRIPT method.
Result<size_t, nsresult> count = CSSEditUtils::SetCSSEquivalentToStyle(
@ -5863,7 +5863,7 @@ nsresult HTMLEditor::RemoveAttributeOrEquivalent(Element* aElement,
if (IsCSSEnabled() && EditorElementStyle::IsHTMLStyle(aAttribute)) {
const EditorElementStyle elementStyle =
EditorElementStyle::Create(*aAttribute);
if (elementStyle.IsCSSEditable(*aElement)) {
if (elementStyle.IsCSSRemovable(*aElement)) {
// XXX It might be keep handling attribute even if aElement is not
// an nsStyledElement instance.
nsStyledElement* styledElement =
@ -5970,7 +5970,7 @@ nsresult HTMLEditor::SetBlockBackgroundColorWithCSSAsSubAction(
*range.StartRef().ContainerAs<Text>(),
HTMLEditUtils::ClosestEditableBlockElement));
if (!editableBlockStyledElement ||
!EditorElementStyle::BGColor().IsCSSEditable(
!EditorElementStyle::BGColor().IsCSSSettable(
*editableBlockStyledElement)) {
continue;
}
@ -5995,7 +5995,7 @@ nsresult HTMLEditor::SetBlockBackgroundColorWithCSSAsSubAction(
const RefPtr<nsStyledElement> styledElement =
range.StartRef().GetContainerAs<nsStyledElement>();
if (!styledElement ||
!EditorElementStyle::BGColor().IsCSSEditable(*styledElement)) {
!EditorElementStyle::BGColor().IsCSSSettable(*styledElement)) {
continue;
}
Result<size_t, nsresult> result = CSSEditUtils::SetCSSEquivalentToStyle(
@ -6026,7 +6026,7 @@ nsresult HTMLEditor::SetBlockBackgroundColorWithCSSAsSubAction(
*range.StartRef().GetChild(),
HTMLEditUtils::ClosestEditableBlockElement));
if (!editableBlockStyledElement ||
!EditorElementStyle::BGColor().IsCSSEditable(
!EditorElementStyle::BGColor().IsCSSSettable(
*editableBlockStyledElement)) {
continue;
}
@ -6087,7 +6087,7 @@ nsresult HTMLEditor::SetBlockBackgroundColorWithCSSAsSubAction(
nsStyledElement* const blockStyledElement =
nsStyledElement::FromNode(handledBlockParent);
if (blockStyledElement &&
EditorElementStyle::BGColor().IsCSSEditable(*blockStyledElement)) {
EditorElementStyle::BGColor().IsCSSSettable(*blockStyledElement)) {
// MOZ_KnownLive(*blockStyledElement): It's handledBlockParent
// whose type is RefPtr.
Result<size_t, nsresult> result =
@ -6118,7 +6118,7 @@ nsresult HTMLEditor::SetBlockBackgroundColorWithCSSAsSubAction(
nsStyledElement* const blockStyledElement =
nsStyledElement::FromNode(handledBlockParent);
if (blockStyledElement &&
EditorElementStyle::BGColor().IsCSSEditable(*blockStyledElement)) {
EditorElementStyle::BGColor().IsCSSSettable(*blockStyledElement)) {
// MOZ_KnownLive(*blockStyledElement): It's handledBlockParent whose
// type is RefPtr.
Result<size_t, nsresult> result =
@ -6150,7 +6150,7 @@ nsresult HTMLEditor::SetBlockBackgroundColorWithCSSAsSubAction(
const RefPtr<nsStyledElement> blockStyledElement =
nsStyledElement::FromNode(editableBlockElement);
if (blockStyledElement &&
EditorElementStyle::BGColor().IsCSSEditable(*blockStyledElement)) {
EditorElementStyle::BGColor().IsCSSSettable(*blockStyledElement)) {
Result<size_t, nsresult> result =
CSSEditUtils::SetCSSEquivalentToStyle(
WithTransaction::Yes, *this, *blockStyledElement,

View File

@ -868,14 +868,18 @@ class HTMLEditor final : public EditorBase,
* SplitAncestorStyledInlineElementsAtRangeEdges() splits all ancestor inline
* elements in the block at aRange if given style matches with some of them.
*
* @param aRange Ancestor inline elements of the start and end boundaries
* will be split.
* @param aStyle The style which you want to split. RemoveAllStyles
* instance is allowed to split any inline elements.
* @param aRange Ancestor inline elements of the start and end
* boundaries will be split.
* @param aStyle The style which you want to split.
* RemoveAllStyles instance is allowed to split any
* inline elements.
* @param aSplitAtEdges Whether this should split elements at start or
* end of inline elements or not.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<SplitRangeOffResult, nsresult>
SplitAncestorStyledInlineElementsAtRangeEdges(
const EditorDOMRange& aRange, const EditorInlineStyle& aStyle);
SplitAncestorStyledInlineElementsAtRangeEdges(const EditorDOMRange& aRange,
const EditorInlineStyle& aStyle,
SplitAtEdges aSplitAtEdges);
/**
* SplitAncestorStyledInlineElementsAt() splits ancestor inline elements at

View File

@ -336,7 +336,7 @@ AlignStateAtSelection::AlignStateAtSelection(HTMLEditor& aHTMLEditor,
return;
}
if (aHTMLEditor.IsCSSEnabled() && EditorElementStyle::Align().IsCSSEditable(
if (aHTMLEditor.IsCSSEnabled() && EditorElementStyle::Align().IsCSSSettable(
*maybeNonEditableBlockElement)) {
// We are in CSS mode and we know how to align this element with CSS
nsAutoString value;
@ -379,7 +379,7 @@ AlignStateAtSelection::AlignStateAtSelection(HTMLEditor& aHTMLEditor,
return;
}
if (EditorElementStyle::Align().IsCSSEditable(*containerElement)) {
if (EditorElementStyle::Align().IsCSSSettable(*containerElement)) {
nsAutoString value;
DebugOnly<nsresult> rvIgnored = CSSEditUtils::GetSpecifiedProperty(
*containerElement, *nsGkAtoms::textAlign, value);

View File

@ -3,6 +3,7 @@
* 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 "ErrorList.h"
#include "HTMLEditor.h"
#include "HTMLEditorInlines.h"
#include "HTMLEditorNestedClasses.h"
@ -32,7 +33,9 @@
#include "nsAString.h"
#include "nsAtom.h"
#include "nsAttrName.h"
#include "nsAttrValue.h"
#include "nsCaseTreatment.h"
#include "nsColor.h"
#include "nsComponentManagerUtils.h"
#include "nsDebug.h"
#include "nsError.h"
@ -291,15 +294,48 @@ nsresult HTMLEditor::SetInlinePropertiesAroundRanges(
AutoInlineStyleSetter inlineStyleSetter(styleToSet);
for (OwningNonNull<nsRange>& domRange : aRanges.Ranges()) {
inlineStyleSetter.Reset();
const EditorDOMRange range = [&]() {
auto rangeOrError =
[&]() MOZ_CAN_RUN_SCRIPT -> Result<EditorDOMRange, nsresult> {
if (aRanges.HasSavedRanges()) {
return EditorDOMRange(
GetExtendedRangeWrappingEntirelySelectedElements(
EditorRawDOMRange(domRange)));
}
EditorDOMRange range(domRange);
// If we're setting <font>, we want to remove ancestors which set
// `font-size` or <font size="..."> recursively. Therefore, for
// extending the ranges to contain all ancestors in the range, we need
// to split ancestors first.
// XXX: Blink and WebKit inserts <font> elements to inner most
// elements, however, we cannot do it under current design because
// once we contain ancestors which have `font-size` or are
// <font size="...">, we lost the original ranges which we wanted to
// apply the style. For fixing this, we need to manage both ranges, but
// it's too expensive especially we allow to run script when we touch
// the DOM tree. Additionally, font-size value affects the height
// of the element, but does not affect the height of ancestor inline
// elements. Therefore, following the behavior may cause similar issue
// as bug 1808906. So at least for now, we should not do this big work.
if (styleToSet.IsStyleOfFontElement()) {
Result<SplitRangeOffResult, nsresult> splitAncestorsResult =
SplitAncestorStyledInlineElementsAtRangeEdges(
range, styleToSet, SplitAtEdges::eDoNotCreateEmptyContainer);
if (MOZ_UNLIKELY(splitAncestorsResult.isErr())) {
NS_WARNING(
"HTMLEditor::SplitAncestorStyledInlineElementsAtRangeEdges() "
"failed");
return splitAncestorsResult.propagateErr();
}
SplitRangeOffResult unwrappedResult = splitAncestorsResult.unwrap();
unwrappedResult.IgnoreCaretPointSuggestion();
range = unwrappedResult.RangeRef();
if (NS_WARN_IF(!range.IsPositionedAndValid())) {
return Err(NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE);
}
}
Result<EditorRawDOMRange, nsresult> rangeOrError =
inlineStyleSetter.ExtendOrShrinkRangeToApplyTheStyle(
*this, EditorDOMRange(domRange), aEditingHost);
inlineStyleSetter.ExtendOrShrinkRangeToApplyTheStyle(*this, range,
aEditingHost);
if (MOZ_UNLIKELY(rangeOrError.isErr())) {
NS_WARNING(
"HTMLEditor::ExtendOrShrinkRangeToApplyTheStyle() failed, but "
@ -308,6 +344,11 @@ nsresult HTMLEditor::SetInlinePropertiesAroundRanges(
}
return EditorDOMRange(rangeOrError.unwrap());
}();
if (MOZ_UNLIKELY(rangeOrError.isErr())) {
return rangeOrError.unwrapErr();
}
const EditorDOMRange range = rangeOrError.unwrap();
if (!range.IsPositioned()) {
continue;
}
@ -572,7 +613,7 @@ HTMLEditor::AutoInlineStyleSetter::ElementIsGoodContainerForTheStyle(
HTMLEditor& aHTMLEditor, Element& aElement) const {
// If the editor is in the CSS mode and the style can be specified with CSS,
// we should not use existing HTML element as a new container.
const bool isCSSEditable = IsCSSEditable(aElement);
const bool isCSSEditable = IsCSSSettable(aElement);
if (!aHTMLEditor.IsCSSEnabled() || !isCSSEditable) {
// First check for <b>, <i>, etc.
if (aElement.IsHTMLElement(&HTMLPropertyRef()) &&
@ -757,7 +798,7 @@ HTMLEditor::AutoInlineStyleSetter::SplitTextNodeAndApplyStyleToMiddleNode(
}
// Don't need to do anything if property already set on node
if (IsCSSEditable(*element)) {
if (IsCSSSettable(*element)) {
// The HTML styles defined by this have a CSS equivalence for node;
// let's check if it carries those CSS styles
nsAutoString value(mAttributeValue);
@ -1055,7 +1096,7 @@ Result<CaretPoint, nsresult> HTMLEditor::AutoInlineStyleSetter::ApplyStyle(
// Don't need to do anything if property already set on node
if (const RefPtr<Element> element = aContent.GetAsElementOrParentElement()) {
if (IsCSSEditable(*element)) {
if (IsCSSSettable(*element)) {
nsAutoString value(mAttributeValue);
// MOZ_KnownLive(element) because it's aContent.
Result<bool, nsresult> isComputedCSSEquivalentToStyleOrError =
@ -1079,7 +1120,7 @@ Result<CaretPoint, nsresult> HTMLEditor::AutoInlineStyleSetter::ApplyStyle(
auto ShouldUseCSS = [&]() {
return (aHTMLEditor.IsCSSEnabled() &&
aContent.GetAsElementOrParentElement() &&
IsCSSEditable(*aContent.GetAsElementOrParentElement())) ||
IsCSSSettable(*aContent.GetAsElementOrParentElement())) ||
// bgcolor is always done using CSS
mAttribute == nsGkAtoms::bgcolor ||
// called for removing parent style, we should use CSS with
@ -1132,7 +1173,7 @@ Result<CaretPoint, nsresult> HTMLEditor::AutoInlineStyleSetter::ApplyStyle(
}
// Add the CSS styles corresponding to the HTML style request
if (IsCSSEditable(*styledElement)) {
if (IsCSSSettable(*styledElement)) {
Result<size_t, nsresult> result = CSSEditUtils::SetCSSEquivalentToStyle(
WithTransaction::Yes, aHTMLEditor, *styledElement, *this,
&mAttributeValue);
@ -1200,7 +1241,7 @@ HTMLEditor::AutoInlineStyleSetter::ApplyCSSTextDecoration(
"Was new value added in "
"IsStyleOfTextDecoration(IgnoreSElement::No))?");
}
if (styledElement && IsCSSEditable(*styledElement) &&
if (styledElement && IsCSSSettable(*styledElement) &&
ElementIsGoodContainerToSetStyle(*styledElement)) {
nsAutoString textDecorationValue;
nsresult rv = CSSEditUtils::GetSpecifiedProperty(
@ -1601,8 +1642,11 @@ EditorRawDOMPoint HTMLEditor::AutoInlineStyleSetter::
return startPoint;
}
const bool useCSS = aHTMLEditor.IsCSSEnabled();
const bool isFontElementStyle = IsStyleOfFontElement();
// FYI: Currently, we don't support setting `font-size` even in the CSS mode.
// Therefore, if the style is <font size="...">, we always set a <font>.
const bool isSettingFontElement =
IsStyleOfFontSize() ||
(!aHTMLEditor.IsCSSEnabled() && IsStyleOfFontElement());
Element* mostDistantStartParentHavingStyle = nullptr;
for (Element* parent :
startPoint.GetContainer()->InclusiveAncestorsOfType<Element>()) {
@ -1616,8 +1660,7 @@ EditorRawDOMPoint HTMLEditor::AutoInlineStyleSetter::
}
// If we're setting <font> element and there is a <font> element which is
// entirely selected, we should use it.
else if (!useCSS && isFontElementStyle &&
parent->IsHTMLElement(nsGkAtoms::font)) {
else if (isSettingFontElement && parent->IsHTMLElement(nsGkAtoms::font)) {
mostDistantStartParentHavingStyle = parent;
}
if (parent->GetPreviousSibling()) {
@ -1641,8 +1684,11 @@ EditorRawDOMPoint HTMLEditor::AutoInlineStyleSetter::
return endPoint;
}
const bool useCSS = aHTMLEditor.IsCSSEnabled();
const bool isFontElementStyle = IsStyleOfFontElement();
// FYI: Currently, we don't support setting `font-size` even in the CSS mode.
// Therefore, if the style is <font size="...">, we always set a <font>.
const bool isSettingFontElement =
IsStyleOfFontSize() ||
(!aHTMLEditor.IsCSSEnabled() && IsStyleOfFontElement());
Element* mostDistantEndParentHavingStyle = nullptr;
for (Element* parent :
endPoint.GetContainer()->InclusiveAncestorsOfType<Element>()) {
@ -1656,8 +1702,7 @@ EditorRawDOMPoint HTMLEditor::AutoInlineStyleSetter::
}
// If we're setting <font> element and there is a <font> element which is
// entirely selected, we should use it.
else if (!useCSS && isFontElementStyle &&
parent->IsHTMLElement(nsGkAtoms::font)) {
else if (isSettingFontElement && parent->IsHTMLElement(nsGkAtoms::font)) {
mostDistantEndParentHavingStyle = parent;
}
if (parent->GetNextSibling()) {
@ -1717,7 +1762,7 @@ EditorRawDOMRange HTMLEditor::AutoInlineStyleSetter::
// should have the new style into the range to avoid creating new <span>
// element.
if (!IsRepresentableWithHTML() ||
(aHTMLEditor.IsCSSEnabled() && IsCSSEditable(*nsGkAtoms::span))) {
(aHTMLEditor.IsCSSEnabled() && IsCSSSettable(*nsGkAtoms::span))) {
// First, if pointing in a text node, use parent point.
if (aStartPoint.IsInContentNode() && aStartPoint.IsStartOfContainer() &&
aStartPoint.GetContainerParentAs<nsIContent>() &&
@ -1902,7 +1947,8 @@ HTMLEditor::AutoInlineStyleSetter::ExtendOrShrinkRangeToApplyTheStyle(
Result<SplitRangeOffResult, nsresult>
HTMLEditor::SplitAncestorStyledInlineElementsAtRangeEdges(
const EditorDOMRange& aRange, const EditorInlineStyle& aStyle) {
const EditorDOMRange& aRange, const EditorInlineStyle& aStyle,
SplitAtEdges aSplitAtEdges) {
MOZ_ASSERT(IsEditActionDataAvailable());
if (NS_WARN_IF(!aRange.IsPositioned())) {
@ -1916,9 +1962,8 @@ HTMLEditor::SplitAncestorStyledInlineElementsAtRangeEdges(
[&]() MOZ_CAN_RUN_SCRIPT -> Result<SplitNodeResult, nsresult> {
AutoTrackDOMRange tracker(RangeUpdaterRef(), &range);
Result<SplitNodeResult, nsresult> result =
SplitAncestorStyledInlineElementsAt(
range.StartRef(), aStyle,
SplitAtEdges::eAllowToCreateEmptyContainer);
SplitAncestorStyledInlineElementsAt(range.StartRef(), aStyle,
aSplitAtEdges);
if (MOZ_UNLIKELY(result.isErr())) {
NS_WARNING("HTMLEditor::SplitAncestorStyledInlineElementsAt() failed");
return result;
@ -1947,8 +1992,8 @@ HTMLEditor::SplitAncestorStyledInlineElementsAtRangeEdges(
[&]() MOZ_CAN_RUN_SCRIPT -> Result<SplitNodeResult, nsresult> {
AutoTrackDOMRange tracker(RangeUpdaterRef(), &range);
Result<SplitNodeResult, nsresult> result =
SplitAncestorStyledInlineElementsAt(
range.EndRef(), aStyle, SplitAtEdges::eAllowToCreateEmptyContainer);
SplitAncestorStyledInlineElementsAt(range.EndRef(), aStyle,
aSplitAtEdges);
if (MOZ_UNLIKELY(result.isErr())) {
NS_WARNING("HTMLEditor::SplitAncestorStyledInlineElementsAt() failed");
return result;
@ -2001,15 +2046,15 @@ HTMLEditor::SplitAncestorStyledInlineElementsAt(
const bool handleCSS =
aStyle.mHTMLProperty != nsGkAtoms::tt || IsCSSEnabled();
AutoTArray<OwningNonNull<nsIContent>, 24> arrayOfParents;
for (nsIContent* content :
aPointToSplit.GetContainer()->InclusiveAncestorsOfType<nsIContent>()) {
if (HTMLEditUtils::IsBlockElement(*content) || !content->GetParent() ||
!EditorUtils::IsEditableContent(*content->GetParent(),
AutoTArray<OwningNonNull<Element>, 24> arrayOfParents;
for (Element* element :
aPointToSplit.GetContainer()->InclusiveAncestorsOfType<Element>()) {
if (HTMLEditUtils::IsBlockElement(*element) || !element->GetParent() ||
!EditorUtils::IsEditableContent(*element->GetParent(),
EditorType::HTML)) {
break;
}
arrayOfParents.AppendElement(*content);
arrayOfParents.AppendElement(*element);
}
// Split any matching style nodes above the point.
@ -2017,7 +2062,7 @@ HTMLEditor::SplitAncestorStyledInlineElementsAt(
SplitNodeResult::NotHandled(aPointToSplit, GetSplitNodeDirection());
MOZ_ASSERT(!result.Handled());
EditorDOMPoint pointToPutCaret;
for (OwningNonNull<nsIContent>& content : arrayOfParents) {
for (OwningNonNull<Element>& element : arrayOfParents) {
auto isSetByCSSOrError = [&]() -> Result<bool, nsresult> {
if (!handleCSS) {
return false;
@ -2025,11 +2070,10 @@ HTMLEditor::SplitAncestorStyledInlineElementsAt(
// The HTML style defined by aStyle has a CSS equivalence in this
// implementation for the node; let's check if it carries those CSS
// styles
if (MOZ_LIKELY(content->GetAsElementOrParentElement()) &&
aStyle.IsCSSEditable(*content->GetAsElementOrParentElement())) {
if (aStyle.IsCSSRemovable(*element)) {
nsAutoString firstValue;
Result<bool, nsresult> isSpecifiedByCSSOrError =
CSSEditUtils::IsSpecifiedCSSEquivalentTo(*this, *content, aStyle,
CSSEditUtils::IsSpecifiedCSSEquivalentTo(*this, *element, aStyle,
firstValue);
if (MOZ_UNLIKELY(isSpecifiedByCSSOrError.isErr())) {
result.IgnoreCaretPointSuggestion();
@ -2049,7 +2093,7 @@ HTMLEditor::SplitAncestorStyledInlineElementsAt(
if (aStyle.IsStyleConflictingWithVerticalAlign()) {
nsAutoString value;
nsresult rv = CSSEditUtils::GetSpecifiedProperty(
*content, *nsGkAtoms::vertical_align, value);
*element, *nsGkAtoms::vertical_align, value);
if (NS_FAILED(rv)) {
NS_WARNING("CSSEditUtils::GetSpecifiedProperty() failed");
result.IgnoreCaretPointSuggestion();
@ -2065,23 +2109,54 @@ HTMLEditor::SplitAncestorStyledInlineElementsAt(
return isSetByCSSOrError.propagateErr();
}
if (!isSetByCSSOrError.inspect()) {
if (!content->IsElement()) {
continue;
}
if (!aStyle.IsStyleToClearAllInlineStyles()) {
// If the content is an inline element represents the style or
// the content is a link element and the style is `href`, we should
// split the content.
if (!content->IsHTMLElement(aStyle.mHTMLProperty) &&
!(aStyle.mHTMLProperty == nsGkAtoms::href &&
HTMLEditUtils::IsLink(content))) {
// If we're removing a link style and the element is an <a href>, we
// need to split it.
if (aStyle.mHTMLProperty == nsGkAtoms::href &&
HTMLEditUtils::IsLink(element)) {
}
// If we're removing HTML style, we should split only the element
// which represents the style.
else if (!element->IsHTMLElement(aStyle.mHTMLProperty) ||
(aStyle.mAttribute && !element->HasAttr(aStyle.mAttribute))) {
continue;
}
// If we're setting <font> related styles, it means that we're not
// toggling the style. In this case, we need to remove parent <font>
// elements and/or update parent <font> elements if there are some
// elements which have the attribute. However, we should not touch if
// the value is same as what the caller setting to keep the DOM tree
// as-is as far as possible.
if (aStyle.IsStyleOfFontElement() && aStyle.MaybeHasValue()) {
const nsAttrValue* const attrValue =
element->GetParsedAttr(aStyle.mAttribute);
if (attrValue) {
if (aStyle.mAttribute == nsGkAtoms::size) {
if (nsContentUtils::ParseLegacyFontSize(
aStyle.AsInlineStyleAndValue().mAttributeValue) ==
attrValue->GetIntegerValue()) {
continue;
}
} else if (aStyle.mAttribute == nsGkAtoms::color) {
nsAttrValue newValue;
nscolor oldColor, newColor;
if (attrValue->GetColorValue(oldColor) &&
newValue.ParseColor(
aStyle.AsInlineStyleAndValue().mAttributeValue) &&
newValue.GetColorValue(newColor) && oldColor == newColor) {
continue;
}
} else if (attrValue->Equals(
aStyle.AsInlineStyleAndValue().mAttributeValue,
eIgnoreCase)) {
continue;
}
}
}
}
// If aProperty is nullptr, we need to split any style.
else if (!EditorUtils::IsEditableContent(content, EditorType::HTML) ||
!HTMLEditUtils::IsRemovableInlineStyleElement(
*content->AsElement())) {
else if (!EditorUtils::IsEditableContent(element, EditorType::HTML) ||
!HTMLEditUtils::IsRemovableInlineStyleElement(*element)) {
continue;
}
}
@ -2093,7 +2168,7 @@ HTMLEditor::SplitAncestorStyledInlineElementsAt(
// is a block, we do nothing but return as handled.
AutoTrackDOMPoint trackPointToPutCaret(RangeUpdaterRef(), &pointToPutCaret);
Result<SplitNodeResult, nsresult> splitNodeResult =
SplitNodeDeepWithTransaction(MOZ_KnownLive(content),
SplitNodeDeepWithTransaction(MOZ_KnownLive(element),
result.AtSplitPoint<EditorDOMPoint>(),
aSplitAtEdges);
if (MOZ_UNLIKELY(splitNodeResult.isErr())) {
@ -2429,9 +2504,8 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::RemoveStyleInside(
// Next, remove CSS style first. Then, `style` attribute will be removed if
// the corresponding CSS property is last one.
const bool isCSSEditable = aStyleToRemove.IsCSSEditable(aElement);
auto isStyleSpecifiedOrError = [&]() -> Result<bool, nsresult> {
if (!isCSSEditable) {
if (!aStyleToRemove.IsCSSRemovable(aElement)) {
return false;
}
MOZ_ASSERT(!aStyleToRemove.IsStyleToClearAllInlineStyles());
@ -2794,7 +2868,7 @@ nsresult HTMLEditor::GetInlinePropertyBase(const EditorInlineStyle& aStyle,
nsIContent::FromNode(range->GetStartContainer());
if (MOZ_LIKELY(collapsedContent &&
collapsedContent->GetAsElementOrParentElement()) &&
aStyle.IsCSSEditable(
aStyle.IsCSSSettable(
*collapsedContent->GetAsElementOrParentElement())) {
if (aValue) {
tOutString.Assign(*aValue);
@ -2860,7 +2934,7 @@ nsresult HTMLEditor::GetInlinePropertyBase(const EditorInlineStyle& aStyle,
bool isSet = false;
if (first) {
if (element) {
if (aStyle.IsCSSEditable(*element)) {
if (aStyle.IsCSSSettable(*element)) {
// The HTML styles defined by aHTMLProperty/aAttribute have a CSS
// equivalence in this implementation for node; let's check if it
// carries those CSS styles
@ -2887,7 +2961,7 @@ nsresult HTMLEditor::GetInlinePropertyBase(const EditorInlineStyle& aStyle,
}
} else {
if (element) {
if (aStyle.IsCSSEditable(*element)) {
if (aStyle.IsCSSSettable(*element)) {
// The HTML styles defined by aHTMLProperty/aAttribute have a CSS
// equivalence in this implementation for node; let's check if it
// carries those CSS styles
@ -3233,7 +3307,8 @@ nsresult HTMLEditor::RemoveInlinePropertiesAsSubAction(
// Remove this style from ancestors of our range endpoints, splitting
// them as appropriate
Result<SplitRangeOffResult, nsresult> splitRangeOffResult =
SplitAncestorStyledInlineElementsAtRangeEdges(range, styleToRemove);
SplitAncestorStyledInlineElementsAtRangeEdges(
range, styleToRemove, SplitAtEdges::eAllowToCreateEmptyContainer);
if (MOZ_UNLIKELY(splitRangeOffResult.isErr())) {
NS_WARNING(
"HTMLEditor::SplitAncestorStyledInlineElementsAtRangeEdges() "
@ -3601,7 +3676,7 @@ Result<bool, nsresult> HTMLEditor::IsRemovableParentStyleWithNewSpanElement(
// If parent block has invertible style, we should remove the style with
// creating new `<span>` element even in HTML mode because Chrome does it.
if (!aStyle.IsCSSEditable(*element)) {
if (!aStyle.IsCSSSettable(*element)) {
return false;
}
nsAutoString emptyString;

View File

@ -36,10 +36,6 @@ var knownFailures = {
'fontsize-1' : true,
'fontsize-2' : true,
},
'c': {
'fontsize-1' : true,
'fontsize-2' : true,
},
};
function isKnownFailure(type, test, param) {

View File

@ -38,18 +38,23 @@ const knownFailures = {
"AC-Proposed-FS:large_TEXT-1_SI-dM": true,
"AC-Proposed-FS:large_TEXT-1_SI-body": true,
"AC-Proposed-FS:large_TEXT-1_SI-div": true,
"C-Proposed-FN:c_FONTf:a-1_SI-dM": true,
"C-Proposed-FN:c_FONTf:a-1_SI-body": true,
"C-Proposed-FN:c_FONTf:a-1_SI-div": true,
"C-Proposed-FN:c_FONTf:a-2_SL-dM": true,
"C-Proposed-FN:c_FONTf:a-2_SL-body": true,
"C-Proposed-FN:c_FONTf:a-2_SL-div": true,
// Those tests expect that <font> elements can be nested, but they don't
// match with the other browsers' behavior.
"C-Proposed-FC:g_FONTc:b.sz:6-1_SI-dM": true,
"C-Proposed-FC:g_FONTc:b.sz:6-1_SI-body": true,
"C-Proposed-FC:g_FONTc:b.sz:6-1_SI-div": true,
"C-Proposed-FS:1_SPAN.ass.s:fs:large-1_SW-dM": true,
"C-Proposed-FS:1_SPAN.ass.s:fs:large-1_SW-body": true,
"C-Proposed-FS:1_SPAN.ass.s:fs:large-1_SW-div": true,
"C-Proposed-FS:5_FONTsz:1.s:fs:xs-1_SW-dM": true,
"C-Proposed-FS:5_FONTsz:1.s:fs:xs-1_SW-body": true,
"C-Proposed-FS:5_FONTsz:1.s:fs:xs-1_SW-div": true,
// Those tests expect that <font> elements can be nested, but they don't
// match with the other browsers' behavior.
"C-Proposed-FS:2_FONTc:b.sz:6-1_SI-dM": true,
"C-Proposed-FS:2_FONTc:b.sz:6-1_SI-body": true,
"C-Proposed-FS:2_FONTc:b.sz:6-1_SI-div": true,
"C-Proposed-FS:larger_FONTsz:4-dM": true,
"C-Proposed-FS:larger_FONTsz:4-body": true,
"C-Proposed-FS:larger_FONTsz:4-div": true,
@ -80,12 +85,6 @@ const knownFailures = {
"CC-Proposed-BC:gray_SPANs:bc:b-2_SR-dM": true,
"CC-Proposed-BC:gray_SPANs:bc:b-2_SR-body": true,
"CC-Proposed-BC:gray_SPANs:bc:b-2_SR-div": true,
"CC-Proposed-FN:c_FONTf:a-1_SI-dM": true,
"CC-Proposed-FN:c_FONTf:a-1_SI-body": true,
"CC-Proposed-FN:c_FONTf:a-1_SI-div": true,
"CC-Proposed-FN:c_FONTf:a-2_SL-dM": true,
"CC-Proposed-FN:c_FONTf:a-2_SL-body": true,
"CC-Proposed-FN:c_FONTf:a-2_SL-div": true,
"CC-Proposed-FS:1_SPANs:fs:l-1_SW-dM": true,
"CC-Proposed-FS:1_SPANs:fs:l-1_SW-body": true,
"CC-Proposed-FS:1_SPANs:fs:l-1_SW-div": true,
@ -677,24 +676,23 @@ const knownFailures = {
"C-Proposed-U_S-U-1_SO-dM": !SpecialPowers.getBoolPref("editor.inline_style.range.compatible_with_the_other_browsers", true),
"C-Proposed-U_S-U-1_SO-body": !SpecialPowers.getBoolPref("editor.inline_style.range.compatible_with_the_other_browsers", true),
"C-Proposed-U_S-U-1_SO-div": !SpecialPowers.getBoolPref("editor.inline_style.range.compatible_with_the_other_browsers", true),
"C-Proposed-FC:g_FONTc:b.sz:6-1_SI-dM": !SpecialPowers.getBoolPref("editor.inline_style.range.compatible_with_the_other_browsers", true),
"C-Proposed-FC:g_FONTc:b.sz:6-1_SI-body": !SpecialPowers.getBoolPref("editor.inline_style.range.compatible_with_the_other_browsers", true),
"C-Proposed-FC:g_FONTc:b.sz:6-1_SI-div": !SpecialPowers.getBoolPref("editor.inline_style.range.compatible_with_the_other_browsers", true),
"C-Proposed-FN:c_FONTf:a-1_SI-dM": !SpecialPowers.getBoolPref("editor.inline_style.range.compatible_with_the_other_browsers", true),
"C-Proposed-FN:c_FONTf:a-1_SI-body": !SpecialPowers.getBoolPref("editor.inline_style.range.compatible_with_the_other_browsers", true),
"C-Proposed-FN:c_FONTf:a-1_SI-div": !SpecialPowers.getBoolPref("editor.inline_style.range.compatible_with_the_other_browsers", true),
"C-Proposed-FN:c_FONTf:a-2_SL-dM": true,
"C-Proposed-FN:c_FONTf:a-2_SL-body": true,
"C-Proposed-FN:c_FONTf:a-2_SL-div": true,
// Those tests expect that <font> elements can be nested, but they don't
// match with the other browsers' behavior.
"C-Proposed-FC:g_FONTc:b.sz:6-1_SI-dM": true,
"C-Proposed-FC:g_FONTc:b.sz:6-1_SI-body": true,
"C-Proposed-FC:g_FONTc:b.sz:6-1_SI-div": true,
"C-Proposed-FS:1_SPAN.ass.s:fs:large-1_SW-dM": true,
"C-Proposed-FS:1_SPAN.ass.s:fs:large-1_SW-body": true,
"C-Proposed-FS:1_SPAN.ass.s:fs:large-1_SW-div": true,
"C-Proposed-FS:5_FONTsz:1.s:fs:xs-1_SW-dM": true,
"C-Proposed-FS:5_FONTsz:1.s:fs:xs-1_SW-body": true,
"C-Proposed-FS:5_FONTsz:1.s:fs:xs-1_SW-div": true,
"C-Proposed-FS:2_FONTc:b.sz:6-1_SI-dM": !SpecialPowers.getBoolPref("editor.inline_style.range.compatible_with_the_other_browsers", true),
"C-Proposed-FS:2_FONTc:b.sz:6-1_SI-body": !SpecialPowers.getBoolPref("editor.inline_style.range.compatible_with_the_other_browsers", true),
"C-Proposed-FS:2_FONTc:b.sz:6-1_SI-div": !SpecialPowers.getBoolPref("editor.inline_style.range.compatible_with_the_other_browsers", true),
// Those tests expect that <font> elements can be nested, but they don't
// match with the other browsers' behavior.
"C-Proposed-FS:2_FONTc:b.sz:6-1_SI-dM": true,
"C-Proposed-FS:2_FONTc:b.sz:6-1_SI-body": true,
"C-Proposed-FS:2_FONTc:b.sz:6-1_SI-div": true,
"C-Proposed-FS:larger_FONTsz:4-dM": true,
"C-Proposed-FS:larger_FONTsz:4-body": true,
"C-Proposed-FS:larger_FONTsz:4-div": true,
@ -731,12 +729,6 @@ const knownFailures = {
"CC-Proposed-BC:gray_SPANs:bc:b-2_SR-dM": true,
"CC-Proposed-BC:gray_SPANs:bc:b-2_SR-body": true,
"CC-Proposed-BC:gray_SPANs:bc:b-2_SR-div": true,
"CC-Proposed-FN:c_FONTf:a-1_SI-dM": true,
"CC-Proposed-FN:c_FONTf:a-1_SI-body": true,
"CC-Proposed-FN:c_FONTf:a-1_SI-div": true,
"CC-Proposed-FN:c_FONTf:a-2_SL-dM": true,
"CC-Proposed-FN:c_FONTf:a-2_SL-body": true,
"CC-Proposed-FN:c_FONTf:a-2_SL-div": true,
"CC-Proposed-FS:1_SPANs:fs:l-1_SW-dM": true,
"CC-Proposed-FS:1_SPANs:fs:l-1_SW-body": true,
"CC-Proposed-FS:1_SPANs:fs:l-1_SW-div": true,

View File

@ -386,18 +386,12 @@
[[["stylewithcss","true"\],["fontsize","4"\]\] "<font size=4>foo<font size=1>b[a\]r</font>baz</font>" compare innerHTML]
expected: FAIL
[[["stylewithcss","false"\],["fontsize","4"\]\] "<font size=4>foo<font size=1>b[a\]r</font>baz</font>" compare innerHTML]
expected: FAIL
[[["stylewithcss","true"\],["fontsize","4"\]\] "foo<span style=\\"font-size: xx-small\\">[bar\]</span>baz" compare innerHTML]
expected: FAIL
[[["stylewithcss","true"\],["fontsize","4"\]\] "foo<span style=\\"font-size: xx-small\\">[bar\]</span>baz" queryCommandValue("fontsize") before]
expected: FAIL
[[["stylewithcss","false"\],["fontsize","4"\]\] "foo<span style=\\"font-size: xx-small\\">[bar\]</span>baz" compare innerHTML]
expected: FAIL
[[["stylewithcss","false"\],["fontsize","4"\]\] "foo<span style=\\"font-size: xx-small\\">[bar\]</span>baz" queryCommandValue("fontsize") before]
expected: FAIL
@ -416,9 +410,6 @@
[[["stylewithcss","true"\],["fontsize","4"\]\] "foo<span style=\\"font-size: medium\\">[bar\]</span>baz" queryCommandValue("fontsize") before]
expected: FAIL
[[["stylewithcss","false"\],["fontsize","4"\]\] "foo<span style=\\"font-size: medium\\">[bar\]</span>baz" compare innerHTML]
expected: FAIL
[[["stylewithcss","false"\],["fontsize","4"\]\] "foo<span style=\\"font-size: medium\\">[bar\]</span>baz" queryCommandValue("fontsize") before]
expected: FAIL
@ -437,9 +428,6 @@
[[["stylewithcss","true"\],["fontsize","4"\]\] "foo<span style=\\"font-size: large\\">[bar\]</span>baz" queryCommandValue("fontsize") before]
expected: FAIL
[[["stylewithcss","false"\],["fontsize","4"\]\] "foo<span style=\\"font-size: large\\">[bar\]</span>baz" compare innerHTML]
expected: FAIL
[[["stylewithcss","false"\],["fontsize","4"\]\] "foo<span style=\\"font-size: large\\">[bar\]</span>baz" queryCommandValue("fontsize") before]
expected: FAIL
@ -467,9 +455,6 @@
[[["stylewithcss","true"\],["fontsize","4"\]\] "foo<span style=\\"font-size: 2em\\">[bar\]</span>baz" queryCommandValue("fontsize") before]
expected: FAIL
[[["stylewithcss","false"\],["fontsize","4"\]\] "foo<span style=\\"font-size: 2em\\">[bar\]</span>baz" compare innerHTML]
expected: FAIL
[[["stylewithcss","false"\],["fontsize","4"\]\] "foo<span style=\\"font-size: 2em\\">[bar\]</span>baz" queryCommandValue("fontsize") before]
expected: FAIL

View File

@ -188,9 +188,6 @@
[[["stylewithcss","false"\],["forecolor","#0000FF"\]\] "foo{<font color=blue>bar</font>}baz" compare innerHTML]
expected: FAIL
[[["stylewithcss","true"\],["forecolor","#0000FF"\]\] "<span style=\\"color: rgb(0, 0, 255)\\">foo<span style=\\"color: brown\\">b[ar\]</span>baz</span>" compare innerHTML]
expected: FAIL
[[["stylewithcss","false"\],["forecolor","#0000FF"\]\] "<span style=\\"color: rgb(0, 0, 255)\\">foo<span style=\\"color: brown\\">b[ar\]</span>baz</span>" compare innerHTML]
expected: FAIL
@ -263,6 +260,18 @@
[[["stylewithcss","false"\],["forecolor","#0000FF"\]\] "foo<font color=brown>ba[r</font>b\]az" compare innerHTML]
expected: FAIL
[[["stylewithcss","false"\],["forecolor","#0000FF"\]\] "<span style=\\"color: blue\\">foo<span style=\\"color: brown\\">[bar\]</span>baz</span>" compare innerHTML]
expected: FAIL
[[["stylewithcss","true"\],["forecolor","#0000FF"\]\] "<span style=\\"color: rgb(0, 0, 255)\\">foo<span id=purple>b[a\]r</span>baz</span>" compare innerHTML]
expected: FAIL
[[["stylewithcss","true"\],["forecolor","#0000FF"\]\] "<span style=\\"color: rgb(0, 0, 255)\\">foo<span id=purple>b[a\]r</span>baz</span>" queryCommandValue("forecolor") after]
expected: FAIL
[[["stylewithcss","false"\],["forecolor","#0000FF"\]\] "<span style=\\"color: rgb(0, 0, 255)\\">foo<span id=purple>b[a\]r</span>baz</span>" queryCommandValue("forecolor") after]
expected: FAIL
[forecolor.html?2001-last]
expected:

View File

@ -492,12 +492,12 @@ var browserTests = [
{"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}],
["foo<span style=\"font-family: monospace\">b[a]r</span>baz",
[["stylewithcss","true"],["fontname","sans-serif"]],
"foo<span style=\"font-family:monospace\">b<span style=\"font-family:sans-serif\">[a]</span>r</span>baz",
"foo<span style=\"font-family:monospace\">b</span><span style=\"font-family:sans-serif\">[a]</span><span style=\"font-family:monospace\">r</span>baz",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}],
["foo<span style=\"font-family: monospace\">b[a]r</span>baz",
[["stylewithcss","false"],["fontname","sans-serif"]],
"foo<span style=\"font-family:monospace\">b<font face=\"sans-serif\">[a]</font>r</span>baz",
"foo<span style=\"font-family:monospace\">b</span><font face=\"sans-serif\">[a]</font><span style=\"font-family:monospace\">r</span>baz",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}],
["foo<tt contenteditable=false>ba[r</tt>b]az",
@ -537,22 +537,22 @@ var browserTests = [
{"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}],
["fo[o<span style=font-family:monospace>b]ar</span>baz",
[["stylewithcss","true"],["fontname","sans-serif"]],
"fo<span style=\"font-family:sans-serif\">[o</span><span style=\"font-family:monospace\"><span style=\"font-family:sans-serif\">b]</span>ar</span>baz",
"fo<span style=\"font-family:sans-serif\">[ob]</span><span style=\"font-family:monospace\">ar</span>baz",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}],
["fo[o<span style=font-family:monospace>b]ar</span>baz",
[["stylewithcss","false"],["fontname","sans-serif"]],
"fo<font face=\"sans-serif\">[o</font><span style=\"font-family:monospace\"><font face=\"sans-serif\">b]</font>ar</span>baz",
"fo<font face=\"sans-serif\">[ob]</font><span style=\"font-family:monospace\">ar</span>baz",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}],
["foo<span style=font-family:monospace>ba[r</span>b]az",
[["stylewithcss","true"],["fontname","sans-serif"]],
"foo<span style=\"font-family:monospace\">ba<span style=\"font-family:sans-serif\">[r</span></span><span style=\"font-family:sans-serif\">b]</span>az",
"foo<span style=\"font-family:monospace\">ba</span><span style=\"font-family:sans-serif\">[rb]</span>az",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}],
["foo<span style=font-family:monospace>ba[r</span>b]az",
[["stylewithcss","false"],["fontname","sans-serif"]],
"foo<span style=\"font-family:monospace\">ba<font face=\"sans-serif\">[r</font></span><font face=\"sans-serif\">b]</font>az",
"foo<span style=\"font-family:monospace\">ba</span><font face=\"sans-serif\">[rb]</font>az",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}],
["fo[o<span style=font-family:monospace>bar</span>b]az",
@ -567,22 +567,22 @@ var browserTests = [
{"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}],
["foo[<span style=font-family:monospace>b]ar</span>baz",
[["stylewithcss","true"],["fontname","sans-serif"]],
"foo[<span style=\"font-family:monospace\"><span style=\"font-family:sans-serif\">b]</span>ar</span>baz",
"foo<span style=\"font-family:sans-serif\">[b]</span><span style=\"font-family:monospace\">ar</span>baz",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}],
["foo[<span style=font-family:monospace>b]ar</span>baz",
[["stylewithcss","false"],["fontname","sans-serif"]],
"foo[<span style=\"font-family:monospace\"><font face=\"sans-serif\">b]</font>ar</span>baz",
"foo<font face=\"sans-serif\">[b]</font><span style=\"font-family:monospace\">ar</span>baz",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}],
["foo<span style=font-family:monospace>ba[r</span>]baz",
[["stylewithcss","true"],["fontname","sans-serif"]],
"foo<span style=\"font-family:monospace\">ba<span style=\"font-family:sans-serif\">[r</span></span>]baz",
"foo<span style=\"font-family:monospace\">ba</span><span style=\"font-family:sans-serif\">[r]</span>baz",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}],
["foo<span style=font-family:monospace>ba[r</span>]baz",
[["stylewithcss","false"],["fontname","sans-serif"]],
"foo<span style=\"font-family:monospace\">ba<font face=\"sans-serif\">[r</font></span>]baz",
"foo<span style=\"font-family:monospace\">ba</span><font face=\"sans-serif\">[r]</font>baz",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}],
["foo[<span style=font-family:monospace>bar</span>]baz",
@ -697,12 +697,12 @@ var browserTests = [
{"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}],
["<span style=font-family:monospace>fo[o</span><kbd>b]ar</kbd>",
[["stylewithcss","true"],["fontname","sans-serif"]],
"<span style=\"font-family:monospace\">fo<span style=\"font-family:sans-serif\">[o</span></span><kbd><span style=\"font-family:sans-serif\">b]</span>ar</kbd>",
"<span style=\"font-family:monospace\">fo</span><span style=\"font-family:sans-serif\">[o</span><kbd><span style=\"font-family:sans-serif\">b]</span>ar</kbd>",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}],
["<span style=font-family:monospace>fo[o</span><kbd>b]ar</kbd>",
[["stylewithcss","false"],["fontname","sans-serif"]],
"<span style=\"font-family:monospace\">fo<font face=\"sans-serif\">[o</font></span><kbd><font face=\"sans-serif\">b]</font>ar</kbd>",
"<span style=\"font-family:monospace\">fo</span><font face=\"sans-serif\">[o</font><kbd><font face=\"sans-serif\">b]</font>ar</kbd>",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}],

View File

@ -372,12 +372,12 @@ var browserTests = [
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"1",false,false,"4"]}],
["<font size=1>foo[bar]baz</font>",
[["stylewithcss","true"],["fontsize","4"]],
"<font size=\"1\">foo<span style=\"font-size:large\">[bar]</span>baz</font>",
"<font size=\"1\">foo</font><span style=\"font-size:large\">[bar]</span><font size=\"1\">baz</font>",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"1",false,false,"4"]}],
["<font size=1>foo[bar]baz</font>",
[["stylewithcss","false"],["fontsize","4"]],
"<font size=\"1\">foo<font size=\"4\">[bar]</font>baz</font>",
"<font size=\"1\">foo</font><font size=\"4\">[bar]</font><font size=\"1\">baz</font>",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"1",false,false,"4"]}],
["foo<font size=3>[bar]</font>baz",
@ -392,12 +392,12 @@ var browserTests = [
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}],
["<font size=3>foo[bar]baz</font>",
[["stylewithcss","true"],["fontsize","4"]],
"<font size=\"3\">foo<span style=\"font-size:large\">[bar]</span>baz</font>",
"<font size=\"3\">foo</font><span style=\"font-size:large\">[bar]</span><font size=\"3\">baz</font>",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}],
["<font size=3>foo[bar]baz</font>",
[["stylewithcss","false"],["fontsize","4"]],
"<font size=\"3\">foo<font size=\"4\">[bar]</font>baz</font>",
"<font size=\"3\">foo</font><font size=\"4\">[bar]</font><font size=\"3\">baz</font>",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}],
["foo<font size=4>[bar]</font>baz",
@ -452,12 +452,12 @@ var browserTests = [
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"1",false,false,"4"]}],
["<span style=\"font-size: xx-small\">foo[bar]baz</span>",
[["stylewithcss","true"],["fontsize","4"]],
"<span style=\"font-size:xx-small\">foo<span style=\"font-size:large\">[bar]</span>baz</span>",
"<span style=\"font-size:xx-small\">foo</span><span style=\"font-size:large\">[bar]</span><span style=\"font-size:xx-small\">baz</span>",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"1",false,false,"4"]}],
["<span style=\"font-size: xx-small\">foo[bar]baz</span>",
[["stylewithcss","false"],["fontsize","4"]],
"<span style=\"font-size:xx-small\">foo<font size=\"4\">[bar]</font>baz</span>",
"<span style=\"font-size:xx-small\">foo</span><font size=\"4\">[bar]</font><span style=\"font-size:xx-small\">baz</span>",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"1",false,false,"4"]}],
["foo<span style=\"font-size: medium\">[bar]</span>baz",
@ -472,12 +472,12 @@ var browserTests = [
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}],
["<span style=\"font-size: medium\">foo[bar]baz</span>",
[["stylewithcss","true"],["fontsize","4"]],
"<span style=\"font-size:medium\">foo<span style=\"font-size:large\">[bar]</span>baz</span>",
"<span style=\"font-size:medium\">foo</span><span style=\"font-size:large\">[bar]</span><span style=\"font-size:medium\">baz</span>",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}],
["<span style=\"font-size: medium\">foo[bar]baz</span>",
[["stylewithcss","false"],["fontsize","4"]],
"<span style=\"font-size:medium\">foo<font size=\"4\">[bar]</font>baz</span>",
"<span style=\"font-size:medium\">foo</span><font size=\"4\">[bar]</font><span style=\"font-size:medium\">baz</span>",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}],
["foo<span style=\"font-size: large\">[bar]</span>baz",
@ -517,12 +517,12 @@ var browserTests = [
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"6",false,false,"4"]}],
["<span style=\"font-size: 2em\">foo[bar]baz</span>",
[["stylewithcss","true"],["fontsize","4"]],
"<span style=\"font-size:2em\">foo<span style=\"font-size:large\">[bar]</span>baz</span>",
"<span style=\"font-size:2em\">foo</span><span style=\"font-size:large\">[bar]</span><span style=\"font-size:2em\">baz</span>",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"6",false,false,"4"]}],
["<span style=\"font-size: 2em\">foo[bar]baz</span>",
[["stylewithcss","false"],["fontsize","4"]],
"<span style=\"font-size:2em\">foo<font size=\"4\">[bar]</font>baz</span>",
"<span style=\"font-size:2em\">foo</span><font size=\"4\">[bar]</font><span style=\"font-size:2em\">baz</span>",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"6",false,false,"4"]}],
["<p style=\"font-size: xx-small\">foo[bar]baz</p>",
@ -647,22 +647,22 @@ var browserTests = [
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"2",false,false,"3"]}],
["fo[o<font size=2>b]ar</font>baz",
[["stylewithcss","true"],["fontsize","4"]],
"fo<span style=\"font-size:large\">[o</span><font size=\"2\"><span style=\"font-size:large\">b]</span>ar</font>baz",
"fo<span style=\"font-size:large\">[ob]</span><font size=\"2\">ar</font>baz",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[true,false,"3",false,false,"4"]}],
["fo[o<font size=2>b]ar</font>baz",
[["stylewithcss","false"],["fontsize","4"]],
"fo<font size=\"4\">[o</font><font size=\"2\"><font size=\"4\">b]</font>ar</font>baz",
"fo<font size=\"4\">[ob]</font><font size=\"2\">ar</font>baz",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[true,false,"3",false,false,"4"]}],
["foo<font size=2>ba[r</font>b]az",
[["stylewithcss","true"],["fontsize","4"]],
"foo<font size=\"2\">ba<span style=\"font-size:large\">[r</span></font><span style=\"font-size:large\">b]</span>az",
"foo<font size=\"2\">ba</font><span style=\"font-size:large\">[rb]</span>az",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[true,false,"2",false,false,"4"]}],
["foo<font size=2>ba[r</font>b]az",
[["stylewithcss","false"],["fontsize","4"]],
"foo<font size=\"2\">ba<font size=\"4\">[r</font></font><font size=\"4\">b]</font>az",
"foo<font size=\"2\">ba</font><font size=\"4\">[rb]</font>az",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[true,false,"2",false,false,"4"]}],
["fo[o<font size=2>bar</font>b]az",
@ -677,22 +677,22 @@ var browserTests = [
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[true,false,"3",false,false,"4"]}],
["foo[<font size=2>b]ar</font>baz",
[["stylewithcss","true"],["fontsize","4"]],
"foo[<font size=\"2\"><span style=\"font-size:large\">b]</span>ar</font>baz",
"foo<span style=\"font-size:large\">b</span><font size=\"2\">ar</font>baz",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"2",false,false,"4"]}],
["foo[<font size=2>b]ar</font>baz",
[["stylewithcss","false"],["fontsize","4"]],
"foo[<font size=\"2\"><font size=\"4\">b]</font>ar</font>baz",
"foo<font size=\"4\">[b]</font><font size=\"2\">ar</font>baz",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"2",false,false,"4"]}],
["foo<font size=2>ba[r</font>]baz",
[["stylewithcss","true"],["fontsize","4"]],
"foo<font size=\"2\">ba<span style=\"font-size:large\">[r</span></font>]baz",
"foo<font size=\"2\">ba</font><span style=\"font-size:large\">r</span>baz",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"2",false,false,"4"]}],
["foo<font size=2>ba[r</font>]baz",
[["stylewithcss","false"],["fontsize","4"]],
"foo<font size=\"2\">ba<font size=\"4\">[r</font></font>]baz",
"foo<font size=\"2\">ba</font><font size=\"4\">[r]</font>baz",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"2",false,false,"4"]}],
["foo[<font size=2>bar</font>]baz",
@ -727,32 +727,32 @@ var browserTests = [
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"2",false,false,"4"]}],
["<font size=1>fo[o</font><span style=font-size:xx-small>b]ar</span>",
[["stylewithcss","true"],["fontsize","4"]],
"<font size=\"1\">fo<span style=\"font-size:large\">[o</span></font><span style=\"font-size:xx-small\"><span style=\"font-size:large\">b]</span>ar</span>",
"<font size=\"1\">fo</font><span style=\"font-size:large\">[ob]</span><span style=\"font-size:xx-small\">ar</span>",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[true,false,"1",false,false,"4"]}],
["<font size=1>fo[o</font><span style=font-size:xx-small>b]ar</span>",
[["stylewithcss","false"],["fontsize","4"]],
"<font size=\"1\">fo<font size=\"4\">[o</font></font><span style=\"font-size:xx-small\"><font size=\"4\">b]</font>ar</span>",
"<font size=\"1\">fo</font><font size=\"4\">[ob]</font><span style=\"font-size:xx-small\">ar</span>",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[true,false,"1",false,false,"4"]}],
["<font size=2>fo[o</font><span style=font-size:small>b]ar</span>",
[["stylewithcss","true"],["fontsize","4"]],
"<font size=\"2\">fo<span style=\"font-size:large\">[o</span></font><span style=\"font-size:small\"><span style=\"font-size:large\">b]</span>ar</span>",
"<font size=\"2\">fo</font><span style=\"font-size:large\">[ob]</span><span style=\"font-size:small\">ar</span>",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"2",false,false,"4"]}],
["<font size=2>fo[o</font><span style=font-size:small>b]ar</span>",
[["stylewithcss","false"],["fontsize","4"]],
"<font size=\"2\">fo<font size=\"4\">[o</font></font><span style=\"font-size:small\"><font size=\"4\">b]</font>ar</span>",
"<font size=\"2\">fo</font><font size=\"4\">[ob]</font><span style=\"font-size:small\">ar</span>",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"2",false,false,"4"]}],
["<font size=3>fo[o</font><span style=font-size:medium>b]ar</span>",
[["stylewithcss","true"],["fontsize","4"]],
"<font size=\"3\">fo<span style=\"font-size:large\">[o</span></font><span style=\"font-size:medium\"><span style=\"font-size:large\">b]</span>ar</span>",
"<font size=\"3\">fo</font><span style=\"font-size:large\">[ob]</span><span style=\"font-size:medium\">ar</span>",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}],
["<font size=3>fo[o</font><span style=font-size:medium>b]ar</span>",
[["stylewithcss","false"],["fontsize","4"]],
"<font size=\"3\">fo<font size=\"4\">[o</font></font><span style=\"font-size:medium\"><font size=\"4\">b]</font>ar</span>",
"<font size=\"3\">fo</font><font size=\"4\">ob</font><span style=\"font-size:medium\">ar</span>",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}],
["<font size=4>fo[o</font><span style=font-size:large>b]ar</span>",
@ -762,22 +762,22 @@ var browserTests = [
{"fontsize":[false,false,"4",false,false,"4"]}],
["<font size=5>fo[o</font><span style=font-size:x-large>b]ar</span>",
[["stylewithcss","true"],["fontsize","4"]],
"<font size=\"5\">fo<span style=\"font-size:large\">[o</span></font><span style=\"font-size:x-large\"><span style=\"font-size:large\">b]</span>ar</span>",
"<font size=\"5\">fo</font><span style=\"font-size:large\">[ob]</span><span style=\"font-size:x-large\">ar</span>",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"5",false,false,"4"]}],
["<font size=5>fo[o</font><span style=font-size:x-large>b]ar</span>",
[["stylewithcss","false"],["fontsize","4"]],
"<font size=\"5\">fo<font size=\"4\">[o</font></font><span style=\"font-size:x-large\"><font size=\"4\">b]</font>ar</span>",
"<font size=\"5\">fo</font><font size=\"4\">[ob]</font><span style=\"font-size:x-large\">ar</span>",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"5",false,false,"4"]}],
["<font size=6>fo[o</font><span style=font-size:xx-large>b]ar</span>",
[["stylewithcss","true"],["fontsize","4"]],
"<font size=\"6\">fo<span style=\"font-size:large\">[o</span></font><span style=\"font-size:xx-large\"><span style=\"font-size:large\">b]</span>ar</span>",
"<font size=\"6\">fo</font><span style=\"font-size:large\">ob</span><span style=\"font-size:xx-large\">ar</span>",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"6",false,false,"4"]}],
["<font size=6>fo[o</font><span style=font-size:xx-large>b]ar</span>",
[["stylewithcss","false"],["fontsize","4"]],
"<font size=\"6\">fo<font size=\"4\">[o</font></font><span style=\"font-size:xx-large\"><font size=\"4\">b]</font>ar</span>",
"<font size=\"6\">fo</font><font size=\"4\">ob</font><span style=\"font-size:xx-large\">ar</span>",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"6",false,false,"4"]}],
@ -825,4 +825,41 @@ var browserTests = [
"<font face=\"monospace\">ab<font size=\"7\">[c]</font></font>",
[true,true],
{}],
// font-size should be removed when applying fontsize without CSS.
// Blink and WebKit puts <font size="..."> into the <span> element in these
// test cases. However, this behavior may cause the background color is
// partially applied to the text because the height is computed without the
// <font>. Therefore, it may be better to put <font> outside any inline
// ancestors.
["<span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">[abc]</span>",
[["styleWithCSS","false"],["fontSize","5"]],
["<span style=\"background-color:rgb(0, 128, 128)\"><font size=\"5\">[abc]</font></span>",
"<font size=\"5\"><span style=\"background-color:rgb(0, 128, 128)\">[abc]</span></font>"],
[true,true],
{}],
["<span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">[a]bc</span>",
[["styleWithCSS","false"],["fontSize","5"]],
["<span style=\"background-color:rgb(0, 128, 128)\"><font size=\"5\">[a]</font></span><span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">bc</span>",
"<font size=\"5\"><span style=\"background-color:rgb(0, 128, 128)\">[a]</span></font><span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">bc</span>"],
[true,true],
{}],
["<span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">a[b]c</span>",
[["styleWithCSS","false"],["fontSize","5"]],
["<span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">a</span><span style=\"background-color:rgb(0, 128, 128)\"><font size=\"5\">[b]</font></span><span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">c</span>",
"<span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">a</span><font size=\"5\"><span style=\"background-color:rgb(0, 128, 128)\">[b]</span></font><span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">c</span>"],
[true,true],
{}],
["<span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">ab[c]</span>",
[["styleWithCSS","false"],["fontSize","5"]],
["<span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">ab</span><span style=\"background-color:rgb(0, 128, 128)\"><font size=\"5\">[c]</font></span>",
"<span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">ab</span><font size=\"5\"><span style=\"background-color:rgb(0, 128, 128)\">[c]</span></font>"],
[true,true],
{}],
["<p><span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">[abc</span></p><p><span style=\"font-size:64px; background-color:rgb(128, 128, 0)\">def]</span></p>",
[["styleWithCSS","false"],["fontSize","5"]],
["<p><span style=\"background-color:rgb(0, 128, 128)\"><font size=\"5\">[abc</font></span></p><p><span style=\"background-color:rgb(128, 128, 0)\"><font size=\"5\">def]</font></span></p>",
"<p><font size=\"5\"><span style=\"background-color:rgb(0, 128, 128)\">[abc</span></font></p><p><font size=\"5\"><span style=\"background-color:rgb(128, 128, 0)\">def]</span></font></p>"],
[true,true],
{}],
]

View File

@ -372,12 +372,12 @@ var browserTests = [
{"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}],
["<span style=\"color: blue\">foo<span style=\"color: brown\">[bar]</span>baz</span>",
[["stylewithcss","true"],["forecolor","#0000FF"]],
"<span style=\"color:rgb(0, 0, 255)\">foo[bar]baz</span>",
"<span style=\"color:rgb(0, 0, 255)\">foo</span><span style=\"color:rgb(0, 0, 255)\">bar</span><span style=\"color:rgb(0, 0, 255)\">baz</span>",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}],
["<span style=\"color: blue\">foo<span style=\"color: brown\">[bar]</span>baz</span>",
[["stylewithcss","false"],["forecolor","#0000FF"]],
"<span style=\"color:rgb(0, 0, 255)\">foo[bar]baz</span>",
"<span style=\"color:rgb(0, 0, 255)\">foo</span><font color=\"#0000ff\">[bar]</font><span style=\"color:rgb(0, 0, 255)\">baz</span>",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}],
["<span style=\"color: #00f\">foo<span style=\"color: brown\">[bar]</span>baz</span>",
@ -440,6 +440,8 @@ var browserTests = [
"foo<span id=\"purple\">ba<font color=\"#0000ff\">[r</font></span><font color=\"#0000ff\">ba]</font>z",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"forecolor":[true,false,"rgb(128, 0, 128)",false,false,"rgb(0, 0, 255)"]}],
// XXX Looks like that there is no good solution for this case because id=purple
// may affect the style, but it's unclear for builtin editors of the browsers.
["<span style=\"color: rgb(0, 0, 255)\">foo<span id=purple>b[a]r</span>baz</span>",
[["stylewithcss","true"],["forecolor","#0000FF"]],
"<span style=\"color:rgb(0, 0, 255)\">foo<span id=\"purple\">b<span style=\"color:rgb(0, 0, 255)\">[a]</span>r</span>baz</span>",
@ -637,22 +639,22 @@ var browserTests = [
{"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}],
["fo[o<font color=brown>b]ar</font>baz",
[["stylewithcss","true"],["forecolor","#0000FF"]],
"fo<span style=\"color:rgb(0, 0, 255)\">[o</span><font color=\"brown\"><span style=\"color:rgb(0, 0, 255)\">b]</span>ar</font>baz",
"fo<span style=\"color:rgb(0, 0, 255)\">[ob]</span><font color=\"brown\">ar</font>baz",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"forecolor":[true,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}],
["fo[o<font color=brown>b]ar</font>baz",
[["stylewithcss","false"],["forecolor","#0000FF"]],
"fo<font color=\"#0000ff\">[o</font><font color=\"brown\"><font color=\"#0000ff\">b]</font>ar</font>baz",
"fo<font color=\"#0000ff\">[ob]</font><font color=\"brown\">ar</font>baz",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"forecolor":[true,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}],
["foo<font color=brown>ba[r</font>b]az",
[["stylewithcss","true"],["forecolor","#0000FF"]],
"foo<font color=\"brown\">ba<span style=\"color:rgb(0, 0, 255)\">[r</span></font><span style=\"color:rgb(0, 0, 255)\">b]</span>az",
"foo<font color=\"brown\">ba</font><span style=\"color:rgb(0, 0, 255)\">[rb]</span>az",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"forecolor":[true,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}],
["foo<font color=brown>ba[r</font>b]az",
[["stylewithcss","false"],["forecolor","#0000FF"]],
"foo<font color=\"brown\">ba<font color=\"#0000ff\">[r</font></font><font color=\"#0000ff\">b]</font>az",
"foo<font color=\"brown\">ba</font><font color=\"#0000ff\">[rb]</font>az",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"forecolor":[true,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}],
["fo[o<font color=brown>bar</font>b]az",
@ -667,22 +669,22 @@ var browserTests = [
{"stylewithcss":[false,true,"",false,false,""],"forecolor":[true,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}],
["foo[<font color=brown>b]ar</font>baz",
[["stylewithcss","true"],["forecolor","#0000FF"]],
"foo[<font color=\"brown\"><span style=\"color:rgb(0, 0, 255)\">b]</span>ar</font>baz",
"foo<span style=\"color:rgb(0, 0, 255)\">[b]</span><font color=\"brown\">ar</font>baz",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}],
["foo[<font color=brown>b]ar</font>baz",
[["stylewithcss","false"],["forecolor","#0000FF"]],
"foo[<font color=\"brown\"><font color=\"#0000ff\">b]</font>ar</font>baz",
"foo<font color=\"#0000ff\">[b]</font><font color=\"brown\">ar</font>baz",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}],
["foo<font color=brown>ba[r</font>]baz",
[["stylewithcss","true"],["forecolor","#0000FF"]],
"foo<font color=\"brown\">ba<span style=\"color:rgb(0, 0, 255)\">[r</span></font>]baz",
"foo<font color=\"brown\">ba</font><span style=\"color:rgb(0, 0, 255)\">[r]</span>baz",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}],
["foo<font color=brown>ba[r</font>]baz",
[["stylewithcss","false"],["forecolor","#0000FF"]],
"foo<font color=\"brown\">ba<font color=\"#0000ff\">[r</font></font>]baz",
"foo<font color=\"brown\">ba</font><font color=\"#0000ff\">[r]</font>baz",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}],
["foo[<font color=brown>bar</font>]baz",
@ -717,22 +719,22 @@ var browserTests = [
{"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}],
["<font color=brown>fo[o</font><span style=color:brown>b]ar</span>",
[["stylewithcss","true"],["forecolor","#0000FF"]],
"<font color=\"brown\">fo<span style=\"color:rgb(0, 0, 255)\">[o</span></font><span style=\"color:rgb(165, 42, 42)\"><span style=\"color:rgb(0, 0, 255)\">b]</span>ar</span>",
"<font color=\"brown\">fo</font><span style=\"color:rgb(0, 0, 255)\">[ob]</span><span style=\"color:rgb(165, 42, 42)\">ar</span>",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}],
["<font color=brown>fo[o</font><span style=color:brown>b]ar</span>",
[["stylewithcss","false"],["forecolor","#0000FF"]],
"<font color=\"brown\">fo<font color=\"#0000ff\">[o</font></font><span style=\"color:rgb(165, 42, 42)\"><font color=\"#0000ff\">b]</font>ar</span>",
"<font color=\"brown\">fo</font><font color=\"#0000ff\">ob</font><span style=\"color:rgb(165, 42, 42)\">ar</span>",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}],
["<span style=color:brown>fo[o</span><span style=color:#0000ff>b]ar</span>",
[["stylewithcss","true"],["forecolor","#0000FF"]],
"<span style=\"color:rgb(165, 42, 42)\">fo<span style=\"color:rgb(0, 0, 255)\">[o</span></span><span style=\"color:rgb(0, 0, 255)\">b]ar</span>",
"<span style=\"color:rgb(165, 42, 42)\">fo</span><span style=\"color:rgb(0, 0, 255)\">[ob]ar</span>",
[true,true],
{"stylewithcss":[false,false,"",false,true,""],"forecolor":[true,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}],
["<span style=color:brown>fo[o</span><span style=color:#0000ff>b]ar</span>",
[["stylewithcss","false"],["forecolor","#0000FF"]],
"<span style=\"color:rgb(165, 42, 42)\">fo<font color=\"#0000ff\">[o</font></span><span style=\"color:rgb(0, 0, 255)\">b]ar</span>",
"<span style=\"color:rgb(165, 42, 42)\">fo</span><font color=\"#0000ff\">[ob]</font><span style=\"color:rgb(0, 0, 255)\">ar</span>",
[true,true],
{"stylewithcss":[false,true,"",false,false,""],"forecolor":[true,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}],