зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1571375 - Don't remove white space when committing composition. r=masayuki
This is regression by bug 1530649. After landing bug 1530649, we try to scan end point of replacement text. But in this bug's situation, afterRun becomes same as current ws run by landing bug 1530649. To get white space type of next of replacement end, we have to scan around end point again. Differential Revision: https://phabricator.services.mozilla.com/D45947 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
746966587f
Коммит
c147a2e204
|
@ -275,7 +275,12 @@ nsresult WSRunObject::InsertText(Document& aDocument,
|
|||
}
|
||||
|
||||
WSFragment* beforeRun = FindNearestRun(mScanStartPoint, false);
|
||||
WSFragment* afterRun = FindNearestRun(mScanEndPoint, true);
|
||||
// If mScanStartPoint isn't equal to mScanEndPoint, it will replace text (i.e.
|
||||
// committing composition). And afterRun will be end point of replaced range.
|
||||
// So we want to know this white space type (trailing whitespace etc) of
|
||||
// this end point, not inserted (start) point, so we re-scan white space type.
|
||||
WSRunObject afterRunObject(mHTMLEditor, mScanEndPoint);
|
||||
WSFragment* afterRun = afterRunObject.FindNearestRun(mScanEndPoint, true);
|
||||
|
||||
EditorDOMPoint pointToInsert(mScanStartPoint);
|
||||
nsAutoString theString(aStringToInsert);
|
||||
|
@ -668,7 +673,7 @@ nsresult WSRunScanner::GetWSNodes() {
|
|||
// collect up an array of nodes that are contiguous with the insertion point
|
||||
// and which contain only whitespace. Stop if you reach non-ws text or a new
|
||||
// block boundary.
|
||||
EditorDOMPoint start(mScanStartPoint), end(mScanEndPoint);
|
||||
EditorDOMPoint start(mScanStartPoint), end(mScanStartPoint);
|
||||
nsCOMPtr<nsINode> wsBoundingParent = GetWSBoundingParent();
|
||||
|
||||
// first look backwards to find preceding ws nodes
|
||||
|
@ -777,12 +782,11 @@ nsresult WSRunScanner::GetWSNodes() {
|
|||
}
|
||||
|
||||
// then look ahead to find following ws nodes
|
||||
if (Text* textNode = mScanEndPoint.GetContainerAsText()) {
|
||||
if (Text* textNode = end.GetContainerAsText()) {
|
||||
// don't need to put it on list. it already is from code above
|
||||
const nsTextFragment* textFrag = &textNode->TextFragment();
|
||||
if (!mScanEndPoint.IsEndOfContainer()) {
|
||||
for (uint32_t i = mScanEndPoint.Offset(); i < textNode->TextLength();
|
||||
i++) {
|
||||
if (!end.IsEndOfContainer()) {
|
||||
for (uint32_t i = end.Offset(); i < textNode->TextLength(); i++) {
|
||||
// sanity bounds check the char position. bug 136165
|
||||
if (i >= textFrag->GetLength()) {
|
||||
MOZ_ASSERT_UNREACHABLE("looking beyond end of text fragment");
|
||||
|
|
|
@ -139,8 +139,12 @@ class MOZ_STACK_CLASS WSRunScanner {
|
|||
* host. aScanEndPoint (aScanEndNode and aScanEndOffset) must be later
|
||||
* point from aScanStartPoint (aScanStartNode and aScanStartOffset).
|
||||
* The end point is currently used only with InsertText(). Therefore,
|
||||
* currently, this assumes that the range does not cross block boundary. If
|
||||
* you use aScanEndPoint newly, please test enough.
|
||||
* currently, this assumes that the range does not cross block boundary.
|
||||
*
|
||||
* Actually, WSRunScanner scans white space type at mScanStartPoint position
|
||||
* only.
|
||||
*
|
||||
* If you use aScanEndPoint newly, please test enough.
|
||||
*/
|
||||
template <typename PT, typename CT>
|
||||
WSRunScanner(const HTMLEditor* aHTMLEditor,
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
src="data:text/html,<div contenteditable id='contenteditable'></div>"></iframe><br/>
|
||||
<iframe id="iframe5" width="200" height="50" src="data:text/html,<input id='input'>"></iframe>
|
||||
<iframe id="iframe6" width="200" height="50" src="data:text/html,<input id='password' type='password'>"></iframe><br/>
|
||||
<iframe id="iframe7" width="300" height="150"
|
||||
src="data:text/html,<span contenteditable id='contenteditable'></span>"></iframe><br/>
|
||||
<input id="input" type="text"/><br/>
|
||||
<input id="password" type="password"/><br/>
|
||||
</p>
|
||||
|
@ -5186,6 +5188,61 @@ function runBug1530649Test()
|
|||
"runBug1530649Test: Committing the new composition string shouldn't remove the last space");
|
||||
}
|
||||
|
||||
function runBug1571375Test()
|
||||
{
|
||||
let contenteditableBySpan = document.getElementById("iframe7").contentDocument.getElementById("contenteditable");
|
||||
let windowOfContenteditableBySpan = document.getElementById("iframe7").contentWindow;
|
||||
let selection = windowOfContenteditableBySpan.getSelection();
|
||||
let doc = document.getElementById("iframe7").contentDocument;
|
||||
|
||||
contenteditableBySpan.focus();
|
||||
|
||||
contenteditableBySpan.innerHTML = "hello world";
|
||||
let range = doc.createRange();
|
||||
range.setStart(contenteditableBySpan.firstChild, 6);
|
||||
range.setEnd(contenteditableBySpan.firstChild, 11);
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
|
||||
synthesizeCompositionChange({
|
||||
composition: {string: "world", clauses: [{length: 5, attr: COMPOSITION_ATTR_RAW_CLAUSE}]},
|
||||
caret: { start: 5, length: 0 },
|
||||
});
|
||||
synthesizeComposition({type: "compositioncommit", data: "world", key: " "});
|
||||
is(contenteditableBySpan.innerHTML, "hello world",
|
||||
"runBug1571375Test: space must not be removed by commit");
|
||||
|
||||
contenteditableBySpan.innerHTML = "hello world";
|
||||
range = doc.createRange();
|
||||
range.setStart(contenteditableBySpan.firstChild, 0);
|
||||
range.setEnd(contenteditableBySpan.firstChild, 5);
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
|
||||
synthesizeCompositionChange({
|
||||
composition: {string: "hello", clauses: [{length: 5, attr: COMPOSITION_ATTR_RAW_CLAUSE}]},
|
||||
caret: { start: 5, length: 0 },
|
||||
});
|
||||
synthesizeComposition({type: "compositioncommit", data: "hello", key: " "});
|
||||
is(contenteditableBySpan.innerHTML, "hello world",
|
||||
"runBug1571375Test: space must not be removed by commit");
|
||||
|
||||
contenteditableBySpan.innerHTML = "hello world<div>.</div>";
|
||||
range = doc.createRange();
|
||||
range.setStart(contenteditableBySpan.firstChild, 6);
|
||||
range.setEnd(contenteditableBySpan.firstChild, 11);
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
|
||||
synthesizeCompositionChange({
|
||||
composition: {string: "world", clauses: [{length: 5, attr: COMPOSITION_ATTR_RAW_CLAUSE}]},
|
||||
caret: {start: 0, length: 0}}
|
||||
);
|
||||
synthesizeComposition({type: "compositioncommit", data: "world", key: " "});
|
||||
is(contenteditableBySpan.innerHTML, "hello world<div>.</div>",
|
||||
"runBug1571375Test: space must not be removed by commit");
|
||||
}
|
||||
|
||||
function runCSSTransformTest()
|
||||
{
|
||||
textarea.focus();
|
||||
|
@ -9105,6 +9162,7 @@ async function runTest()
|
|||
runBug722639Test();
|
||||
runBug1375825Test();
|
||||
runBug1530649Test();
|
||||
runBug1571375Test();
|
||||
runForceCommitTest();
|
||||
runNestedSettingValue();
|
||||
runBug811755Test();
|
||||
|
|
Загрузка…
Ссылка в новой задаче