Commit e17fa44d authored by kalman@chromium.org's avatar kalman@chromium.org
Browse files

2011-02-15 Benjamin Kalman <kalman@chromium.org>

        Reviewed by Ryosuke Niwa.

        Refactor the extend-selection tests to be clearer what they're doing
        https://bugs.webkit.org/show_bug.cgi?id=54429

        This is essentially a cleanup to extend-selection.js and propagation of those changes to the affected tests.

        * editing/selection/extend-selection-character.html:
        * editing/selection/extend-selection-enclosing-block.html:
        * editing/selection/extend-selection-home-end.html:
        * editing/selection/extend-selection-word.html:
        * editing/selection/resources/extend-selection.js:
        (getSerializedSelection):
        (extendSelectionWithinBlock):
        (extendSelectionToEnd):
        (fold):
        (logMismatchingPositions):
        (extendAndLogSelection):
        (extendAndLogSelectionWithinBlock):
        (extendAndLogSelectionToEnd):
        (runSelectionTestsWithGranularity):
        (getTestNodeContainer):
        (createNode):
        (createCharAndWordNodes):
        (createEnclosingBlockNodes):
        (createHomeEndNodes):
        (createAllNodes):
        (.window.onload):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@78565 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent a8d6b941
2011-02-15 Benjamin Kalman <kalman@chromium.org>
Reviewed by Ryosuke Niwa.
Refactor the extend-selection tests to be clearer what they're doing
https://bugs.webkit.org/show_bug.cgi?id=54429
This is essentially a cleanup to extend-selection.js and propagation of those changes to the affected tests.
* editing/selection/extend-selection-character.html:
* editing/selection/extend-selection-enclosing-block.html:
* editing/selection/extend-selection-home-end.html:
* editing/selection/extend-selection-word.html:
* editing/selection/resources/extend-selection.js:
(getSerializedSelection):
(extendSelectionWithinBlock):
(extendSelectionToEnd):
(fold):
(logMismatchingPositions):
(extendAndLogSelection):
(extendAndLogSelectionWithinBlock):
(extendAndLogSelectionToEnd):
(runSelectionTestsWithGranularity):
(getTestNodeContainer):
(createNode):
(createCharAndWordNodes):
(createEnclosingBlockNodes):
(createHomeEndNodes):
(createAllNodes):
(.window.onload):
2011-02-15 Philippe Normand <pnormand@igalia.com>
 
