Bug 1811434 - Make HTMLEditor never join <font> elements if they have different styles r=m_kato

Currently, `HTMLEditor` joins inline elements if the tag name is same and the
specified CSS style is not different.  However, this may cause loosing style
specified by `<font>` elements at joining 2 paragraphs etc.  We should not
join `<font>` elements if they have:
* different values for `color`, `size` or `face`
* only one has `color`, `size` or `face`

I don't delete unnecessary testcases in `delete.js` and `forwarddelete.js` which
are same as adding tests because deleting them causes unexpected failures of
some following tests near the boundary of test chunks.  Perhaps, we should
group them better in another bug.

Differential Revision: https://phabricator.services.mozilla.com/D167742
This commit is contained in:
Masayuki Nakano 2023-01-26 10:10:07 +00:00
parent 46b5e78f5d
commit 70bec1642d
5 changed files with 228 additions and 12 deletions

View file

@ -144,6 +144,32 @@ bool HTMLEditUtils::CanContentsBeJoined(const nsIContent& aLeftContent,
aRightContent.NodeInfo()->NameAtom()) {
return false;
}
if (aLeftContent.NodeInfo()->NameAtom() == nsGkAtoms::font) {
const nsAttrValue* const leftSize =
aLeftContent.AsElement()->GetParsedAttr(nsGkAtoms::size);
const nsAttrValue* const rightSize =
aRightContent.AsElement()->GetParsedAttr(nsGkAtoms::size);
if (!leftSize ^ !rightSize || (leftSize && !leftSize->Equals(*rightSize))) {
return false;
}
const nsAttrValue* const leftColor =
aLeftContent.AsElement()->GetParsedAttr(nsGkAtoms::color);
const nsAttrValue* const rightColor =
aRightContent.AsElement()->GetParsedAttr(nsGkAtoms::color);
if (!leftColor ^ !rightColor ||
(leftColor && !leftColor->Equals(*rightColor))) {
return false;
}
const nsAttrValue* const leftFace =
aLeftContent.AsElement()->GetParsedAttr(nsGkAtoms::face);
const nsAttrValue* const rightFace =
aRightContent.AsElement()->GetParsedAttr(nsGkAtoms::face);
if (!leftFace ^ !rightFace || (leftFace && !leftFace->Equals(*rightFace))) {
return false;
}
}
if (aStyleDifference == StyleDifference::Ignore ||
!aLeftContent.IsElement()) {
return true;

View file

@ -334,12 +334,6 @@
[[["stylewithcss","false"\],["defaultparagraphseparator","p"\],["delete",""\]\] "<p>foo<p style=color:brown>[\]bar" compare innerHTML]
expected: FAIL
[[["defaultparagraphseparator","div"\],["delete",""\]\] "<p><font color=blue>foo</font><p><font color=brown>[\]bar</font>" compare innerHTML]
expected: FAIL
[[["defaultparagraphseparator","p"\],["delete",""\]\] "<p><font color=blue>foo</font><p><font color=brown>[\]bar</font>" compare innerHTML]
expected: FAIL
[[["defaultparagraphseparator","div"\],["delete",""\]\] "<p style=background-color:aqua>foo<p>[\]bar" compare innerHTML]
expected: FAIL
@ -708,3 +702,57 @@
[[["delete",""\]\] "<ul><li>abc</li><li contenteditable=\\"false\\">def</li></ul><p>[\]ghi</p>" compare innerHTML]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","div"\],["delete",""\]\] "<p><font color=blue>foo</font><p><font color=brown>[\]bar</font>" queryCommandValue("foreColor") after]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","p"\],["delete",""\]\] "<p><font color=blue>foo</font><p><font color=brown>[\]bar</font>" queryCommandValue("foreColor") after]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","div"\],["delete",""\]\] "<p><font size=3>foo</font><p><font size=5>[\]bar</font>" queryCommandValue("fontSize") after]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","p"\],["delete",""\]\] "<p><font size=3>foo</font><p><font size=5>[\]bar</font>" queryCommandValue("fontSize") after]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","div"\],["delete",""\]\] "<p><font size=4>foo</font><p><font size=5>[\]bar</font>" queryCommandValue("fontSize") after]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","p"\],["delete",""\]\] "<p><font size=4>foo</font><p><font size=5>[\]bar</font>" queryCommandValue("fontSize") after]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","div"\],["delete",""\]\] "<p><font color=blue>foo</font><p><font size=5>[\]bar</font>" queryCommandValue("fontSize") after]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","div"\],["delete",""\]\] "<p><font color=blue>foo</font><p><font size=5>[\]bar</font>" queryCommandValue("foreColor") after]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","p"\],["delete",""\]\] "<p><font color=blue>foo</font><p><font size=5>[\]bar</font>" queryCommandValue("fontSize") after]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","p"\],["delete",""\]\] "<p><font color=blue>foo</font><p><font size=5>[\]bar</font>" queryCommandValue("foreColor") after]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","div"\],["delete",""\]\] "<p><font size=5>foo</font><p><font color=blue>[\]bar</font>" queryCommandValue("fontSize") before]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","div"\],["delete",""\]\] "<p><font size=5>foo</font><p><font color=blue>[\]bar</font>" queryCommandValue("fontSize") after]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","div"\],["delete",""\]\] "<p><font size=5>foo</font><p><font color=blue>[\]bar</font>" queryCommandValue("foreColor") after]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","p"\],["delete",""\]\] "<p><font size=5>foo</font><p><font color=blue>[\]bar</font>" queryCommandValue("fontSize") before]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","p"\],["delete",""\]\] "<p><font size=5>foo</font><p><font color=blue>[\]bar</font>" queryCommandValue("fontSize") after]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","p"\],["delete",""\]\] "<p><font size=5>foo</font><p><font color=blue>[\]bar</font>" queryCommandValue("foreColor") after]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","div"\],["delete",""\]\] "<p><font face=monospace>foo</font><p><font face=sans-serif>[\]bar</font>" queryCommandValue("fontName") after]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","p"\],["delete",""\]\] "<p><font face=monospace>foo</font><p><font face=sans-serif>[\]bar</font>" queryCommandValue("fontName") after]
expected: FAIL

