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}, ProcessSameValue, nullptr, nullptr, nullptr},
CSS_EQUIV_TABLE_NONE}; 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[] = { const CSSEditUtils::CSSEquivTable bgcolorEquivTable[] = {
{CSSEditUtils::eCSSEditableProperty_background_color, true, false, {CSSEditUtils::eCSSEditableProperty_background_color, true, false,
ProcessSameValue, nullptr, nullptr, nullptr}, ProcessSameValue, nullptr, nullptr, nullptr},
@ -812,13 +817,17 @@ void CSSEditUtils::GetCSSDeclarations(
if (!attributeOrStyle) { if (!attributeOrStyle) {
return nullptr; return nullptr;
} }
if (nsGkAtoms::font == htmlProperty && if (nsGkAtoms::font == htmlProperty) {
attributeOrStyle == nsGkAtoms::color) { if (attributeOrStyle == nsGkAtoms::color) {
return fontColorEquivTable; return fontColorEquivTable;
} }
if (nsGkAtoms::font == htmlProperty && if (attributeOrStyle == nsGkAtoms::face) {
attributeOrStyle == nsGkAtoms::face) { return fontFaceEquivTable;
return fontFaceEquivTable; }
if (attributeOrStyle == nsGkAtoms::size) {
return fontSizeEquivTable;
}
MOZ_ASSERT(attributeOrStyle == nsGkAtoms::bgcolor);
} }
if (attributeOrStyle == nsGkAtoms::bgcolor) { if (attributeOrStyle == nsGkAtoms::bgcolor) {
return bgcolorEquivTable; return bgcolorEquivTable;
@ -877,7 +886,7 @@ Result<size_t, nsresult> CSSEditUtils::SetCSSEquivalentToStyle(
WithTransaction aWithTransaction, HTMLEditor& aHTMLEditor, WithTransaction aWithTransaction, HTMLEditor& aHTMLEditor,
nsStyledElement& aStyledElement, const EditorElementStyle& aStyleToSet, nsStyledElement& aStyledElement, const EditorElementStyle& aStyleToSet,
const nsAString* aValue) { 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 // 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 // an equivalence for the requested HTML style in this implementation
@ -905,7 +914,7 @@ nsresult CSSEditUtils::RemoveCSSEquivalentToStyle(
WithTransaction aWithTransaction, HTMLEditor& aHTMLEditor, WithTransaction aWithTransaction, HTMLEditor& aHTMLEditor,
nsStyledElement& aStyledElement, const EditorElementStyle& aStyleToRemove, nsStyledElement& aStyledElement, const EditorElementStyle& aStyleToRemove,
const nsAString* aValue) { 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 // 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 // an equivalence for the requested HTML style in this implementation
@ -941,7 +950,8 @@ nsresult CSSEditUtils::GetCSSEquivalentTo(Element& aElement,
StyleType aStyleType) { StyleType aStyleType) {
MOZ_ASSERT_IF(aStyle.IsInlineStyle(), MOZ_ASSERT_IF(aStyle.IsInlineStyle(),
!aStyle.AsInlineStyle().IsStyleToClearAllInlineStyles()); !aStyle.AsInlineStyle().IsStyleToClearAllInlineStyles());
MOZ_DIAGNOSTIC_ASSERT(aStyle.IsCSSEditable(aElement)); MOZ_DIAGNOSTIC_ASSERT(aStyle.IsCSSSettable(aElement) ||
aStyle.IsCSSRemovable(aElement));
aOutValue.Truncate(); aOutValue.Truncate();
AutoTArray<CSSDeclaration, 4> cssDeclarations; AutoTArray<CSSDeclaration, 4> cssDeclarations;
@ -1130,6 +1140,27 @@ Result<bool, nsresult> CSSEditUtils::IsCSSEquivalentTo(
isSet = true; isSet = true;
} }
return isSet; 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) { } else if (aStyle.mAttribute == nsGkAtoms::align) {
isSet = true; isSet = true;
} else { } else {

View File

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

View File

@ -15,6 +15,7 @@
#include "EditorDOMPoint.h" #include "EditorDOMPoint.h"
#include "EditorForwards.h" #include "EditorForwards.h"
#include "EditorUtils.h" // for CaretPoint #include "EditorUtils.h" // for CaretPoint
#include "HTMLEditHelpers.h"
#include "JoinSplitNodeDirection.h" #include "JoinSplitNodeDirection.h"
#include "mozilla/AlreadyAddRefed.h" #include "mozilla/AlreadyAddRefed.h"
@ -923,8 +924,19 @@ class MOZ_STACK_CLASS EditorElementStyle {
aAttribute == nsGkAtoms::valign || aAttribute == nsGkAtoms::width; 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; } nsStaticAtom* Style() const { return mStyle; }
@ -1005,6 +1017,13 @@ struct MOZ_STACK_CLASS EditorInlineStyle : public EditorElementStyle {
return mHTMLProperty == nsGkAtoms::font && mAttribute != nsGkAtoms::bgcolor; 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 * Returns true if the style is conflict with vertical-align even though
* they are not mapped to vertical-align in the CSS mode. * 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, explicit EditorInlineStyle(const nsStaticAtom& aHTMLProperty,
nsAtom* aAttribute = nullptr) nsAtom* aAttribute = nullptr)
// Needs const_cast hack here because the struct users may want : EditorInlineStyle(aHTMLProperty, aAttribute, HasValue::No) {}
// non-const nsStaticAtom pointer due to bug 1794954
: mHTMLProperty(const_cast<nsStaticAtom*>(&aHTMLProperty)),
mAttribute(aAttribute) {}
EditorInlineStyle(const nsStaticAtom& aHTMLProperty, EditorInlineStyle(const nsStaticAtom& aHTMLProperty,
RefPtr<nsAtom>&& aAttribute) RefPtr<nsAtom>&& aAttribute)
// Needs const_cast hack here because the struct users may want : EditorInlineStyle(aHTMLProperty, aAttribute, HasValue::No) {}
// non-const nsStaticAtom pointer due to bug 1794954
: mHTMLProperty(const_cast<nsStaticAtom*>(&aHTMLProperty)),
mAttribute(std::move(aAttribute)) {}
/** /**
* Returns the instance which means remove all inline styles. * Returns the instance which means remove all inline styles.
@ -1068,6 +1081,33 @@ struct MOZ_STACK_CLASS EditorInlineStyle : public EditorElementStyle {
mAttribute == aOther.mAttribute; 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: private:
EditorInlineStyle() = default; EditorInlineStyle() = default;
@ -1096,25 +1136,25 @@ struct MOZ_STACK_CLASS EditorInlineStyleAndValue : public EditorInlineStyle {
EditorInlineStyleAndValue() = delete; EditorInlineStyleAndValue() = delete;
explicit EditorInlineStyleAndValue(nsStaticAtom& aHTMLProperty) explicit EditorInlineStyleAndValue(nsStaticAtom& aHTMLProperty)
: EditorInlineStyle(aHTMLProperty) {} : EditorInlineStyle(aHTMLProperty, nullptr, HasValue::No) {}
EditorInlineStyleAndValue(nsStaticAtom& aHTMLProperty, nsAtom& aAttribute, EditorInlineStyleAndValue(nsStaticAtom& aHTMLProperty, nsAtom& aAttribute,
const nsAString& aValue) const nsAString& aValue)
: EditorInlineStyle(aHTMLProperty, &aAttribute), : EditorInlineStyle(aHTMLProperty, &aAttribute, HasValue::Yes),
mAttributeValue(aValue) {} mAttributeValue(aValue) {}
EditorInlineStyleAndValue(nsStaticAtom& aHTMLProperty, EditorInlineStyleAndValue(nsStaticAtom& aHTMLProperty,
RefPtr<nsAtom>&& aAttribute, RefPtr<nsAtom>&& aAttribute,
const nsAString& aValue) const nsAString& aValue)
: EditorInlineStyle(aHTMLProperty, std::move(aAttribute)), : EditorInlineStyle(aHTMLProperty, std::move(aAttribute), HasValue::Yes),
mAttributeValue(aValue) { mAttributeValue(aValue) {
MOZ_ASSERT(mAttribute); MOZ_ASSERT(mAttribute);
} }
EditorInlineStyleAndValue(nsStaticAtom& aHTMLProperty, nsAtom& aAttribute, EditorInlineStyleAndValue(nsStaticAtom& aHTMLProperty, nsAtom& aAttribute,
nsString&& aValue) nsString&& aValue)
: EditorInlineStyle(aHTMLProperty, &aAttribute), : EditorInlineStyle(aHTMLProperty, &aAttribute, HasValue::Yes),
mAttributeValue(std::move(aValue)) {} mAttributeValue(std::move(aValue)) {}
EditorInlineStyleAndValue(nsStaticAtom& aHTMLProperty, EditorInlineStyleAndValue(nsStaticAtom& aHTMLProperty,
RefPtr<nsAtom>&& aAttribute, nsString&& aValue) RefPtr<nsAtom>&& aAttribute, nsString&& aValue)
: EditorInlineStyle(aHTMLProperty, std::move(aAttribute)), : EditorInlineStyle(aHTMLProperty, std::move(aAttribute), HasValue::Yes),
mAttributeValue(aValue) {} mAttributeValue(aValue) {}
[[nodiscard]] static EditorInlineStyleAndValue ToInvert( [[nodiscard]] static EditorInlineStyleAndValue ToInvert(
@ -1154,9 +1194,21 @@ struct MOZ_STACK_CLASS EditorInlineStyleAndValue : public EditorInlineStyle {
EditorInlineStyleAndValue(const EditorInlineStyle& aStyle, EditorInlineStyleAndValue(const EditorInlineStyle& aStyle,
const nsAString& aValue) 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 } // namespace mozilla
#endif // #ifndef HTMLEditHelpers_h #endif // #ifndef HTMLEditHelpers_h

View File

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

View File

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

View File

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

View File

@ -336,7 +336,7 @@ AlignStateAtSelection::AlignStateAtSelection(HTMLEditor& aHTMLEditor,
return; return;
} }
if (aHTMLEditor.IsCSSEnabled() && EditorElementStyle::Align().IsCSSEditable( if (aHTMLEditor.IsCSSEnabled() && EditorElementStyle::Align().IsCSSSettable(
*maybeNonEditableBlockElement)) { *maybeNonEditableBlockElement)) {
// We are in CSS mode and we know how to align this element with CSS // We are in CSS mode and we know how to align this element with CSS
nsAutoString value; nsAutoString value;
@ -379,7 +379,7 @@ AlignStateAtSelection::AlignStateAtSelection(HTMLEditor& aHTMLEditor,
return; return;
} }
if (EditorElementStyle::Align().IsCSSEditable(*containerElement)) { if (EditorElementStyle::Align().IsCSSSettable(*containerElement)) {
nsAutoString value; nsAutoString value;
DebugOnly<nsresult> rvIgnored = CSSEditUtils::GetSpecifiedProperty( DebugOnly<nsresult> rvIgnored = CSSEditUtils::GetSpecifiedProperty(
*containerElement, *nsGkAtoms::textAlign, value); *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 * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ErrorList.h"
#include "HTMLEditor.h" #include "HTMLEditor.h"
#include "HTMLEditorInlines.h" #include "HTMLEditorInlines.h"
#include "HTMLEditorNestedClasses.h" #include "HTMLEditorNestedClasses.h"
@ -32,7 +33,9 @@
#include "nsAString.h" #include "nsAString.h"
#include "nsAtom.h" #include "nsAtom.h"
#include "nsAttrName.h" #include "nsAttrName.h"
#include "nsAttrValue.h"
#include "nsCaseTreatment.h" #include "nsCaseTreatment.h"
#include "nsColor.h"
#include "nsComponentManagerUtils.h" #include "nsComponentManagerUtils.h"
#include "nsDebug.h" #include "nsDebug.h"
#include "nsError.h" #include "nsError.h"
@ -291,15 +294,48 @@ nsresult HTMLEditor::SetInlinePropertiesAroundRanges(
AutoInlineStyleSetter inlineStyleSetter(styleToSet); AutoInlineStyleSetter inlineStyleSetter(styleToSet);
for (OwningNonNull<nsRange>& domRange : aRanges.Ranges()) { for (OwningNonNull<nsRange>& domRange : aRanges.Ranges()) {
inlineStyleSetter.Reset(); inlineStyleSetter.Reset();
const EditorDOMRange range = [&]() { auto rangeOrError =
[&]() MOZ_CAN_RUN_SCRIPT -> Result<EditorDOMRange, nsresult> {
if (aRanges.HasSavedRanges()) { if (aRanges.HasSavedRanges()) {
return EditorDOMRange( return EditorDOMRange(
GetExtendedRangeWrappingEntirelySelectedElements( GetExtendedRangeWrappingEntirelySelectedElements(
EditorRawDOMRange(domRange))); 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 = Result<EditorRawDOMRange, nsresult> rangeOrError =
inlineStyleSetter.ExtendOrShrinkRangeToApplyTheStyle( inlineStyleSetter.ExtendOrShrinkRangeToApplyTheStyle(*this, range,
*this, EditorDOMRange(domRange), aEditingHost); aEditingHost);
if (MOZ_UNLIKELY(rangeOrError.isErr())) { if (MOZ_UNLIKELY(rangeOrError.isErr())) {
NS_WARNING( NS_WARNING(
"HTMLEditor::ExtendOrShrinkRangeToApplyTheStyle() failed, but " "HTMLEditor::ExtendOrShrinkRangeToApplyTheStyle() failed, but "
@ -308,6 +344,11 @@ nsresult HTMLEditor::SetInlinePropertiesAroundRanges(
} }
return EditorDOMRange(rangeOrError.unwrap()); return EditorDOMRange(rangeOrError.unwrap());
}(); }();
if (MOZ_UNLIKELY(rangeOrError.isErr())) {
return rangeOrError.unwrapErr();
}
const EditorDOMRange range = rangeOrError.unwrap();
if (!range.IsPositioned()) { if (!range.IsPositioned()) {
continue; continue;
} }
@ -572,7 +613,7 @@ HTMLEditor::AutoInlineStyleSetter::ElementIsGoodContainerForTheStyle(
HTMLEditor& aHTMLEditor, Element& aElement) const { HTMLEditor& aHTMLEditor, Element& aElement) const {
// If the editor is in the CSS mode and the style can be specified with CSS, // 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. // 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) { if (!aHTMLEditor.IsCSSEnabled() || !isCSSEditable) {
// First check for <b>, <i>, etc. // First check for <b>, <i>, etc.
if (aElement.IsHTMLElement(&HTMLPropertyRef()) && if (aElement.IsHTMLElement(&HTMLPropertyRef()) &&
@ -757,7 +798,7 @@ HTMLEditor::AutoInlineStyleSetter::SplitTextNodeAndApplyStyleToMiddleNode(
} }
// Don't need to do anything if property already set on node // 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; // The HTML styles defined by this have a CSS equivalence for node;
// let's check if it carries those CSS styles // let's check if it carries those CSS styles
nsAutoString value(mAttributeValue); 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 // Don't need to do anything if property already set on node
if (const RefPtr<Element> element = aContent.GetAsElementOrParentElement()) { if (const RefPtr<Element> element = aContent.GetAsElementOrParentElement()) {
if (IsCSSEditable(*element)) { if (IsCSSSettable(*element)) {
nsAutoString value(mAttributeValue); nsAutoString value(mAttributeValue);
// MOZ_KnownLive(element) because it's aContent. // MOZ_KnownLive(element) because it's aContent.
Result<bool, nsresult> isComputedCSSEquivalentToStyleOrError = Result<bool, nsresult> isComputedCSSEquivalentToStyleOrError =
@ -1079,7 +1120,7 @@ Result<CaretPoint, nsresult> HTMLEditor::AutoInlineStyleSetter::ApplyStyle(
auto ShouldUseCSS = [&]() { auto ShouldUseCSS = [&]() {
return (aHTMLEditor.IsCSSEnabled() && return (aHTMLEditor.IsCSSEnabled() &&
aContent.GetAsElementOrParentElement() && aContent.GetAsElementOrParentElement() &&
IsCSSEditable(*aContent.GetAsElementOrParentElement())) || IsCSSSettable(*aContent.GetAsElementOrParentElement())) ||
// bgcolor is always done using CSS // bgcolor is always done using CSS
mAttribute == nsGkAtoms::bgcolor || mAttribute == nsGkAtoms::bgcolor ||
// called for removing parent style, we should use CSS with // 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 // Add the CSS styles corresponding to the HTML style request
if (IsCSSEditable(*styledElement)) { if (IsCSSSettable(*styledElement)) {
Result<size_t, nsresult> result = CSSEditUtils::SetCSSEquivalentToStyle( Result<size_t, nsresult> result = CSSEditUtils::SetCSSEquivalentToStyle(
WithTransaction::Yes, aHTMLEditor, *styledElement, *this, WithTransaction::Yes, aHTMLEditor, *styledElement, *this,
&mAttributeValue); &mAttributeValue);
@ -1200,7 +1241,7 @@ HTMLEditor::AutoInlineStyleSetter::ApplyCSSTextDecoration(
"Was new value added in " "Was new value added in "
"IsStyleOfTextDecoration(IgnoreSElement::No))?"); "IsStyleOfTextDecoration(IgnoreSElement::No))?");
} }
if (styledElement && IsCSSEditable(*styledElement) && if (styledElement && IsCSSSettable(*styledElement) &&
ElementIsGoodContainerToSetStyle(*styledElement)) { ElementIsGoodContainerToSetStyle(*styledElement)) {
nsAutoString textDecorationValue; nsAutoString textDecorationValue;
nsresult rv = CSSEditUtils::GetSpecifiedProperty( nsresult rv = CSSEditUtils::GetSpecifiedProperty(
@ -1601,8 +1642,11 @@ EditorRawDOMPoint HTMLEditor::AutoInlineStyleSetter::
return startPoint; return startPoint;
} }
const bool useCSS = aHTMLEditor.IsCSSEnabled(); // FYI: Currently, we don't support setting `font-size` even in the CSS mode.
const bool isFontElementStyle = IsStyleOfFontElement(); // Therefore, if the style is <font size="...">, we always set a <font>.
const bool isSettingFontElement =
IsStyleOfFontSize() ||
(!aHTMLEditor.IsCSSEnabled() && IsStyleOfFontElement());
Element* mostDistantStartParentHavingStyle = nullptr; Element* mostDistantStartParentHavingStyle = nullptr;
for (Element* parent : for (Element* parent :
startPoint.GetContainer()->InclusiveAncestorsOfType<Element>()) { 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 // If we're setting <font> element and there is a <font> element which is
// entirely selected, we should use it. // entirely selected, we should use it.
else if (!useCSS && isFontElementStyle && else if (isSettingFontElement && parent->IsHTMLElement(nsGkAtoms::font)) {
parent->IsHTMLElement(nsGkAtoms::font)) {
mostDistantStartParentHavingStyle = parent; mostDistantStartParentHavingStyle = parent;
} }
if (parent->GetPreviousSibling()) { if (parent->GetPreviousSibling()) {
@ -1641,8 +1684,11 @@ EditorRawDOMPoint HTMLEditor::AutoInlineStyleSetter::
return endPoint; return endPoint;
} }
const bool useCSS = aHTMLEditor.IsCSSEnabled(); // FYI: Currently, we don't support setting `font-size` even in the CSS mode.
const bool isFontElementStyle = IsStyleOfFontElement(); // Therefore, if the style is <font size="...">, we always set a <font>.
const bool isSettingFontElement =
IsStyleOfFontSize() ||
(!aHTMLEditor.IsCSSEnabled() && IsStyleOfFontElement());
Element* mostDistantEndParentHavingStyle = nullptr; Element* mostDistantEndParentHavingStyle = nullptr;
for (Element* parent : for (Element* parent :
endPoint.GetContainer()->InclusiveAncestorsOfType<Element>()) { 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 // If we're setting <font> element and there is a <font> element which is
// entirely selected, we should use it. // entirely selected, we should use it.
else if (!useCSS && isFontElementStyle && else if (isSettingFontElement && parent->IsHTMLElement(nsGkAtoms::font)) {
parent->IsHTMLElement(nsGkAtoms::font)) {
mostDistantEndParentHavingStyle = parent; mostDistantEndParentHavingStyle = parent;
} }
if (parent->GetNextSibling()) { if (parent->GetNextSibling()) {
@ -1717,7 +1762,7 @@ EditorRawDOMRange HTMLEditor::AutoInlineStyleSetter::
// should have the new style into the range to avoid creating new <span> // should have the new style into the range to avoid creating new <span>
// element. // element.
if (!IsRepresentableWithHTML() || if (!IsRepresentableWithHTML() ||
(aHTMLEditor.IsCSSEnabled() && IsCSSEditable(*nsGkAtoms::span))) { (aHTMLEditor.IsCSSEnabled() && IsCSSSettable(*nsGkAtoms::span))) {
// First, if pointing in a text node, use parent point. // First, if pointing in a text node, use parent point.
if (aStartPoint.IsInContentNode() && aStartPoint.IsStartOfContainer() && if (aStartPoint.IsInContentNode() && aStartPoint.IsStartOfContainer() &&
aStartPoint.GetContainerParentAs<nsIContent>() && aStartPoint.GetContainerParentAs<nsIContent>() &&
@ -1902,7 +1947,8 @@ HTMLEditor::AutoInlineStyleSetter::ExtendOrShrinkRangeToApplyTheStyle(
Result<SplitRangeOffResult, nsresult> Result<SplitRangeOffResult, nsresult>
HTMLEditor::SplitAncestorStyledInlineElementsAtRangeEdges( HTMLEditor::SplitAncestorStyledInlineElementsAtRangeEdges(
const EditorDOMRange& aRange, const EditorInlineStyle& aStyle) { const EditorDOMRange& aRange, const EditorInlineStyle& aStyle,
SplitAtEdges aSplitAtEdges) {
MOZ_ASSERT(IsEditActionDataAvailable()); MOZ_ASSERT(IsEditActionDataAvailable());
if (NS_WARN_IF(!aRange.IsPositioned())) { if (NS_WARN_IF(!aRange.IsPositioned())) {
@ -1916,9 +1962,8 @@ HTMLEditor::SplitAncestorStyledInlineElementsAtRangeEdges(
[&]() MOZ_CAN_RUN_SCRIPT -> Result<SplitNodeResult, nsresult> { [&]() MOZ_CAN_RUN_SCRIPT -> Result<SplitNodeResult, nsresult> {
AutoTrackDOMRange tracker(RangeUpdaterRef(), &range); AutoTrackDOMRange tracker(RangeUpdaterRef(), &range);
Result<SplitNodeResult, nsresult> result = Result<SplitNodeResult, nsresult> result =
SplitAncestorStyledInlineElementsAt( SplitAncestorStyledInlineElementsAt(range.StartRef(), aStyle,
range.StartRef(), aStyle, aSplitAtEdges);
SplitAtEdges::eAllowToCreateEmptyContainer);
if (MOZ_UNLIKELY(result.isErr())) { if (MOZ_UNLIKELY(result.isErr())) {
NS_WARNING("HTMLEditor::SplitAncestorStyledInlineElementsAt() failed"); NS_WARNING("HTMLEditor::SplitAncestorStyledInlineElementsAt() failed");
return result; return result;
@ -1947,8 +1992,8 @@ HTMLEditor::SplitAncestorStyledInlineElementsAtRangeEdges(
[&]() MOZ_CAN_RUN_SCRIPT -> Result<SplitNodeResult, nsresult> { [&]() MOZ_CAN_RUN_SCRIPT -> Result<SplitNodeResult, nsresult> {
AutoTrackDOMRange tracker(RangeUpdaterRef(), &range); AutoTrackDOMRange tracker(RangeUpdaterRef(), &range);
Result<SplitNodeResult, nsresult> result = Result<SplitNodeResult, nsresult> result =
SplitAncestorStyledInlineElementsAt( SplitAncestorStyledInlineElementsAt(range.EndRef(), aStyle,
range.EndRef(), aStyle, SplitAtEdges::eAllowToCreateEmptyContainer); aSplitAtEdges);
if (MOZ_UNLIKELY(result.isErr())) { if (MOZ_UNLIKELY(result.isErr())) {
NS_WARNING("HTMLEditor::SplitAncestorStyledInlineElementsAt() failed"); NS_WARNING("HTMLEditor::SplitAncestorStyledInlineElementsAt() failed");
return result; return result;
@ -2001,15 +2046,15 @@ HTMLEditor::SplitAncestorStyledInlineElementsAt(
const bool handleCSS = const bool handleCSS =
aStyle.mHTMLProperty != nsGkAtoms::tt || IsCSSEnabled(); aStyle.mHTMLProperty != nsGkAtoms::tt || IsCSSEnabled();
AutoTArray<OwningNonNull<nsIContent>, 24> arrayOfParents; AutoTArray<OwningNonNull<Element>, 24> arrayOfParents;
for (nsIContent* content : for (Element* element :
aPointToSplit.GetContainer()->InclusiveAncestorsOfType<nsIContent>()) { aPointToSplit.GetContainer()->InclusiveAncestorsOfType<Element>()) {
if (HTMLEditUtils::IsBlockElement(*content) || !content->GetParent() || if (HTMLEditUtils::IsBlockElement(*element) || !element->GetParent() ||
!EditorUtils::IsEditableContent(*content->GetParent(), !EditorUtils::IsEditableContent(*element->GetParent(),
EditorType::HTML)) { EditorType::HTML)) {
break; break;
} }
arrayOfParents.AppendElement(*content); arrayOfParents.AppendElement(*element);
} }
// Split any matching style nodes above the point. // Split any matching style nodes above the point.
@ -2017,7 +2062,7 @@ HTMLEditor::SplitAncestorStyledInlineElementsAt(
SplitNodeResult::NotHandled(aPointToSplit, GetSplitNodeDirection()); SplitNodeResult::NotHandled(aPointToSplit, GetSplitNodeDirection());
MOZ_ASSERT(!result.Handled()); MOZ_ASSERT(!result.Handled());
EditorDOMPoint pointToPutCaret; EditorDOMPoint pointToPutCaret;
for (OwningNonNull<nsIContent>& content : arrayOfParents) { for (OwningNonNull<Element>& element : arrayOfParents) {
auto isSetByCSSOrError = [&]() -> Result<bool, nsresult> { auto isSetByCSSOrError = [&]() -> Result<bool, nsresult> {
if (!handleCSS) { if (!handleCSS) {
return false; return false;
@ -2025,11 +2070,10 @@ HTMLEditor::SplitAncestorStyledInlineElementsAt(
// The HTML style defined by aStyle has a CSS equivalence in this // The HTML style defined by aStyle has a CSS equivalence in this
// implementation for the node; let's check if it carries those CSS // implementation for the node; let's check if it carries those CSS
// styles // styles
if (MOZ_LIKELY(content->GetAsElementOrParentElement()) && if (aStyle.IsCSSRemovable(*element)) {
aStyle.IsCSSEditable(*content->GetAsElementOrParentElement())) {
nsAutoString firstValue; nsAutoString firstValue;
Result<bool, nsresult> isSpecifiedByCSSOrError = Result<bool, nsresult> isSpecifiedByCSSOrError =
CSSEditUtils::IsSpecifiedCSSEquivalentTo(*this, *content, aStyle, CSSEditUtils::IsSpecifiedCSSEquivalentTo(*this, *element, aStyle,
firstValue); firstValue);
if (MOZ_UNLIKELY(isSpecifiedByCSSOrError.isErr())) { if (MOZ_UNLIKELY(isSpecifiedByCSSOrError.isErr())) {
result.IgnoreCaretPointSuggestion(); result.IgnoreCaretPointSuggestion();
@ -2049,7 +2093,7 @@ HTMLEditor::SplitAncestorStyledInlineElementsAt(
if (aStyle.IsStyleConflictingWithVerticalAlign()) { if (aStyle.IsStyleConflictingWithVerticalAlign()) {
nsAutoString value; nsAutoString value;
nsresult rv = CSSEditUtils::GetSpecifiedProperty( nsresult rv = CSSEditUtils::GetSpecifiedProperty(
*content, *nsGkAtoms::vertical_align, value); *element, *nsGkAtoms::vertical_align, value);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
NS_WARNING("CSSEditUtils::GetSpecifiedProperty() failed"); NS_WARNING("CSSEditUtils::GetSpecifiedProperty() failed");
result.IgnoreCaretPointSuggestion(); result.IgnoreCaretPointSuggestion();
@ -2065,23 +2109,54 @@ HTMLEditor::SplitAncestorStyledInlineElementsAt(
return isSetByCSSOrError.propagateErr(); return isSetByCSSOrError.propagateErr();
} }
if (!isSetByCSSOrError.inspect()) { if (!isSetByCSSOrError.inspect()) {
if (!content->IsElement()) {
continue;
}
if (!aStyle.IsStyleToClearAllInlineStyles()) { if (!aStyle.IsStyleToClearAllInlineStyles()) {
// If the content is an inline element represents the style or // If we're removing a link style and the element is an <a href>, we
// the content is a link element and the style is `href`, we should // need to split it.
// split the content. if (aStyle.mHTMLProperty == nsGkAtoms::href &&
if (!content->IsHTMLElement(aStyle.mHTMLProperty) && HTMLEditUtils::IsLink(element)) {
!(aStyle.mHTMLProperty == nsGkAtoms::href && }
HTMLEditUtils::IsLink(content))) { // 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; 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. // If aProperty is nullptr, we need to split any style.
else if (!EditorUtils::IsEditableContent(content, EditorType::HTML) || else if (!EditorUtils::IsEditableContent(element, EditorType::HTML) ||
!HTMLEditUtils::IsRemovableInlineStyleElement( !HTMLEditUtils::IsRemovableInlineStyleElement(*element)) {
*content->AsElement())) {
continue; continue;
} }
} }
@ -2093,7 +2168,7 @@ HTMLEditor::SplitAncestorStyledInlineElementsAt(
// is a block, we do nothing but return as handled. // is a block, we do nothing but return as handled.
AutoTrackDOMPoint trackPointToPutCaret(RangeUpdaterRef(), &pointToPutCaret); AutoTrackDOMPoint trackPointToPutCaret(RangeUpdaterRef(), &pointToPutCaret);
Result<SplitNodeResult, nsresult> splitNodeResult = Result<SplitNodeResult, nsresult> splitNodeResult =
SplitNodeDeepWithTransaction(MOZ_KnownLive(content), SplitNodeDeepWithTransaction(MOZ_KnownLive(element),
result.AtSplitPoint<EditorDOMPoint>(), result.AtSplitPoint<EditorDOMPoint>(),
aSplitAtEdges); aSplitAtEdges);
if (MOZ_UNLIKELY(splitNodeResult.isErr())) { 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 // Next, remove CSS style first. Then, `style` attribute will be removed if
// the corresponding CSS property is last one. // the corresponding CSS property is last one.
const bool isCSSEditable = aStyleToRemove.IsCSSEditable(aElement);
auto isStyleSpecifiedOrError = [&]() -> Result<bool, nsresult> { auto isStyleSpecifiedOrError = [&]() -> Result<bool, nsresult> {
if (!isCSSEditable) { if (!aStyleToRemove.IsCSSRemovable(aElement)) {
return false; return false;
} }
MOZ_ASSERT(!aStyleToRemove.IsStyleToClearAllInlineStyles()); MOZ_ASSERT(!aStyleToRemove.IsStyleToClearAllInlineStyles());
@ -2794,7 +2868,7 @@ nsresult HTMLEditor::GetInlinePropertyBase(const EditorInlineStyle& aStyle,
nsIContent::FromNode(range->GetStartContainer()); nsIContent::FromNode(range->GetStartContainer());
if (MOZ_LIKELY(collapsedContent && if (MOZ_LIKELY(collapsedContent &&
collapsedContent->GetAsElementOrParentElement()) && collapsedContent->GetAsElementOrParentElement()) &&
aStyle.IsCSSEditable( aStyle.IsCSSSettable(
*collapsedContent->GetAsElementOrParentElement())) { *collapsedContent->GetAsElementOrParentElement())) {
if (aValue) { if (aValue) {
tOutString.Assign(*aValue); tOutString.Assign(*aValue);
@ -2860,7 +2934,7 @@ nsresult HTMLEditor::GetInlinePropertyBase(const EditorInlineStyle& aStyle,
bool isSet = false; bool isSet = false;
if (first) { if (first) {
if (element) { if (element) {
if (aStyle.IsCSSEditable(*element)) { if (aStyle.IsCSSSettable(*element)) {
// The HTML styles defined by aHTMLProperty/aAttribute have a CSS // The HTML styles defined by aHTMLProperty/aAttribute have a CSS
// equivalence in this implementation for node; let's check if it // equivalence in this implementation for node; let's check if it
// carries those CSS styles // carries those CSS styles
@ -2887,7 +2961,7 @@ nsresult HTMLEditor::GetInlinePropertyBase(const EditorInlineStyle& aStyle,
} }
} else { } else {
if (element) { if (element) {
if (aStyle.IsCSSEditable(*element)) { if (aStyle.IsCSSSettable(*element)) {
// The HTML styles defined by aHTMLProperty/aAttribute have a CSS // The HTML styles defined by aHTMLProperty/aAttribute have a CSS
// equivalence in this implementation for node; let's check if it // equivalence in this implementation for node; let's check if it
// carries those CSS styles // carries those CSS styles
@ -3233,7 +3307,8 @@ nsresult HTMLEditor::RemoveInlinePropertiesAsSubAction(
// Remove this style from ancestors of our range endpoints, splitting // Remove this style from ancestors of our range endpoints, splitting
// them as appropriate // them as appropriate
Result<SplitRangeOffResult, nsresult> splitRangeOffResult = Result<SplitRangeOffResult, nsresult> splitRangeOffResult =
SplitAncestorStyledInlineElementsAtRangeEdges(range, styleToRemove); SplitAncestorStyledInlineElementsAtRangeEdges(
range, styleToRemove, SplitAtEdges::eAllowToCreateEmptyContainer);
if (MOZ_UNLIKELY(splitRangeOffResult.isErr())) { if (MOZ_UNLIKELY(splitRangeOffResult.isErr())) {
NS_WARNING( NS_WARNING(
"HTMLEditor::SplitAncestorStyledInlineElementsAtRangeEdges() " "HTMLEditor::SplitAncestorStyledInlineElementsAtRangeEdges() "
@ -3601,7 +3676,7 @@ Result<bool, nsresult> HTMLEditor::IsRemovableParentStyleWithNewSpanElement(
// If parent block has invertible style, we should remove the style with // If parent block has invertible style, we should remove the style with
// creating new `<span>` element even in HTML mode because Chrome does it. // creating new `<span>` element even in HTML mode because Chrome does it.
if (!aStyle.IsCSSEditable(*element)) { if (!aStyle.IsCSSSettable(*element)) {
return false; return false;
} }
nsAutoString emptyString; nsAutoString emptyString;

View File

@ -36,10 +36,6 @@ var knownFailures = {
'fontsize-1' : true, 'fontsize-1' : true,
'fontsize-2' : true, 'fontsize-2' : true,
}, },
'c': {
'fontsize-1' : true,
'fontsize-2' : true,
},
}; };
function isKnownFailure(type, test, param) { 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-dM": true,
"AC-Proposed-FS:large_TEXT-1_SI-body": true, "AC-Proposed-FS:large_TEXT-1_SI-body": true,
"AC-Proposed-FS:large_TEXT-1_SI-div": 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, // Those tests expect that <font> elements can be nested, but they don't
"C-Proposed-FN:c_FONTf:a-1_SI-div": true, // match with the other browsers' behavior.
"C-Proposed-FN:c_FONTf:a-2_SL-dM": true, "C-Proposed-FC:g_FONTc:b.sz:6-1_SI-dM": true,
"C-Proposed-FN:c_FONTf:a-2_SL-body": true, "C-Proposed-FC:g_FONTc:b.sz:6-1_SI-body": true,
"C-Proposed-FN:c_FONTf:a-2_SL-div": 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-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-body": true,
"C-Proposed-FS:1_SPAN.ass.s:fs:large-1_SW-div": 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, // Those tests expect that <font> elements can be nested, but they don't
"C-Proposed-FS:5_FONTsz:1.s:fs:xs-1_SW-div": true, // 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-dM": true,
"C-Proposed-FS:larger_FONTsz:4-body": true, "C-Proposed-FS:larger_FONTsz:4-body": true,
"C-Proposed-FS:larger_FONTsz:4-div": 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-dM": true,
"CC-Proposed-BC:gray_SPANs:bc:b-2_SR-body": 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-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-dM": true,
"CC-Proposed-FS:1_SPANs:fs:l-1_SW-body": true, "CC-Proposed-FS:1_SPANs:fs:l-1_SW-body": true,
"CC-Proposed-FS:1_SPANs:fs:l-1_SW-div": 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-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-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-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), // Those tests expect that <font> elements can be nested, but they don't
"C-Proposed-FC:g_FONTc:b.sz:6-1_SI-div": !SpecialPowers.getBoolPref("editor.inline_style.range.compatible_with_the_other_browsers", true), // match with the other browsers' behavior.
"C-Proposed-FN:c_FONTf:a-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-dM": true,
"C-Proposed-FN:c_FONTf:a-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-body": true,
"C-Proposed-FN:c_FONTf:a-1_SI-div": !SpecialPowers.getBoolPref("editor.inline_style.range.compatible_with_the_other_browsers", true), "C-Proposed-FC:g_FONTc:b.sz:6-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,
"C-Proposed-FS:1_SPAN.ass.s:fs:large-1_SW-dM": 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-body": true,
"C-Proposed-FS:1_SPAN.ass.s:fs:large-1_SW-div": 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, // Those tests expect that <font> elements can be nested, but they don't
"C-Proposed-FS:5_FONTsz:1.s:fs:xs-1_SW-div": true, // match with the other browsers' behavior.
"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-dM": 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-body": true,
"C-Proposed-FS:2_FONTc:b.sz:6-1_SI-div": !SpecialPowers.getBoolPref("editor.inline_style.range.compatible_with_the_other_browsers", 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-dM": true,
"C-Proposed-FS:larger_FONTsz:4-body": true, "C-Proposed-FS:larger_FONTsz:4-body": true,
"C-Proposed-FS:larger_FONTsz:4-div": 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-dM": true,
"CC-Proposed-BC:gray_SPANs:bc:b-2_SR-body": 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-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-dM": true,
"CC-Proposed-FS:1_SPANs:fs:l-1_SW-body": true, "CC-Proposed-FS:1_SPANs:fs:l-1_SW-body": true,
"CC-Proposed-FS:1_SPANs:fs:l-1_SW-div": 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] [[["stylewithcss","true"\],["fontsize","4"\]\] "<font size=4>foo<font size=1>b[a\]r</font>baz</font>" compare innerHTML]
expected: FAIL 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] [[["stylewithcss","true"\],["fontsize","4"\]\] "foo<span style=\\"font-size: xx-small\\">[bar\]</span>baz" compare innerHTML]
expected: FAIL expected: FAIL
[[["stylewithcss","true"\],["fontsize","4"\]\] "foo<span style=\\"font-size: xx-small\\">[bar\]</span>baz" queryCommandValue("fontsize") before] [[["stylewithcss","true"\],["fontsize","4"\]\] "foo<span style=\\"font-size: xx-small\\">[bar\]</span>baz" queryCommandValue("fontsize") before]
expected: FAIL 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] [[["stylewithcss","false"\],["fontsize","4"\]\] "foo<span style=\\"font-size: xx-small\\">[bar\]</span>baz" queryCommandValue("fontsize") before]
expected: FAIL expected: FAIL
@ -416,9 +410,6 @@
[[["stylewithcss","true"\],["fontsize","4"\]\] "foo<span style=\\"font-size: medium\\">[bar\]</span>baz" queryCommandValue("fontsize") before] [[["stylewithcss","true"\],["fontsize","4"\]\] "foo<span style=\\"font-size: medium\\">[bar\]</span>baz" queryCommandValue("fontsize") before]
expected: FAIL 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] [[["stylewithcss","false"\],["fontsize","4"\]\] "foo<span style=\\"font-size: medium\\">[bar\]</span>baz" queryCommandValue("fontsize") before]
expected: FAIL expected: FAIL
@ -437,9 +428,6 @@
[[["stylewithcss","true"\],["fontsize","4"\]\] "foo<span style=\\"font-size: large\\">[bar\]</span>baz" queryCommandValue("fontsize") before] [[["stylewithcss","true"\],["fontsize","4"\]\] "foo<span style=\\"font-size: large\\">[bar\]</span>baz" queryCommandValue("fontsize") before]
expected: FAIL 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] [[["stylewithcss","false"\],["fontsize","4"\]\] "foo<span style=\\"font-size: large\\">[bar\]</span>baz" queryCommandValue("fontsize") before]
expected: FAIL expected: FAIL
@ -467,9 +455,6 @@
[[["stylewithcss","true"\],["fontsize","4"\]\] "foo<span style=\\"font-size: 2em\\">[bar\]</span>baz" queryCommandValue("fontsize") before] [[["stylewithcss","true"\],["fontsize","4"\]\] "foo<span style=\\"font-size: 2em\\">[bar\]</span>baz" queryCommandValue("fontsize") before]
expected: FAIL 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] [[["stylewithcss","false"\],["fontsize","4"\]\] "foo<span style=\\"font-size: 2em\\">[bar\]</span>baz" queryCommandValue("fontsize") before]
expected: FAIL expected: FAIL

View File

@ -188,9 +188,6 @@
[[["stylewithcss","false"\],["forecolor","#0000FF"\]\] "foo{<font color=blue>bar</font>}baz" compare innerHTML] [[["stylewithcss","false"\],["forecolor","#0000FF"\]\] "foo{<font color=blue>bar</font>}baz" compare innerHTML]
expected: FAIL 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] [[["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 expected: FAIL
@ -263,6 +260,18 @@
[[["stylewithcss","false"\],["forecolor","#0000FF"\]\] "foo<font color=brown>ba[r</font>b\]az" compare innerHTML] [[["stylewithcss","false"\],["forecolor","#0000FF"\]\] "foo<font color=brown>ba[r</font>b\]az" compare innerHTML]
expected: FAIL 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] [forecolor.html?2001-last]
expected: expected:

View File

@ -492,12 +492,12 @@ var browserTests = [
{"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}],
["foo<span style=\"font-family: monospace\">b[a]r</span>baz", ["foo<span style=\"font-family: monospace\">b[a]r</span>baz",
[["stylewithcss","true"],["fontname","sans-serif"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}],
["foo<span style=\"font-family: monospace\">b[a]r</span>baz", ["foo<span style=\"font-family: monospace\">b[a]r</span>baz",
[["stylewithcss","false"],["fontname","sans-serif"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}],
["foo<tt contenteditable=false>ba[r</tt>b]az", ["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"]}], {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}],
["fo[o<span style=font-family:monospace>b]ar</span>baz", ["fo[o<span style=font-family:monospace>b]ar</span>baz",
[["stylewithcss","true"],["fontname","sans-serif"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}],
["fo[o<span style=font-family:monospace>b]ar</span>baz", ["fo[o<span style=font-family:monospace>b]ar</span>baz",
[["stylewithcss","false"],["fontname","sans-serif"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}],
["foo<span style=font-family:monospace>ba[r</span>b]az", ["foo<span style=font-family:monospace>ba[r</span>b]az",
[["stylewithcss","true"],["fontname","sans-serif"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}], {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}],
["foo<span style=font-family:monospace>ba[r</span>b]az", ["foo<span style=font-family:monospace>ba[r</span>b]az",
[["stylewithcss","false"],["fontname","sans-serif"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}], {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}],
["fo[o<span style=font-family:monospace>bar</span>b]az", ["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"]}], {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}],
["foo[<span style=font-family:monospace>b]ar</span>baz", ["foo[<span style=font-family:monospace>b]ar</span>baz",
[["stylewithcss","true"],["fontname","sans-serif"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}],
["foo[<span style=font-family:monospace>b]ar</span>baz", ["foo[<span style=font-family:monospace>b]ar</span>baz",
[["stylewithcss","false"],["fontname","sans-serif"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}],
["foo<span style=font-family:monospace>ba[r</span>]baz", ["foo<span style=font-family:monospace>ba[r</span>]baz",
[["stylewithcss","true"],["fontname","sans-serif"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}],
["foo<span style=font-family:monospace>ba[r</span>]baz", ["foo<span style=font-family:monospace>ba[r</span>]baz",
[["stylewithcss","false"],["fontname","sans-serif"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}],
["foo[<span style=font-family:monospace>bar</span>]baz", ["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"]}], {"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>", ["<span style=font-family:monospace>fo[o</span><kbd>b]ar</kbd>",
[["stylewithcss","true"],["fontname","sans-serif"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], {"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>", ["<span style=font-family:monospace>fo[o</span><kbd>b]ar</kbd>",
[["stylewithcss","false"],["fontname","sans-serif"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], {"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"]}], {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"1",false,false,"4"]}],
["<font size=1>foo[bar]baz</font>", ["<font size=1>foo[bar]baz</font>",
[["stylewithcss","true"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"1",false,false,"4"]}], {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"1",false,false,"4"]}],
["<font size=1>foo[bar]baz</font>", ["<font size=1>foo[bar]baz</font>",
[["stylewithcss","false"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"1",false,false,"4"]}], {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"1",false,false,"4"]}],
["foo<font size=3>[bar]</font>baz", ["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"]}], {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}],
["<font size=3>foo[bar]baz</font>", ["<font size=3>foo[bar]baz</font>",
[["stylewithcss","true"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}], {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}],
["<font size=3>foo[bar]baz</font>", ["<font size=3>foo[bar]baz</font>",
[["stylewithcss","false"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}], {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}],
["foo<font size=4>[bar]</font>baz", ["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"]}], {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"1",false,false,"4"]}],
["<span style=\"font-size: xx-small\">foo[bar]baz</span>", ["<span style=\"font-size: xx-small\">foo[bar]baz</span>",
[["stylewithcss","true"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"1",false,false,"4"]}], {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"1",false,false,"4"]}],
["<span style=\"font-size: xx-small\">foo[bar]baz</span>", ["<span style=\"font-size: xx-small\">foo[bar]baz</span>",
[["stylewithcss","false"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"1",false,false,"4"]}], {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"1",false,false,"4"]}],
["foo<span style=\"font-size: medium\">[bar]</span>baz", ["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"]}], {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}],
["<span style=\"font-size: medium\">foo[bar]baz</span>", ["<span style=\"font-size: medium\">foo[bar]baz</span>",
[["stylewithcss","true"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}], {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}],
["<span style=\"font-size: medium\">foo[bar]baz</span>", ["<span style=\"font-size: medium\">foo[bar]baz</span>",
[["stylewithcss","false"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}], {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}],
["foo<span style=\"font-size: large\">[bar]</span>baz", ["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"]}], {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"6",false,false,"4"]}],
["<span style=\"font-size: 2em\">foo[bar]baz</span>", ["<span style=\"font-size: 2em\">foo[bar]baz</span>",
[["stylewithcss","true"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"6",false,false,"4"]}], {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"6",false,false,"4"]}],
["<span style=\"font-size: 2em\">foo[bar]baz</span>", ["<span style=\"font-size: 2em\">foo[bar]baz</span>",
[["stylewithcss","false"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"6",false,false,"4"]}], {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"6",false,false,"4"]}],
["<p style=\"font-size: xx-small\">foo[bar]baz</p>", ["<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"]}], {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"2",false,false,"3"]}],
["fo[o<font size=2>b]ar</font>baz", ["fo[o<font size=2>b]ar</font>baz",
[["stylewithcss","true"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[true,false,"3",false,false,"4"]}], {"stylewithcss":[false,false,"",false,true,""],"fontsize":[true,false,"3",false,false,"4"]}],
["fo[o<font size=2>b]ar</font>baz", ["fo[o<font size=2>b]ar</font>baz",
[["stylewithcss","false"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[true,false,"3",false,false,"4"]}], {"stylewithcss":[false,true,"",false,false,""],"fontsize":[true,false,"3",false,false,"4"]}],
["foo<font size=2>ba[r</font>b]az", ["foo<font size=2>ba[r</font>b]az",
[["stylewithcss","true"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[true,false,"2",false,false,"4"]}], {"stylewithcss":[false,false,"",false,true,""],"fontsize":[true,false,"2",false,false,"4"]}],
["foo<font size=2>ba[r</font>b]az", ["foo<font size=2>ba[r</font>b]az",
[["stylewithcss","false"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[true,false,"2",false,false,"4"]}], {"stylewithcss":[false,true,"",false,false,""],"fontsize":[true,false,"2",false,false,"4"]}],
["fo[o<font size=2>bar</font>b]az", ["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"]}], {"stylewithcss":[false,true,"",false,false,""],"fontsize":[true,false,"3",false,false,"4"]}],
["foo[<font size=2>b]ar</font>baz", ["foo[<font size=2>b]ar</font>baz",
[["stylewithcss","true"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"2",false,false,"4"]}], {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"2",false,false,"4"]}],
["foo[<font size=2>b]ar</font>baz", ["foo[<font size=2>b]ar</font>baz",
[["stylewithcss","false"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"2",false,false,"4"]}], {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"2",false,false,"4"]}],
["foo<font size=2>ba[r</font>]baz", ["foo<font size=2>ba[r</font>]baz",
[["stylewithcss","true"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"2",false,false,"4"]}], {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"2",false,false,"4"]}],
["foo<font size=2>ba[r</font>]baz", ["foo<font size=2>ba[r</font>]baz",
[["stylewithcss","false"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"2",false,false,"4"]}], {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"2",false,false,"4"]}],
["foo[<font size=2>bar</font>]baz", ["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"]}], {"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>", ["<font size=1>fo[o</font><span style=font-size:xx-small>b]ar</span>",
[["stylewithcss","true"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[true,false,"1",false,false,"4"]}], {"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>", ["<font size=1>fo[o</font><span style=font-size:xx-small>b]ar</span>",
[["stylewithcss","false"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[true,false,"1",false,false,"4"]}], {"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>", ["<font size=2>fo[o</font><span style=font-size:small>b]ar</span>",
[["stylewithcss","true"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"2",false,false,"4"]}], {"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>", ["<font size=2>fo[o</font><span style=font-size:small>b]ar</span>",
[["stylewithcss","false"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"2",false,false,"4"]}], {"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>", ["<font size=3>fo[o</font><span style=font-size:medium>b]ar</span>",
[["stylewithcss","true"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}], {"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>", ["<font size=3>fo[o</font><span style=font-size:medium>b]ar</span>",
[["stylewithcss","false"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}], {"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>", ["<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"]}], {"fontsize":[false,false,"4",false,false,"4"]}],
["<font size=5>fo[o</font><span style=font-size:x-large>b]ar</span>", ["<font size=5>fo[o</font><span style=font-size:x-large>b]ar</span>",
[["stylewithcss","true"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"5",false,false,"4"]}], {"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>", ["<font size=5>fo[o</font><span style=font-size:x-large>b]ar</span>",
[["stylewithcss","false"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"5",false,false,"4"]}], {"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>", ["<font size=6>fo[o</font><span style=font-size:xx-large>b]ar</span>",
[["stylewithcss","true"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"6",false,false,"4"]}], {"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>", ["<font size=6>fo[o</font><span style=font-size:xx-large>b]ar</span>",
[["stylewithcss","false"],["fontsize","4"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"6",false,false,"4"]}], {"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>", "<font face=\"monospace\">ab<font size=\"7\">[c]</font></font>",
[true,true], [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)"]}], {"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>", ["<span style=\"color: blue\">foo<span style=\"color: brown\">[bar]</span>baz</span>",
[["stylewithcss","true"],["forecolor","#0000FF"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], {"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>", ["<span style=\"color: blue\">foo<span style=\"color: brown\">[bar]</span>baz</span>",
[["stylewithcss","false"],["forecolor","#0000FF"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], {"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>", ["<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", "foo<span id=\"purple\">ba<font color=\"#0000ff\">[r</font></span><font color=\"#0000ff\">ba]</font>z",
[true,true], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"forecolor":[true,false,"rgb(128, 0, 128)",false,false,"rgb(0, 0, 255)"]}], {"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>", ["<span style=\"color: rgb(0, 0, 255)\">foo<span id=purple>b[a]r</span>baz</span>",
[["stylewithcss","true"],["forecolor","#0000FF"]], [["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>", "<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)"]}], {"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", ["fo[o<font color=brown>b]ar</font>baz",
[["stylewithcss","true"],["forecolor","#0000FF"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"forecolor":[true,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], {"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", ["fo[o<font color=brown>b]ar</font>baz",
[["stylewithcss","false"],["forecolor","#0000FF"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"forecolor":[true,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], {"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", ["foo<font color=brown>ba[r</font>b]az",
[["stylewithcss","true"],["forecolor","#0000FF"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"forecolor":[true,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], {"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", ["foo<font color=brown>ba[r</font>b]az",
[["stylewithcss","false"],["forecolor","#0000FF"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"forecolor":[true,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], {"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", ["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)"]}], {"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", ["foo[<font color=brown>b]ar</font>baz",
[["stylewithcss","true"],["forecolor","#0000FF"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], {"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", ["foo[<font color=brown>b]ar</font>baz",
[["stylewithcss","false"],["forecolor","#0000FF"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], {"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", ["foo<font color=brown>ba[r</font>]baz",
[["stylewithcss","true"],["forecolor","#0000FF"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], {"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", ["foo<font color=brown>ba[r</font>]baz",
[["stylewithcss","false"],["forecolor","#0000FF"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], {"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", ["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)"]}], {"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>", ["<font color=brown>fo[o</font><span style=color:brown>b]ar</span>",
[["stylewithcss","true"],["forecolor","#0000FF"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], {"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>", ["<font color=brown>fo[o</font><span style=color:brown>b]ar</span>",
[["stylewithcss","false"],["forecolor","#0000FF"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], {"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>", ["<span style=color:brown>fo[o</span><span style=color:#0000ff>b]ar</span>",
[["stylewithcss","true"],["forecolor","#0000FF"]], [["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], [true,true],
{"stylewithcss":[false,false,"",false,true,""],"forecolor":[true,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], {"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>", ["<span style=color:brown>fo[o</span><span style=color:#0000ff>b]ar</span>",
[["stylewithcss","false"],["forecolor","#0000FF"]], [["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], [true,true],
{"stylewithcss":[false,true,"",false,false,""],"forecolor":[true,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], {"stylewithcss":[false,true,"",false,false,""],"forecolor":[true,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}],