Reviewed by Eric Carlson.
......@@ -8,16 +8,7 @@
<body>
<pre id="console"></pre>
<script>
if (window.layoutTestController) {
layoutTestController.dumpAsText();
var tests = createTestNodes("char-and-word");
var sel = getSelection();
log("\n\n\nExtending by character\n");
testExtendingSelection(tests, sel, "character", 0);
}
log("\n\n\nExtending by character\n");
runSelectionTestsWithGranularity(createCharAndWordNodes(), "character");
</script>
</body>
......@@ -8,30 +8,24 @@
<body>
<pre id="console"></pre>
<script>
function testExtendingSelectionForEnclosingBlock(tests, sel, granularity)
function runSelectionTestsWithGranularityForEnclosingBlock(testNodes, granularity)
{
for (var i = 0; i < tests.length; ++i) {
log("Test " + (i + 1) + ", LTR:\n Extending right: ");
sel.setPosition(tests[i], 0);
var ltrRightPos = extendingSelection(sel, "right", granularity, 1);
for (var i = 0; i < testNodes.length; ++i) {
getSelection().setPosition(testNodes[i], 0);
log("Test " + (i + 1) + ", LTR:\n");
log(" Extending right: ");
extendAndLogSelectionWithinBlock("right", granularity);
log(" Extending left: ");
var ltrLeftPos = extendingSelection(sel, "left", granularity, 1);
extendAndLogSelectionWithinBlock("left", granularity);
}
}
if (window.layoutTestController) {
layoutTestController.dumpAsText();
tests = createTestNodes("enclosing-block");
sel = getSelection();
log("\n\n\nExtending by character\n");
testExtendingSelectionForEnclosingBlock(tests, sel, "character", 1);
log("\n\n\n\n\nExtending by word\n");
testExtendingSelectionForEnclosingBlock(tests, sel, "word", 1);
}
log("\n\n\nExtending by character\n");
runSelectionTestsWithGranularityForEnclosingBlock(createEnclosingBlockNodes(), "character");
log("\n\n\n\n\nExtending by word\n");
runSelectionTestsWithGranularityForEnclosingBlock(createEnclosingBlockNodes(), "word");
</script>
</body>
......@@ -8,36 +8,31 @@
<body>
<pre id="console"></pre>
<script>
function testExtendingLineBoundary(tests, sel)
function testExtendingLineBoundary(testNodes)
{
for (var i = 0; i < tests.length; ++i) {
tests[i].style.direction = "ltr";
log("Test " + (i + 1) + ", LTR:\n Extending forward: ");
sel.setPosition(tests[i], 0);
var ltrRightPos = extendingSelection(sel, "forward", "lineBoundary", 0);
log(" Extending backward: ");
var ltrLeftPos = extendingSelection(sel, "backward", "lineBoundary", 0);
tests[i].style.direction = "rtl";
log("Test " + (i + 1) + ", RTL:\n Extending forward: ");
sel.setPosition(tests[i], 0);
var ltrRightPos = extendingSelection(sel, "forward", "lineBoundary", 0);
function extendToEndAndBack(node)
{
getSelection().setPosition(node, 0);
log(" Extending forward: ");
extendAndLogSelectionToEnd("forward", "lineBoundary");
log(" Extending backward: ");
var ltrLeftPos = extendingSelection(sel, "backward", "lineBoundary", 0);
extendAndLogSelectionToEnd("backward", "lineBoundary");
}
}
if (window.layoutTestController) {
layoutTestController.dumpAsText();
for (var i = 0; i < testNodes.length; ++i) {
var node = testNodes[i];
tests = createTestNodes(); // all
var sel = getSelection();
log("\n\n\nExtending by lineBoundary\n");
testExtendingLineBoundary(tests, sel);
log("Test " + (i + 1) + ", LTR:\n");
node.style.direction = "ltr";
extendToEndAndBack(node);
log("Test " + (i + 1) + ", RTL:\n");
node.style.direction = "rtl";
extendToEndAndBack(node);
}
}
log("\n\n\nExtending by lineBoundary\n");
testExtendingLineBoundary(createAllNodes());
</script>
</body>
......@@ -8,16 +8,7 @@
<body>
<pre id="console"></pre>
<script>
if (window.layoutTestController) {
layoutTestController.dumpAsText();
var tests = createTestNodes('char-and-word');
var sel = getSelection();
log("\n\n\n\n\nExtending by word\n");
testExtendingSelection(tests, sel, "word", 0);
}
log("\n\n\n\n\nExtending by word\n");
runSelectionTestsWithGranularity(createCharAndWordNodes(), "word");
</script>
</body>
......@@ -3,60 +3,47 @@ function log(message)
document.getElementById("console").appendChild(document.createTextNode(message));
}
function positionsExtendingInDirectionForEnclosingBlock(sel, direction, granularity)
function getSerializedSelection()
{
return {
node: getSelection().extentNode,
begin: getSelection().baseOffset,
end: getSelection().extentOffset
};
}
function extendSelectionWithinBlock(direction, granularity)
{
var positions = [];
var ltrNum;
var rtlNum;
if (granularity == "character") {
ltrNum = 5;
} else {
ltrNum = 1;
}
if (granularity == "character") {
rtlNum = 15;
} else {
rtlNum = 3;
}
var index = 0;
while (index <= ltrNum) {
positions.push({ node: sel.extentNode, begin: sel.baseOffset, end: sel.extentOffset });
sel.modify("extend", direction, granularity);
++index;
}
var antiDirection = direction;
if (antiDirection == 'left') {
antiDirection = "right";
} else if (antiDirection = 'right') {
antiDirection = "left";
var leftIterations = (granularity === "character") ? 5 : 1;
var rightIterations = (granularity === "character") ? 15 : 3;
for (var index = 0; index <= leftIterations; ++index) {
positions.push(getSerializedSelection());
getSelection().modify("extend", direction, granularity);
}
index = 0;
while (index <= rtlNum) {
positions.push({ node: sel.extentNode, begin: sel.baseOffset, end: sel.extentOffset });
sel.modify("extend", antiDirection, granularity);
++index;
for (var index = 0; index <= rightIterations; ++index) {
positions.push(getSerializedSelection());
getSelection().modify("extend", (direction === "left") ? "right" : "left", granularity);
}
var index = 0;
while (index < ltrNum) {
positions.push({ node: sel.extentNode, begin: sel.baseOffset, end: sel.extentOffset });
sel.modify("extend", direction, granularity);
++index;
for (var index = 0; index < leftIterations; ++index) {
positions.push(getSerializedSelection());
getSelection().modify("extend", direction, granularity);
}
return positions;
}
function positionsExtendingInDirection(sel, direction, granularity)
function extendSelectionToEnd(direction, granularity)
{
var positions = [];
while (true) {
positions.push({ node: sel.extentNode, begin: sel.baseOffset, end: sel.extentOffset });
sel.modify("extend", direction, granularity);
if (positions[positions.length - 1].node == sel.extentNode && positions[positions.length - 1].end == sel.extentOffset)
break;
};
do {
var position = getSerializedSelection();
positions.push(position);
getSelection().modify("extend", direction, granularity);
} while (position.node !== getSerializedSelection().node || position.end !== getSerializedSelection().end);
return positions;
}
......@@ -68,7 +55,7 @@ function fold(string)
if (char >= 0x05d0)
char -= 0x058f;
else if (char == 10) {
result += "\\n";
result +="\\n";
continue;
}
result += String.fromCharCode(char);
......@@ -91,177 +78,182 @@ function logPositions(positions)
log("]");
}
function checkReverseOrder(inputPositions, inputReversePositions)
function logMismatchingPositions(positions, comparisonPositions)
{
var positions = inputPositions.slice();
var reversePositions = inputReversePositions.slice();
var mismatch = (positions.length != reversePositions.length);
if (mismatch)
log("WARNING: positions should be the same, but the length are not the same " + positions.length + " vs. " + reversePositions.length + "\n");
while (!mismatch) {
var pos = positions.pop();
if (!pos)
break;
var reversePos = reversePositions.shift();
if (pos.node != reversePos.node) {
mismatch = true;
log("WARNING: positions should be the reverse, but node are not the reverse\n");
}
if (pos.begin != reversePos.begin) {
mismatch = true;
log("WARNING: positions should be the same, but begin are not " + pos.begin + " vs. " + reversePos.begin + "\n");
}
if (pos.end != reversePos.end) {
mismatch = true;
log("WARNING: positions should be the same, but end are not " + pos.end + " vs. " + reversePos.end + "\n");
}
if (positions.length !== comparisonPositions.length) {
log("WARNING: positions should be the same, but the length are not the same " + positions.length + " vs. " + samePositions.length + "\n");
return;
}
}
for (var i = 0; i < positions.length; ++i) {
var pos = positions[i];
var comparison = comparisonPositions[i];
function checkSameOrder(inputPositions, inputSamePositions)
{
var positions = inputPositions.slice();
var samePositions = inputSamePositions.slice();
var mismatch = positions.length != samePositions.length;
if (mismatch)
log("WARNING: positions should be the same, but the length are not the same " + positions.length + " vs. " + samePositions.length + "\n");
while (!mismatch) {
var pos = positions.pop();
if (!pos)
break;
var samePos = samePositions.pop();
if (pos.node != samePos.node) {
mismatch = true;
if (pos.node !== comparison.node)
log("WARNING: positions should be the same, but node are not the same\n");
}
if (pos.begin != samePos.begin) {
mismatch = true;
log("WARNING: positions should be the same, but begin are not the same " + pos.begin + " vs. " + samePos.begin + "\n");
}
if (pos.end != samePos.end) {
mismatch = true;
log("WARNING: positions should be the same, but end are not the same " + pos.end + " vs. " + samePos.end + "\n");
}
}
if (pos.begin !== comparison.begin)
log("WARNING: positions should be the same, but begin are not the same " + pos.begin + " vs. " + comparison.begin + "\n");
if (pos.end !== comparison.end)
log("WARNING: positions should be the same, but end are not the same " + pos.end + " vs. " + comparison.end + "\n");
}
}
function extendingSelection(sel, direction, granularity, option)
function extendAndLogSelection(functionToExtendSelection, direction, granularity)
{
var positions;
if (option == 0) {
positions = positionsExtendingInDirection(sel, direction, granularity);
} else {
positions = positionsExtendingInDirectionForEnclosingBlock(sel, direction, granularity);
}
var positions = functionToExtendSelection(direction, granularity);
logPositions(positions);
log("\n");
return positions;
}
function testExtendingSelection(tests, sel, granularity)
function extendAndLogSelectionWithinBlock(direction, granularity)
{
for (var i = 0; i < tests.length; ++i) {
tests[i].style.direction = "ltr";
log("Test " + (i + 1) + ", LTR:\n Extending right: ");
sel.setPosition(tests[i], 0);
var ltrRightPos = extendingSelection(sel, "right", granularity, 0);
return extendAndLogSelection(extendSelectionWithinBlock, direction, granularity);
}
function extendAndLogSelectionToEnd(direction, granularity)
{
return extendAndLogSelection(extendSelectionToEnd, direction, granularity);
}
function runSelectionTestsWithGranularity(testNodes, granularity)
{
for (var i = 0; i < testNodes.length; ++i) {
var testNode = testNodes[i];
testNode.style.direction = "ltr";
log("Test " + (i + 1) + ", LTR:\n");
log(" Extending right: ");
getSelection().setPosition(testNode);
var ltrRightPos = extendAndLogSelectionToEnd("right", granularity);
log(" Extending left: ");
var ltrLeftPos = extendingSelection(sel, "left", granularity, 0);
var ltrLeftPos = extendAndLogSelectionToEnd("left", granularity);
log(" Extending forward: ");
sel.setPosition(tests[i], 0);
var ltrForwardPos = extendingSelection(sel, "forward", granularity, 0);
getSelection().setPosition(testNode);
var ltrForwardPos = extendAndLogSelectionToEnd("forward", granularity);
log(" Extending backward: ");
var ltrBackwardPos = extendingSelection(sel, "backward", granularity, 0);
var ltrBackwardPos = extendAndLogSelectionToEnd("backward", granularity);
tests[i].style.direction = "rtl";
testNode.style.direction = "rtl";
log("Test " + (i + 1) + ", RTL:\n Extending left: ");
sel.setPosition(tests[i], 0);
var rtlLeftPos = extendingSelection(sel, "left", granularity, 0);
log("Test " + (i + 1) + ", RTL:\n");
log(" Extending left: ");
getSelection().setPosition(testNode);
var rtlLeftPos = extendAndLogSelectionToEnd("left", granularity);
log(" Extending right: ");
var rtlRightPos = extendingSelection(sel, "right", granularity, 0);
var rtlRightPos = extendAndLogSelectionToEnd("right", granularity);
log(" Extending forward: ");
sel.setPosition(tests[i], 0);
var rtlForwardPos = extendingSelection(sel, "forward", granularity, 0);
getSelection().setPosition(testNode);
var rtlForwardPos = extendAndLogSelectionToEnd("forward", granularity);
log(" Extending backward: ");
var rtlBackwardPos = extendingSelection(sel, "backward", granularity, 0);
var rtlBackwardPos = extendAndLogSelectionToEnd("backward", granularity);
// validations
log("\n\n validating ltrRight and ltrLeft\n");
if (granularity == "character")
checkReverseOrder(ltrRightPos, ltrLeftPos);
logMismatchingPositions(ltrRightPos, ltrLeftPos.slice().reverse());
// Order might not be reversed for extending by word because the 1-point shift by space.
log(" validating ltrRight and ltrForward\n");
checkSameOrder(ltrRightPos, ltrForwardPos);
logMismatchingPositions(ltrRightPos, ltrForwardPos);
log(" validating ltrForward and rtlForward\n");
checkSameOrder(ltrForwardPos, rtlForwardPos);
logMismatchingPositions(ltrForwardPos, rtlForwardPos);
log(" validating ltrLeft and ltrBackward\n");
checkSameOrder(ltrLeftPos, ltrBackwardPos);
logMismatchingPositions(ltrLeftPos, ltrBackwardPos);
log(" validating ltrBackward and rtlBackward\n");
checkSameOrder(ltrBackwardPos, rtlBackwardPos);
logMismatchingPositions(ltrBackwardPos, rtlBackwardPos);
log(" validating ltrRight and rtlLeft\n");
checkSameOrder(ltrRightPos, rtlLeftPos);
logMismatchingPositions(ltrRightPos, rtlLeftPos);
log(" validating ltrLeft and rtlRight\n");
checkSameOrder(ltrLeftPos, rtlRightPos);
logMismatchingPositions(ltrLeftPos, rtlRightPos);
log("\n\n");
}
}
var data = [
['char-and-word', null, '\nabc &#1488;&#1489;&#1490; xyz &#1491;&#1492;&#1493; def\n'],
['char-and-word', null, '\n&#1488;&#1489;&#1490; xyz &#1491;&#1492;&#1493; def &#1494;&#1495;&#1496;\n'],
['char-and-word', null, '\n&#1488;&#1489;&#1490; &#1491;&#1492;&#1493; &#1488;&#1489;&#1490;\n'],
['char-and-word', null, '\nabc efd dabeb\n'],
['char-and-word', null, 'Lorem <span style="direction: rtl">ipsum dolor sit</span> amet'],
['char-and-word', null, 'Lorem <span dir="rtl">ipsum dolor sit</span> amet'],
['char-and-word', null, 'Lorem <span style="direction: ltr">ipsum dolor sit</span> amet'],
['char-and-word', null, 'Lorem <span dir="ltr">ipsum dolor sit</span> amet'],
['enclosing-block', null, 'Lorem <div dir="rtl">ipsum dolor sit</div> amett'],
['home-end', null, 'Lorem <span style="direction: ltr">ipsum dolor sit</span> amet'],
['home-end', null, 'Lorem <span style="direction: ltr">ipsum dolor<div > just a test</div> sit</span> amet'],
['home-end', null, 'Lorem <span dir="ltr">ipsum dolor sit</span> amet'],
['home-end', null, 'Lorem <div dir="ltr">ipsum dolor sit</div> amet'],
['home-end', null, '\n Just\n <span>testing רק</span>\n בודק\n'],
['home-end', null, '\n Just\n <span>testing what</span>\n ever\n'],
['home-end', null, 'car means &#1488;&#1489;&#1490;.'],
['home-end', null, '&#x202B;car &#1491;&#1492;&#1493; &#1488;&#1489;&#1490;.&#x202c;'],
['home-end', null, 'he said "&#x202B;car &#1491;&#1492;&#1493; &#1488;&#1489;&#1490;&#x202c;."'],
['home-end', null, '&#1494;&#1495;&#1496; &#1497;&#1498;&#1499; &#1500;&#1501;&#1502; \'&#x202a;he said "&#x202B;car &#1491;&#1492;&#1493; &#1488;&#1489;&#1490;&#x202c;"&#x202c;\'?'],
['home-end', null, '&#1488;&#1489;&#1490; abc &#1491;&#1492;&#1493;<br />edf &#1494;&#1495;&#1496; abrebg'],
['home-end', 'line-break:before-white-space; width:5em', 'abcdefg abcdefg abcdefg a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg '],
['home-end', 'line-break:after-white-space; width:5em', 'abcdefg abcdefg abcdefg a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg ']
];
function createTestNodes(name) {
var nodes = [];
for (var i = 0; i < data.length; i++) {
if (name && data[i][0] != name)
continue;
var style = data[i][1];
var text = data[i][2];
var div = document.createElement('div');
div.contentEditable = true;
if (style)
div.setAttribute('style', style);
div.innerHTML = text;
document.body.insertBefore(div, document.getElementById('console'));
nodes.push(div);
function getTestNodeContainer()
{
var tests = document.getElementById("tests");
if (!tests) {
tests = document.createElement("div");
tests.id = "tests";
document.body.insertBefore(tests, document.getElementById("console"));
}
return tests;
}
window.onload = function() {
for (var i = 0; i < nodes.length; i++)
nodes[i].parentNode.removeChild(nodes[i]);
}
function createNode(content, style)
{
var node = document.createElement("div");
node.innerHTML = content;
node.contentEditable = true;
if (style)
node.setAttribute("style", style);
getTestNodeContainer().appendChild(node);
return node;
}
return nodes;
function createCharAndWordNodes()
{
return [
createNode('\nabc &#1488;&#1489;&#1490; xyz &#1491;&#1492;&#1493; def\n'),
createNode('\n&#1488;&#1489;&#1490; xyz &#1491;&#1492;&#1493; def &#1494;&#1495;&#1496;\n'),
createNode('\n&#1488;&#1489;&#1490; &#1491;&#1492;&#1493; &#1488;&#1489;&#1490;\n'),
createNode('\nabc efd dabeb\n'),
createNode('Lorem <span style="direction: rtl">ipsum dolor sit</span> amet'),
createNode('Lorem <span dir="rtl">ipsum dolor sit</span> amet'),
createNode('Lorem <span style="direction: ltr">ipsum dolor sit</span> amet'),
createNode('Lorem <span dir="ltr">ipsum dolor sit</span> amet')
];
}
function createEnclosingBlockNodes()
{
return [
createNode('Lorem <div dir="rtl">ipsum dolor sit</div> amett')
];
}
function createHomeEndNodes()
{
return [
createNode('Lorem <span style="direction: ltr">ipsum dolor sit</span> amet'),
createNode('Lorem <span style="direction: ltr">ipsum dolor<div > just a test</div> sit</span> amet'),
createNode('Lorem <span dir="ltr">ipsum dolor sit</span> amet'),
createNode('Lorem <div dir="ltr">ipsum dolor sit</div> amet'),
createNode('\n Just\n <span>testing רק</span>\n בודק\n'),
createNode('\n Just\n <span>testing what</span>\n ever\n'),
createNode('car means &#1488;&#1489;&#1490;.'),
createNode('&#x202B;car &#1491;&#1492;&#1493; &#1488;&#1489;&#1490;.&#x202c;'),
createNode('he said "&#x202B;car &#1491;&#1492;&#1493; &#1488;&#1489;&#1490;&#x202c;."'),
createNode('&#1494;&#1495;&#1496; &#1497;&#1498;&#1499; &#1500;&#1501;&#1502; \'&#x202a;he said ' +
'"&#x202B;car &#1491;&#1492;&#1493; &#1488;&#1489;&#1490;&#x202c;"&#x202c;\'?'),
createNode('&#1488;&#1489;&#1490; abc &#1491;&#1492;&#1493;<br />edf &#1494;&#1495;&#1496; abrebg'),
createNode('abcdefg abcdefg abcdefg a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg ',
'line-break:before-white-space; width:5em'),
createNode('abcdefg abcdefg abcdefg a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg ',
'line-break:after-white-space; width:5em')
];