View file

@ -262,12 +262,6 @@
[[["stylewithcss","false"\],["defaultparagraphseparator","p"\],["forwarddelete",""\]\] "<p>foo[\]<p style=color:brown>bar" compare innerHTML]
expected: FAIL
[[["defaultparagraphseparator","div"\],["forwarddelete",""\]\] "<p><font color=blue>foo[\]</font><p><font color=brown>bar</font>" compare innerHTML]
expected: FAIL
[[["defaultparagraphseparator","p"\],["forwarddelete",""\]\] "<p><font color=blue>foo[\]</font><p><font color=brown>bar</font>" compare innerHTML]
expected: FAIL
[[["defaultparagraphseparator","div"\],["forwarddelete",""\]\] "<p><span style=color:blue>foo[\]</font><p><span style=color:brown>bar</font>" compare innerHTML]
expected: FAIL
@ -585,3 +579,27 @@
[[["forwarddelete",""\]\] "<p><quasit>[foo\]</quasit>" compare innerHTML]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","div"\],["forwarddelete",""\]\] "<p><font color=blue>foo[\]</font><p><font color=brown>bar</font>" queryCommandValue("foreColor") after]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","p"\],["forwarddelete",""\]\] "<p><font color=blue>foo[\]</font><p><font color=brown>bar</font>" queryCommandValue("foreColor") after]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","div"\],["forwarddelete",""\]\] "<p><font color=blue>foo[\]</font><p><font size=5>bar</font>" queryCommandValue("fontSize") before]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","div"\],["forwarddelete",""\]\] "<p><font color=blue>foo[\]</font><p><font size=5>bar</font>" queryCommandValue("fontSize") after]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","div"\],["forwarddelete",""\]\] "<p><font color=blue>foo[\]</font><p><font size=5>bar</font>" queryCommandValue("foreColor") after]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","p"\],["forwarddelete",""\]\] "<p><font color=blue>foo[\]</font><p><font size=5>bar</font>" queryCommandValue("fontSize") before]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","p"\],["forwarddelete",""\]\] "<p><font color=blue>foo[\]</font><p><font size=5>bar</font>" queryCommandValue("fontSize") after]
expected: FAIL
[[["styleWithCSS","false"\],["defaultparagraphseparator","p"\],["forwarddelete",""\]\] "<p><font color=blue>foo[\]</font><p><font size=5>bar</font>" queryCommandValue("foreColor") after]
expected: FAIL

