mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1125934 - Discard redundant NS_COMPOSITION_CHANGE event which is send just before NS_COMPOSITION_END on TSF. r=masayuki
This commit is contained in:
parent
d8f563fcbd
commit
6558751505
@ -224,6 +224,17 @@ TextComposition::DispatchCompositionEvent(
|
||||
dispatchEvent = dispatchDOMTextEvent = false;
|
||||
}
|
||||
|
||||
// widget may dispatch redundant NS_COMPOSITION_CHANGE event
|
||||
// which modifies neither composition string, clauses nor caret
|
||||
// position. In such case, we shouldn't dispatch DOM events.
|
||||
if (dispatchDOMTextEvent &&
|
||||
aCompositionEvent->message == NS_COMPOSITION_CHANGE &&
|
||||
mLastData == aCompositionEvent->mData &&
|
||||
mRanges && aCompositionEvent->mRanges &&
|
||||
mRanges->Equals(*aCompositionEvent->mRanges)) {
|
||||
dispatchEvent = dispatchDOMTextEvent = false;
|
||||
}
|
||||
|
||||
if (dispatchDOMTextEvent) {
|
||||
if (!MaybeDispatchCompositionUpdate(aCompositionEvent)) {
|
||||
return;
|
||||
|
@ -84,7 +84,7 @@ struct TextRangeStyle
|
||||
IsLineStyleDefined() && mLineStyle == LINESTYLE_NONE;
|
||||
}
|
||||
|
||||
bool Equals(const TextRangeStyle& aOther)
|
||||
bool Equals(const TextRangeStyle& aOther) const
|
||||
{
|
||||
if (mDefinedStyles != aOther.mDefinedStyles)
|
||||
return false;
|
||||
@ -103,12 +103,12 @@ struct TextRangeStyle
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator !=(const TextRangeStyle &aOther)
|
||||
bool operator !=(const TextRangeStyle &aOther) const
|
||||
{
|
||||
return !Equals(aOther);
|
||||
}
|
||||
|
||||
bool operator ==(const TextRangeStyle &aOther)
|
||||
bool operator ==(const TextRangeStyle &aOther) const
|
||||
{
|
||||
return Equals(aOther);
|
||||
}
|
||||
@ -166,6 +166,14 @@ struct TextRange
|
||||
"Invalid range type");
|
||||
return mRangeType != NS_TEXTRANGE_CARETPOSITION;
|
||||
}
|
||||
|
||||
bool Equals(const TextRange& aOther) const
|
||||
{
|
||||
return mStartOffset == aOther.mStartOffset &&
|
||||
mEndOffset == aOther.mEndOffset &&
|
||||
mRangeType == aOther.mRangeType &&
|
||||
mRangeStyle == aOther.mRangeStyle;
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
@ -201,6 +209,20 @@ public:
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Equals(const TextRangeArray& aOther) const
|
||||
{
|
||||
size_t len = Length();
|
||||
if (len != aOther.Length()) {
|
||||
return false;
|
||||
}
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (!ElementAt(i).Equals(aOther.ElementAt(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -2978,6 +2978,178 @@ function runIsComposingTest()
|
||||
textarea.value = "";
|
||||
}
|
||||
|
||||
function runRedundantChangeTest()
|
||||
{
|
||||
textarea.focus();
|
||||
|
||||
var result = {};
|
||||
function clearResult()
|
||||
{
|
||||
result = { compositionupdate: false, compositionend: false, text: false, input: false };
|
||||
}
|
||||
|
||||
function handler(aEvent)
|
||||
{
|
||||
result[aEvent.type] = true;
|
||||
}
|
||||
|
||||
textarea.addEventListener("compositionupdate", handler, true);
|
||||
textarea.addEventListener("compositionend", handler, true);
|
||||
textarea.addEventListener("input", handler, true);
|
||||
textarea.addEventListener("text", handler, true);
|
||||
|
||||
textarea.value = "";
|
||||
|
||||
// synthesize change event
|
||||
clearResult();
|
||||
synthesizeCompositionChange(
|
||||
{ "composition":
|
||||
{ "string": "\u3042",
|
||||
"clauses":
|
||||
[
|
||||
{ "length": 1, "attr": COMPOSITION_ATTR_SELECTED_CLAUSE }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 1, "length": 0 }
|
||||
});
|
||||
|
||||
is(result.compositionupdate, true, "runRedundantChangeTest: compositionupdate should be fired after synthesizing composition change #1");
|
||||
is(result.compositionend, false, "runRedundantChangeTest: compositionend shouldn't be fired after synthesizing composition change #1");
|
||||
is(result.text, true, "runRedundantChangeTest: text should be fired after synthesizing composition change because it's dispatched when there is composing string #1");
|
||||
is(result.input, true, "runRedundantChangeTest: input should be fired after synthesizing composition change #1");
|
||||
is(textarea.value, "\u3042", "runRedundantChangeTest: textarea has uncommitted string #1");
|
||||
|
||||
// synthesize another change event
|
||||
clearResult();
|
||||
synthesizeCompositionChange(
|
||||
{ "composition":
|
||||
{ "string": "\u3042\u3044",
|
||||
"clauses":
|
||||
[
|
||||
{ "length": 2, "attr": COMPOSITION_ATTR_SELECTED_CLAUSE }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 2, "length": 0 }
|
||||
});
|
||||
|
||||
is(result.compositionupdate, true, "runRedundantChangeTest: compositionupdate should be fired after synthesizing composition change #2");
|
||||
is(result.compositionend, false, "runRedundantChangeTest: compositionend shouldn't be fired after synthesizing composition change #2");
|
||||
is(result.text, true, "runRedundantChangeTest: text should be fired after synthesizing composition change because it's dispatched when there is composing string #2");
|
||||
is(result.input, true, "runRedundantChangeTest: input should be fired after synthesizing composition change #2");
|
||||
is(textarea.value, "\u3042\u3044", "runRedundantChangeTest: textarea has uncommitted string #2");
|
||||
|
||||
// synthesize same change event again
|
||||
clearResult();
|
||||
synthesizeCompositionChange(
|
||||
{ "composition":
|
||||
{ "string": "\u3042\u3044",
|
||||
"clauses":
|
||||
[
|
||||
{ "length": 2, "attr": COMPOSITION_ATTR_SELECTED_CLAUSE }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 2, "length": 0 }
|
||||
});
|
||||
|
||||
is(result.compositionupdate, false, "runRedundantChangeTest: compositionupdate shouldn't be fired after synthesizing composition change again");
|
||||
is(result.compositionend, false, "runRedundantChangeTest: compositionend shouldn't be fired after synthesizing composition change again");
|
||||
is(result.text, false, "runRedundantChangeTest: text shouldn't be fired after synthesizing composition change again because it's dispatched when there is composing string");
|
||||
is(result.input, false, "runRedundantChangeTest: input shouldn't be fired after synthesizing composition change again");
|
||||
is(textarea.value, "\u3042\u3044", "runRedundantChangeTest: textarea has uncommitted string #3");
|
||||
|
||||
synthesizeComposition({ type: "compositioncommit" });
|
||||
|
||||
textarea.removeEventListener("compositionupdate", handler, true);
|
||||
textarea.removeEventListener("compositionend", handler, true);
|
||||
textarea.removeEventListener("input", handler, true);
|
||||
textarea.removeEventListener("text", handler, true);
|
||||
}
|
||||
|
||||
function runNotRedundantChangeTest()
|
||||
{
|
||||
textarea.focus();
|
||||
|
||||
var result = {};
|
||||
function clearResult()
|
||||
{
|
||||
result = { compositionupdate: false, compositionend: false, text: false, input: false };
|
||||
}
|
||||
|
||||
function handler(aEvent)
|
||||
{
|
||||
result[aEvent.type] = true;
|
||||
}
|
||||
|
||||
textarea.addEventListener("compositionupdate", handler, true);
|
||||
textarea.addEventListener("compositionend", handler, true);
|
||||
textarea.addEventListener("input", handler, true);
|
||||
textarea.addEventListener("text", handler, true);
|
||||
|
||||
textarea.value = "abcde";
|
||||
|
||||
// synthesize change event with non-null ranges
|
||||
clearResult();
|
||||
synthesizeCompositionChange(
|
||||
{ "composition":
|
||||
{ "string": "ABCDE",
|
||||
"clauses":
|
||||
[
|
||||
{ "length": 5, "attr": COMPOSITION_ATTR_SELECTED_CLAUSE }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 5, "length": 0 }
|
||||
});
|
||||
|
||||
is(result.compositionupdate, true, "runNotRedundantChangeTest: compositionupdate should be fired after synthesizing composition change with non-null ranges");
|
||||
is(result.compositionend, false, "runNotRedundantChangeTest: compositionend shouldn't be fired after synthesizing composition change with non-null ranges");
|
||||
is(result.text, true, "runNotRedundantChangeTest: text should be fired after synthesizing composition change because it's dispatched when there is composing string with non-null ranges");
|
||||
is(result.input, true, "runNotRedundantChangeTest: input should be fired after synthesizing composition change with non-null ranges");
|
||||
is(textarea.value, "abcdeABCDE", "runNotRedundantChangeTest: textarea has uncommitted string #1");
|
||||
|
||||
// synthesize change event with null ranges
|
||||
clearResult();
|
||||
synthesizeCompositionChange(
|
||||
{ "composition":
|
||||
{ "string": "",
|
||||
"clauses":
|
||||
[
|
||||
{ "length": 0, "attr": 0 }
|
||||
]
|
||||
},
|
||||
});
|
||||
is(result.compositionupdate, true, "runNotRedundantChangeTest: compositionupdate should be fired after synthesizing composition change with null ranges after non-null ranges");
|
||||
is(result.compositionend, false, "runNotRedundantChangeTest: compositionend shouldn't be fired after synthesizing composition change with null ranges after non-null ranges");
|
||||
is(result.text, true, "runNotRedundantChangeTest: text should be fired after synthesizing composition change because it's dispatched when there is composing string with null ranges after non-null ranges");
|
||||
is(result.input, false, "runNotRedundantChangeTest: input shouldn't be fired after synthesizing composition change with null ranges after non-null ranges");
|
||||
is(textarea.value, "abcde", "runNotRedundantChangeTest: textarea doesn't have uncommitted string");
|
||||
|
||||
// synthesize change event with non-null ranges
|
||||
clearResult();
|
||||
synthesizeCompositionChange(
|
||||
{ "composition":
|
||||
{ "string": "ABCDE",
|
||||
"clauses":
|
||||
[
|
||||
{ "length": 5, "attr": COMPOSITION_ATTR_SELECTED_CLAUSE }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 5, "length": 0 }
|
||||
});
|
||||
|
||||
is(result.compositionupdate, true, "runNotRedundantChangeTest: compositionupdate should be fired after synthesizing composition change with non-null ranges after null ranges");
|
||||
is(result.compositionend, false, "runNotRedundantChangeTest: compositionend shouldn't be fired after synthesizing composition change with non-null ranges after null ranges");
|
||||
is(result.text, true, "runNotRedundantChangeTest: text should be fired after synthesizing composition change because it's dispatched when there is composing string with non-null ranges after null ranges");
|
||||
is(result.input, true, "runNotRedundantChangeTest: input should be fired after synthesizing composition change with non-null ranges after null ranges");
|
||||
is(textarea.value, "abcdeABCDE", "runNotRedundantChangeTest: textarea has uncommitted string #2");
|
||||
|
||||
synthesizeComposition({ type: "compositioncommit", data: "" });
|
||||
|
||||
textarea.removeEventListener("compositionupdate", handler, true);
|
||||
textarea.removeEventListener("compositionend", handler, true);
|
||||
textarea.removeEventListener("input", handler, true);
|
||||
textarea.removeEventListener("text", handler, true);
|
||||
}
|
||||
|
||||
function runRemoveContentTest(aCallback)
|
||||
{
|
||||
var events = [];
|
||||
@ -3550,6 +3722,8 @@ function runTest()
|
||||
runForceCommitTest();
|
||||
runBug811755Test();
|
||||
runIsComposingTest();
|
||||
runRedundantChangeTest();
|
||||
runNotRedundantChangeTest();
|
||||
runAsyncForceCommitTest(function () {
|
||||
runRemoveContentTest(function () {
|
||||
runFrameTest();
|
||||
|
Loading…
Reference in New Issue
Block a user