blob: 41db4cc571e8be443e35fcea431c73a28c969924 [file] [log] [blame]
function nodeOfWordBreak(nodeAndOffset)
{
var node = document.getElementById(nodeAndOffset[0]).firstChild;
if (nodeAndOffset.length == 3) {
var childIndex = nodeAndOffset[2];
for (var i = 0; i < childIndex - 1; ++i) {
node = node.nextSibling;
}
}
return node;
}
function positionEqualToWordBreak(position, wordBreak)
{
if (wordBreak.search(',') == -1)
return position.offset == wordBreak;
else {
var nodeAndOffset = wordBreak.split(',');
return position.node == nodeOfWordBreak(nodeAndOffset) && position.offset == nodeAndOffset[1];
}
}
function validateData(positions, wordBreaks)
{
assert_equals(positions.length, wordBreaks.length, 'wordBreaks.length');
for (var i = 0; i < wordBreaks.length - 1; ++i)
assert_true(positionEqualToWordBreak(positions[i], wordBreaks[i]), 'positionEqualToWordBreak of ' + i);
}
const TEST_FOR_CRASH = 'test_for_crash';
function collectWordBreaks(test, searchDirection)
{
if (test.title == TEST_FOR_CRASH)
return TEST_FOR_CRASH;
var title;
if (searchDirection == 'right')
title = test.title.split('|')[0];
else
title = test.title.split('|')[1];
var pattern = /\[(.+?)\]/g;
var result;
var wordBreaks = [];
while ((result = pattern.exec(title)) != null) {
wordBreaks.push(result[1]);
}
if (wordBreaks.length == 0) {
wordBreaks = title.split(' ');
}
return wordBreaks;
}
function moveByWord(sel, test, searchDirection, dir)
{
var prevOffset = internals.visibleSelectionAnchorOffset;
var prevNode = internals.visibleSelectionAnchorNode;
var positions = [];
positions.push({ node: prevNode, offset: prevOffset });
while (1) {
sel.modify('move', searchDirection, 'word');
if (prevNode == internals.visibleSelectionAnchorNode && prevOffset == internals.visibleSelectionAnchorOffset)
break;
prevNode = internals.visibleSelectionAnchorNode;
prevOffset = internals.visibleSelectionAnchorOffset;
positions.push({ node: prevNode, offset: prevOffset });
};
var wordBreaks = collectWordBreaks(test, searchDirection);
if (wordBreaks == TEST_FOR_CRASH)
return;
validateData(positions, wordBreaks);
}
function moveByWordOnEveryChar(sel, test, searchDirection, dir)
{
var wordBreaks = collectWordBreaks(test, searchDirection);
var wordBreakIndex = 1;
var prevOffset = internals.visibleSelectionAnchorOffset;
var prevNode = internals.visibleSelectionAnchorNode;
while (1) {
sel.modify('move', searchDirection, 'word');
if (wordBreaks != TEST_FOR_CRASH) {
if (wordBreakIndex >= wordBreaks.length) {
assert_equals(internals.visibleSelectionAnchorNode, prevNode, 'expected to stay in the same position');
assert_equals(internals.visibleSelectionAnchorOffset, prevOffset, 'expected to stay in the same position');
} else {
assert_true(positionEqualToWordBreak({ node: internals.visibleSelectionAnchorNode, offset: internals.visibleSelectionAnchorOffset }, wordBreaks[wordBreakIndex]), 'positionEqualToWordBreak of ' + wordBreakIndex);
}
}
// Restore position and move by 1 character.
sel.collapse(prevNode, prevOffset);
sel.modify('move', searchDirection, 'character');
if (prevNode == internals.visibleSelectionAnchorNode && prevOffset == internals.visibleSelectionAnchorOffset)
return;
prevNode = internals.visibleSelectionAnchorNode;
prevOffset = internals.visibleSelectionAnchorOffset;
if (wordBreakIndex < wordBreaks.length &&
positionEqualToWordBreak({ node: prevNode, offset: prevOffset }, wordBreaks[wordBreakIndex])) {
++wordBreakIndex;
}
};
}
function moveByWordForEveryPosition(sel, test, dir)
{
// Check ctrl-right-arrow works for every position.
sel.collapse(test, 0);
var direction = 'right';
if (dir == 'rtl')
direction = 'left';
moveByWord(sel, test, direction, dir);
sel.collapse(test, 0);
moveByWordOnEveryChar(sel, test, direction, dir);
sel.modify('move', 'forward', 'lineBoundary');
var position = { node: internals.visibleSelectionAnchorNode, offset: internals.visibleSelectionAnchorOffset };
// Check ctrl-left-arrow works for every position.
if (dir == 'ltr')
direction = 'left';
else
direction = 'right';
moveByWord(sel, test, direction, dir);
sel.collapse(position.node, position.offset);
moveByWordOnEveryChar(sel, test, direction, dir);
}
function runTest() {
div = document.createElement('div');
div.id = 'log';
document.body.appendChild(div);
var tests = document.getElementsByClassName('test_move_by_word');
var sel = getSelection();
for (var testcase of tests) {
test(function () {
assert_own_property(window, 'internals');
if (testcase.className.search('fix_width') != -1) {
var span = document.getElementById('span_size');
var length = span.offsetWidth;
testcase.style.width = length + 'px';
}
if (testcase.getAttribute('dir') == 'ltr')
moveByWordForEveryPosition(sel, testcase, 'ltr');
else
moveByWordForEveryPosition(sel, testcase, 'rtl');
}, testcase.id);
}
}