View file

@ -2806,4 +2806,66 @@ var browserTests = [
"<ul><li>abcghi<br></li></ul>"],
[true],
{"delete":[false,false,"",false,false,""]}],
// <font>s shouldn't be joined if they have different attributes.
["<p><font color=blue>foo</font><p><font color=brown>[]bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","div"],["delete",""]],
"<p><font color=\"blue\">foo[]</font><font color=\"brown\">bar</font></p>",
[true,true,true],
{"foreColor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}],
["<p><font color=blue>foo</font><p><font color=brown>[]bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","p"],["delete",""]],
"<p><font color=\"blue\">foo[]</font><font color=\"brown\">bar</font></p>",
[true,true,true],
{"foreColor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}],
["<p><font size=3>foo</font><p><font size=5>[]bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","div"],["delete",""]],
"<p><font size=\"3\">foo[]</font><font size=\"5\">bar</font></p>",
[true,true,true],
{"fontSize":[false,false,"5",false,false,"3"]}],
["<p><font size=3>foo</font><p><font size=5>[]bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","p"],["delete",""]],
"<p><font size=\"3\">foo[]</font><font size=\"5\">bar</font></p>",
[true,true,true],
{"fontSize":[false,false,"5",false,false,"3"]}],
["<p><font size=4>foo</font><p><font size=5>[]bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","div"],["delete",""]],
"<p><font size=\"4\">foo[]</font><font size=\"5\">bar</font></p>",
[true,true,true],
{"fontSize":[false,false,"5",false,false,"4"]}],
["<p><font size=4>foo</font><p><font size=5>[]bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","p"],["delete",""]],
"<p><font size=\"4\">foo[]</font><font size=\"5\">bar</font></p>",
[true,true,true],
{"fontSize":[false,false,"5",false,false,"4"]}],
["<p><font color=blue>foo</font><p><font size=5>[]bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","div"],["delete",""]],
"<p><font color=\"blue\">foo[]</font><font size=\"5\">bar</font></p>",
[true,true,true],
{"fontSize":[false,false,"5",false,false,"3"],"foreColor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}],
["<p><font color=blue>foo</font><p><font size=5>[]bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","p"],["delete",""]],
"<p><font color=\"blue\">foo[]</font><font size=\"5\">bar</font></p>",
[true,true,true],
{"fontSize":[false,false,"5",false,false,"3"],"foreColor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}],
["<p><font size=5>foo</font><p><font color=blue>[]bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","div"],["delete",""]],
"<p><font size=\"5\">foo[]</font><font color=\"blue\">bar</font></p>",
[true,true,true],
{"fontSize":[false,false,"3",false,false,"5"],"foreColor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 0)"]}],
["<p><font size=5>foo</font><p><font color=blue>[]bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","p"],["delete",""]],
"<p><font size=\"5\">foo[]</font><font color=\"blue\">bar</font></p>",
[true,true,true],
{"fontSize":[false,false,"3",false,false,"5"],"foreColor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 0)"]}],
["<p><font face=monospace>foo</font><p><font face=sans-serif>[]bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","div"],["delete",""]],
"<p><font face=\"monospace\">foo[]</font><font face=\"sans-serif\">bar</font></p>",
[true,true,true],
{"fontName":[false,false,"sans-serif",false,false,"monospace"]}],
["<p><font face=monospace>foo</font><p><font face=sans-serif>[]bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","p"],["delete",""]],
"<p><font face=\"monospace\">foo[]</font><font face=\"sans-serif\">bar</font></p>",
[true,true,true],
{"fontName":[false,false,"sans-serif",false,false,"monospace"]}],
]

