blob: 2685a20fbb53807286617770996df37552a61fd1 [file] [log] [blame]
<!doctype html>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../assert_selection.js"></script>
<script>
// For https://bugs.webkit.org/show_bug.cgi?id=57340, which introduce
// VisibleSelection::Visible{Base,Extent}() and |original_base_| in
// |SelectionController|.
// TODO(editing-dev): We should make this test faster[1], e.g. do not drag
// all characters.
// [1] http://crbug.com/741259
const kFontSize = '20px';
const kMouseStep = 5;
function fold(string) {
const results = [];
for (let i = 0; i < string.length; i++) {
let code = string.charCodeAt(i);
if (0x05d0 <= code && code <= 0x05ea)// Hebrew Alef
code += -0x05d0 + 'A'.charCodeAt(0);
results.push(String.fromCharCode(code));
}
return results.join('');
}
function startDrag(x, y) {
assert_own_property(window, 'eventSender', 'This test requires window.eventSender');
eventSender.dragMode = false;
// Clear click count
eventSender.mouseMoveTo(0, 0);
eventSender.mouseDown();
eventSender.mouseUp();
eventSender.mouseMoveTo(x, y);
eventSender.mouseDown();
}
function endDrag() {
eventSender.mouseUp();
}
class StaticRange {
constructor(selection) {
this.anchorNode_ = selection.anchorNode;
this.anchorOffset_ = selection.anchorOffset;
this.focusNode_ = selection.focusNode;
this.focusOffset_ = selection.focusOffset;
}
equals(other) {
return this.anchorNode_ == other.anchorNode_ &&
this.anchorOffset_ == other.anchorOffset_ &&
this.focusNode_ == other.focusNode_ &&
this.focusOffset_ == other.focusOffset_;
}
}
function moveRightUntilSelectionChanged(selection, left, right, y) {
const startRange = new StaticRange(selection);
for (let x = left; x <= right; x += kMouseStep) {
eventSender.mouseMoveTo(x, y);
if (!startRange.equals(new StaticRange(selection)))
return x;
}
throw 'moveRightUntilSelectionChanged failed';
}
function moveLeftUntilSelectionChanged(selection, left, right, y) {
const startRange = new StaticRange(selection);
for (let x = right; x >= left; x -= kMouseStep) {
eventSender.mouseMoveTo(x, y);
if (!startRange.equals(new StaticRange(selection)))
return x;
}
throw 'moveLeftUntilSelectionChanged failed';
}
function dragLeftToRight(selection, count) {
const target = selection.document.querySelector('.target');
const left = selection.computeLeft(target);
const right = left + target.offsetWidth;
const y = selection.computeTop(target);
startDrag(left, y);
let x = left;
for (let i = 0; i < count; ++i)
x = moveRightUntilSelectionChanged(selection, x, right, y);
endDrag();
}
function dragRightToLeft(selection, numberOfSelectionChanges) {
const target = selection.document.querySelector('.target');
const left = selection.computeLeft(target);
const right = left + target.offsetWidth - 1;
const y = selection.computeTop(target);
startDrag(right, y);
let x = right;
for (let i = 0; i < numberOfSelectionChanges; ++i)
x = moveLeftUntilSelectionChanged(selection, left, x, y);
endDrag();
}
function testIt(drag, caseIndex, count, sample, expected, expectedText) {
test(() => assert_selection(
sample,
selection => {
selection.document.body.style.fontFamily = 'monospace';
selection.document.body.style.fontSize = kFontSize;
drag(selection, count);
assert_equals(fold(selection.toString()), expectedText);
},
expected),
`${caseIndex}-${count}: ${drag.name} expects "${expectedText}".`);
}
const kSample1 = '<span class="target">abc\u05d0\u05d1\u05d2</span>';
testIt(dragLeftToRight, 1, 1, kSample1,
'<span class="target">^a|bc\u05d0\u05d1\u05d2</span>', 'a');
testIt(dragLeftToRight, 1, 2, kSample1,
'<span class="target">^ab|c\u05d0\u05d1\u05d2</span>', 'ab');
testIt(dragLeftToRight, 1, 3, kSample1,
'<span class="target">^abc|\u05d0\u05d1\u05d2</span>', 'abc');
testIt(dragLeftToRight, 1, 4, kSample1,
'<span class="target">^abc\u05d0\u05d1|\u05d2</span>', 'abcAB');
testIt(dragLeftToRight, 1, 5, kSample1,
'<span class="target">^abc\u05d0|\u05d1\u05d2</span>', 'abcA');
testIt(dragLeftToRight, 1, 6, kSample1,
'<span class="target">^abc\u05d0\u05d1\u05d2|</span>', 'abcABC');
testIt(dragRightToLeft, 1, 1, kSample1,
'<span class="target">abc^\u05d0|\u05d1\u05d2</span>', 'A');
testIt(dragRightToLeft, 1, 2, kSample1,
'<span class="target">abc^\u05d0\u05d1|\u05d2</span>', 'AB');
testIt(dragRightToLeft, 1, 3, kSample1,
'<span class="target">abc|\u05d0\u05d1\u05d2^</span>', 'ABC');
testIt(dragRightToLeft, 1, 4, kSample1,
'<span class="target">ab|c\u05d0\u05d1\u05d2^</span>', 'cABC');
testIt(dragRightToLeft, 1, 5, kSample1,
'<span class="target">a|bc\u05d0\u05d1\u05d2^</span>', 'bcABC');
testIt(dragRightToLeft, 1, 6, kSample1,
'<span class="target">|abc\u05d0\u05d1\u05d2^</span>', 'abcABC');
const kSample2 = '<span class="target">\u05d0\u05d1\u05d2def</span>';
testIt(dragLeftToRight, 2, 1, kSample2,
'<span class="target">\u05d0\u05d1|\u05d2^def</span>', 'C');
testIt(dragLeftToRight, 2, 2, kSample2,
'<span class="target">\u05d0|\u05d1\u05d2^def</span>', 'BC');
testIt(dragLeftToRight, 2, 3, kSample2,
'<span class="target">^\u05d0\u05d1\u05d2|def</span>', 'ABC');
testIt(dragLeftToRight, 2, 4, kSample2,
'<span class="target">^\u05d0\u05d1\u05d2d|ef</span>', 'ABCd');
testIt(dragLeftToRight, 2, 5, kSample2,
// TODO(editing-dev): This should be 'ABCef' instead of 'ABCde'.
'<span class="target">^\u05d0\u05d1\u05d2de|f</span>', 'ABCde');
testIt(dragLeftToRight, 2, 6, kSample2,
'<span class="target">^\u05d0\u05d1\u05d2def|</span>', 'ABCdef');
testIt(dragRightToLeft, 2, 1, kSample2,
'<span class="target">\u05d0\u05d1\u05d2de|f^</span>', 'f');
testIt(dragRightToLeft, 2, 2, kSample2,
'<span class="target">\u05d0\u05d1\u05d2d|ef^</span>', 'ef');
testIt(dragRightToLeft, 2, 3, kSample2,
'<span class="target">\u05d0\u05d1\u05d2|def^</span>', 'def');
testIt(dragRightToLeft, 2, 4, kSample2,
'<span class="target">\u05d0|\u05d1\u05d2def^</span>', 'BCdef');
testIt(dragRightToLeft, 2, 5, kSample2,
'<span class="target">\u05d0\u05d1|\u05d2def^</span>', 'Cdef');
testIt(dragRightToLeft, 2, 6, kSample2,
'<span class="target">|\u05d0\u05d1\u05d2def^</span>', 'ABCdef');
const kSample3 = 'abc<span class="target">\u05d0\u05d1\u05d2</span>def';
testIt(dragLeftToRight, 3, 1, kSample3,
'abc<span class="target">\u05d0\u05d1|\u05d2^</span>def', 'C');
testIt(dragLeftToRight, 3, 2, kSample3,
'abc<span class="target">\u05d0|\u05d1\u05d2^</span>def', 'BC');
testIt(dragLeftToRight, 3, 3, kSample3,
'abc<span class="target">^\u05d0\u05d1\u05d2|</span>def', 'ABC');
testIt(dragRightToLeft, 3, 1, kSample3,
'abc<span class="target">^\u05d0|\u05d1\u05d2</span>def', 'A');
testIt(dragRightToLeft, 3, 2, kSample3,
'abc<span class="target">^\u05d0\u05d1|\u05d2</span>def', 'AB');
testIt(dragRightToLeft, 3, 3, kSample3,
'abc<span class="target">|\u05d0\u05d1\u05d2^</span>def', 'ABC');
const kSample4 = [
'<div dir="rtl">',
'<span class="target">\u05d0\u05d1\u05d2</span>def',
'</div>',
].join('');
testIt(dragLeftToRight, 4, 1, kSample4,
'<div dir="rtl"><span class="target">\u05d0\u05d1|\u05d2^</span>def</div>',
'C');
testIt(dragLeftToRight, 4, 2, kSample4,
'<div dir="rtl"><span class="target">\u05d0|\u05d1\u05d2^</span>def</div>',
'BC');
testIt(dragLeftToRight, 4, 3, kSample4,
'<div dir="rtl"><span class="target">|\u05d0\u05d1\u05d2^</span>def</div>',
'ABC');
testIt(dragRightToLeft, 4, 1, kSample4,
'<div dir="rtl"><span class="target">^\u05d0|\u05d1\u05d2</span>def</div>',
'A');
testIt(dragRightToLeft, 4, 2, kSample4,
'<div dir="rtl"><span class="target">^\u05d0\u05d1|\u05d2</span>def</div>',
'AB');
testIt(dragRightToLeft, 4, 3, kSample4,
'<div dir="rtl"><span class="target">^\u05d0\u05d1\u05d2|</span>def</div>',
'ABC');
const kSample5 = '\u05d0\u05d1\u05d2d<span class="target">ef</span>';
testIt(dragLeftToRight, 5, 1, kSample5,
'\u05d0\u05d1\u05d2d<span class="target">^e|f</span>', 'e');
testIt(dragLeftToRight, 5, 2, kSample5,
'\u05d0\u05d1\u05d2d<span class="target">^ef|</span>', 'ef');
testIt(dragRightToLeft, 5, 1, kSample5,
'\u05d0\u05d1\u05d2d<span class="target">e|f^</span>', 'f');
testIt(dragRightToLeft, 5, 2, kSample5,
'\u05d0\u05d1\u05d2d<span class="target">|ef^</span>', 'ef');
const kSample6 = 'abc<span class="target">\u05d0\u05d1</span>\u05d2';
testIt(dragLeftToRight, 6, 1, kSample6,
'abc<span class="target">\u05d0|\u05d1^</span>\u05d2', 'B');
testIt(dragLeftToRight, 6, 2, kSample6,
'abc<span class="target">|\u05d0\u05d1^</span>\u05d2', 'AB');
testIt(dragRightToLeft, 6, 1, kSample6,
'abc<span class="target">^\u05d0|\u05d1</span>\u05d2', 'A');
testIt(dragRightToLeft, 6, 2, kSample6,
'abc<span class="target">^\u05d0\u05d1|</span>\u05d2', 'AB');
const kSample7 = 'a\u05e7\u05dc<span class="target">12</span>\u05d9\u05ddd';
testIt(dragLeftToRight, 7, 1, kSample7,
'a\u05e7\u05dc<span class="target">^1|2</span>\u05d9\u05ddd', '1');
testIt(dragLeftToRight, 7, 2, kSample7,
'a\u05e7\u05dc<span class="target">^12|</span>\u05d9\u05ddd', '12');
testIt(dragRightToLeft, 7, 1, kSample7,
'a\u05e7\u05dc<span class="target">1|2^</span>\u05d9\u05ddd', '2');
testIt(dragRightToLeft, 7, 2, kSample7,
'a\u05e7\u05dc<span class="target">|12^</span>\u05d9\u05ddd', '12');
const kSample8 = [
'<div dir="rtl">',
'<span class="target">\u05d0\u05d1\u05d2 123</span>',
'</div>',
].join('');
testIt(dragLeftToRight, 8, 1, kSample8,
'<div dir="rtl"><span class="target">\u05d0\u05d1\u05d2 ^1|23</span></div>',
'1');
testIt(dragLeftToRight, 8, 2, kSample8,
'<div dir="rtl"><span class="target">\u05d0\u05d1\u05d2 ^12|3</span></div>',
'12');
testIt(dragLeftToRight, 8, 3, kSample8,
'<div dir="rtl"><span class="target">\u05d0\u05d1\u05d2 |123^</span></div>',
'123');
testIt(dragLeftToRight, 8, 4, kSample8,
'<div dir="rtl"><span class="target">\u05d0\u05d1\u05d2| 123^</span></div>',
' 123');
testIt(dragLeftToRight, 8, 5, kSample8,
'<div dir="rtl"><span class="target">\u05d0\u05d1|\u05d2 123^</span></div>',
'C 123');
testIt(dragLeftToRight, 8, 6, kSample8,
'<div dir="rtl"><span class="target">\u05d0|\u05d1\u05d2 123^</span></div>',
'BC 123');
testIt(dragLeftToRight, 8, 7, kSample8,
'<div dir="rtl"><span class="target">|\u05d0\u05d1\u05d2 123^</span></div>',
'ABC 123');
testIt(dragRightToLeft, 8, 1, kSample8,
'<div dir="rtl"><span class="target">^\u05d0|\u05d1\u05d2 123</span></div>',
'A');
testIt(dragRightToLeft, 8, 2, kSample8,
'<div dir="rtl"><span class="target">^\u05d0\u05d1|\u05d2 123</span></div>',
'AB');
testIt(dragRightToLeft, 8, 3, kSample8,
'<div dir="rtl"><span class="target">^\u05d0\u05d1\u05d2| 123</span></div>',
'ABC');
testIt(dragRightToLeft, 8, 4, kSample8,
'<div dir="rtl"><span class="target">^\u05d0\u05d1\u05d2 |123</span></div>',
'ABC ');
testIt(dragRightToLeft, 8, 5, kSample8,
'<div dir="rtl"><span class="target">^\u05d0\u05d1\u05d2 12|3</span></div>',
'ABC 12');
testIt(dragRightToLeft, 8, 6, kSample8,
'<div dir="rtl"><span class="target">^\u05d0\u05d1\u05d2 1|23</span></div>',
'ABC 1');
testIt(dragRightToLeft, 8, 7, kSample8,
'<div dir="rtl"><span class="target">^\u05d0\u05d1\u05d2 123|</span></div>',
'ABC 123');
const kSample9 = '<span class="target">\u05d0\u05d1\u05d2 123</span>';
testIt(dragLeftToRight, 9, 1, kSample9,
'<span class="target">\u05d0\u05d1\u05d2 ^1|23</span>', '1');
testIt(dragLeftToRight, 9, 2, kSample9,
'<span class="target">\u05d0\u05d1\u05d2 ^12|3</span>', '12');
testIt(dragLeftToRight, 9, 3, kSample9,
// TODO(editing-dev): This should be ' 123' instead of '123'.
'<span class="target">\u05d0\u05d1\u05d2 ^123|</span>', '123');
testIt(dragLeftToRight, 9, 4, kSample9,
// TODO(editing-dev): This should be 'C 123' instead of ' '.
'<span class="target">\u05d0\u05d1\u05d2| ^123</span>', ' ');
testIt(dragLeftToRight, 9, 5, kSample9,
// TODO(editing-dev): This should be 'BC 123' instead of 'C '.
'<span class="target">\u05d0\u05d1|\u05d2 ^123</span>', 'C ');
testIt(dragLeftToRight, 9, 6, kSample9,
// TODO(editing-dev): This should be 'ABC 123' instead of 'BC '.
'<span class="target">\u05d0|\u05d1\u05d2 ^123</span>', 'BC ');
testIt(dragLeftToRight, 9, 7, kSample9,
// TODO(editing-dev): This should be '' instead of '123'.
'<span class="target">\u05d0\u05d1\u05d2 ^123|</span>', '123');
testIt(dragRightToLeft, 9, 1, kSample9,
'<span class="target">^\u05d0|\u05d1\u05d2 123</span>', 'A');
testIt(dragRightToLeft, 9, 2, kSample9,
'<span class="target">^\u05d0\u05d1|\u05d2 123</span>', 'AB');
testIt(dragRightToLeft, 9, 3, kSample9,
'<span class="target">^\u05d0\u05d1\u05d2| 123</span>', 'ABC');
testIt(dragRightToLeft, 9, 4, kSample9,
// TODO(editing-dev): This should be 'ABC ' instead of ''.
'<span class="target">\u05d0\u05d1\u05d2 123|</span>', '');
testIt(dragRightToLeft, 9, 5, kSample9,
'<span class="target">^\u05d0\u05d1\u05d2 12|3</span>', 'ABC 12');
testIt(dragRightToLeft, 9, 6, kSample9,
'<span class="target">^\u05d0\u05d1\u05d2 1|23</span>', 'ABC 1');
testIt(dragRightToLeft, 9, 7, kSample9,
// TODO(editing-dev): This should be 'ABC 123' instead of ''.
'<span class="target">\u05d0\u05d1\u05d2 |123^</span>', '123');
// For https://bugs.webkit.org/show_bug.cgi?id=73056
const kStyle10 = 'position: absolute; left: 0px; top: 0px; z-index: -5;';
const kSample10 = [
'<div style="position: relative;">',
'a\u05d0\u05d1\u05d2b',
`<div style="${kStyle10}">`,
'a<span class="target">\u05d0\u05d1\u05d2</span>b',
'</div>',
'</div>'
].join('');
testIt(dragLeftToRight, 10, 1, kSample10,
[
'<div style="position: relative;">',
'a\u05d0\u05d1|\u05d2^b',
`<div style="${kStyle10}">`,
'a<span class="target">\u05d0\u05d1\u05d2</span>b',
'</div>',
'</div>'
].join(''), 'C');
testIt(dragLeftToRight, 10, 2, kSample10,
[
'<div style="position: relative;">',
'a\u05d0|\u05d1\u05d2^b',
`<div style="${kStyle10}">`,
'a<span class="target">\u05d0\u05d1\u05d2</span>b',
'</div>',
'</div>'
].join(''), 'BC');
testIt(dragLeftToRight, 10, 3, kSample10,
[
'<div style="position: relative;">',
'a^\u05d0\u05d1\u05d2|b',
`<div style="${kStyle10}">`,
'a<span class="target">\u05d0\u05d1\u05d2</span>b',
'</div>',
'</div>'
].join(''), 'ABC');
testIt(dragRightToLeft, 10, 1, kSample10,
[
'<div style="position: relative;">',
'a^\u05d0|\u05d1\u05d2b',
`<div style="${kStyle10}">`,
'a<span class="target">\u05d0\u05d1\u05d2</span>b',
'</div>',
'</div>'
].join(''), 'A');
testIt(dragRightToLeft, 10, 2, kSample10,
[
'<div style="position: relative;">',
'a^\u05d0\u05d1|\u05d2b',
`<div style="${kStyle10}">`,
'a<span class="target">\u05d0\u05d1\u05d2</span>b',
'</div>',
'</div>'
].join(''), 'AB');
;
testIt(dragRightToLeft, 10, 3, kSample10,
[
'<div style="position: relative;">',
'a|\u05d0\u05d1\u05d2^b',
`<div style="${kStyle10}">`,
'a<span class="target">\u05d0\u05d1\u05d2</span>b',
'</div>',
'</div>'
].join(''), 'ABC');
const kSample11 = '<span class="target" dir="rtl">\u05d0\u05d1\u05d2<br></span>';
testIt(dragLeftToRight, 11, 1, kSample11,
'<span class="target" dir="rtl">\u05d0\u05d1|\u05d2^<br></span>', 'C');
testIt(dragLeftToRight, 11, 2, kSample11,
'<span class="target" dir="rtl">\u05d0|\u05d1\u05d2^<br></span>', 'BC');
testIt(dragLeftToRight, 11, 3, kSample11,
'<span class="target" dir="rtl">^\u05d0\u05d1\u05d2|<br></span>', 'ABC');
testIt(dragRightToLeft, 11, 1, kSample11,
'<span class="target" dir="rtl">^\u05d0|\u05d1\u05d2<br></span>', 'A');
testIt(dragRightToLeft, 11, 2, kSample11,
'<span class="target" dir="rtl">^\u05d0\u05d1|\u05d2<br></span>', 'AB');
testIt(dragRightToLeft, 11, 3, kSample11,
'<span class="target" dir="rtl">|\u05d0\u05d1\u05d2^<br></span>', 'ABC');
</script>