View file

@ -2686,4 +2686,66 @@ var browserTests = [
"<ul><li>abcghi<br></li></ul>"],
[true],
{"forwarddelete":[false,false,"",false,false,""]}],
// <font>s shouldn't be joined if they have different attributes.
["<p><font color=blue>foo[]</font><p><font color=brown>bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","div"],["forwarddelete",""]],
"<p><font color=\"blue\">foo[]</font><font color=\"brown\">bar</font></p>",
[true,true,true],
{"foreColor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}],
["<p><font color=blue>foo[]</font><p><font color=brown>bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","p"],["forwarddelete",""]],
"<p><font color=\"blue\">foo[]</font><font color=\"brown\">bar</font></p>",
[true,true,true],
{"foreColor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}],
["<p><font size=3>foo[]</font><p><font size=5>bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","div"],["forwarddelete",""]],
"<p><font size=\"3\">foo[]</font><font size=\"5\">bar</font></p>",
[true,true,true],
{"fontSize":[false,false,"3",false,false,"3"]}],
["<p><font size=3>foo[]</font><p><font size=5>bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","p"],["forwarddelete",""]],
"<p><font size=\"3\">foo[]</font><font size=\"5\">bar</font></p>",
[true,true,true],
{"fontSize":[false,false,"3",false,false,"3"]}],
["<p><font size=4>foo[]</font><p><font size=5>bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","div"],["forwarddelete",""]],
"<p><font size=\"4\">foo[]</font><font size=\"5\">bar</font></p>",
[true,true,true],
{"fontSize":[false,false,"4",false,false,"4"]}],
["<p><font size=4>foo[]</font><p><font size=5>bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","p"],["forwarddelete",""]],
"<p><font size=\"4\">foo[]</font><font size=\"5\">bar</font></p>",
[true,true,true],
{"fontSize":[false,false,"4",false,false,"4"]}],
["<p><font color=blue>foo[]</font><p><font size=5>bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","div"],["forwarddelete",""]],
"<p><font color=\"blue\">foo[]</font><font size=\"5\">bar</font></p>",
[true,true,true],
{"fontSize":[false,false,"3",false,false,"3"],"foreColor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}],
["<p><font color=blue>foo[]</font><p><font size=5>bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","p"],["forwarddelete",""]],
"<p><font color=\"blue\">foo[]</font><font size=\"5\">bar</font></p>",
[true,true,true],
{"fontSize":[false,false,"3",false,false,"3"],"foreColor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}],
["<p><font size=5>foo[]</font><p><font color=blue>bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","div"],["forwarddelete",""]],
"<p><font size=\"5\">foo[]</font><font color=\"blue\">bar</font></p>",
[true,true,true],
{"fontSize":[false,false,"5",false,false,"5"],"foreColor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 0)"]}],
["<p><font size=5>foo[]</font><p><font color=blue>bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","p"],["forwarddelete",""]],
"<p><font size=\"5\">foo[]</font><font color=\"blue\">bar</font></p>",
[true,true,true],
{"fontSize":[false,false,"5",false,false,"5"],"foreColor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 0)"]}],
["<p><font face=monospace>foo[]</font><p><font face=sans-serif>bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","div"],["forwarddelete",""]],
"<p><font face=\"monospace\">foo[]</font><font face=\"sans-serif\">bar</font></p>",
[true,true,true],
{"fontName":[false,false,"monospace",false,false,"monospace"]}],
["<p><font face=monospace>foo[]</font><p><font face=sans-serif>bar</font>",
[["styleWithCSS","false"],["defaultparagraphseparator","p"],["forwarddelete",""]],
"<p><font face=\"monospace\">foo[]</font><font face=\"sans-serif\">bar</font></p>",
[true,true,true],
{"fontName":[false,false,"monospace",false,false,"monospace"]}],
]