4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
7 -webkit-user-modify: read-write;
9 border: 1px dashed lightblue;
10 margin: 4px 4px 4px 24px;
12 font-family: Lucida Grande;
13 counter-increment: test-number;
15 div.test:before { content: counter(test-number); position: absolute; left: 8px; font-size: x-small; text-align: right; width: 20px; }
16 div.test span { background-color: #def; }
17 div.test img { width: 1em; height: 1em; background-color: lightgreen; }
18 div.test img + img { background-color: lightblue; }
19 div.test div { border: 1px dashed pink; padding: 3px; height: 2em; }
20 test_move_by_word {display: none;}
27 messages.push(message);
32 document.getElementById("console").appendChild(document.createTextNode(messages.join("")));
35 function caretCoordinates()
37 if (!window.textInputController)
38 return { x: 0, y :0 };
39 var caretRect = textInputController.firstRectForCharacterRange(textInputController.selectedRange()[0], 0);
40 return { x: caretRect[0], y: caretRect[1] };
47 for (var i = 0; i < string.length; ++i) {
48 var char = string.charCodeAt(i);
51 else if (char == 10) {
55 result += String.fromCharCode(char);
60 function logPositions(positions)
62 for (var i = 0; i < positions.length; ++i) {
64 if (positions[i].node != positions[i - 1].node)
68 if (!i || positions[i].node != positions[i - 1].node)
69 log((positions[i].node instanceof Text ? '"' + fold(positions[i].node.data) + '"' : "<" + positions[i].node.tagName + ">") + "[");
70 log(positions[i].offset);
77 function validateData(positions)
79 for (var i = 0; i < wordBreaks.length - 1; ++i) {
80 if (positions[i].offset != wordBreaks[i + 1]) {
84 if (i != wordBreaks.length - 1 && positions[i] != wordBreaks[i]) {
85 log(" FAIL expected: [");
86 for (var i = 1; i < wordBreaks.length; ++i) {
87 log(wordBreaks[i] + ", ");
89 log(wordBreaks[wordBreaks.length - 1] + "]");
93 function collectWordBreaks(test, searchDirection)
95 if (searchDirection == "right") {
96 if (test.getAttribute("dir") == 'ltr')
97 wordBreaks = test.title.split("|")[0].split(" ");
99 wordBreaks = test.title.split("|")[1].split(" ");
101 if (test.getAttribute("dir") == 'ltr')
102 wordBreaks = test.title.split("|")[1].split(" ");
104 wordBreaks = test.title.split("|")[0].split(" ");
108 function moveByWord(sel, test, searchDirection, dir)
110 log("Move " + searchDirection + " by one word\n");
111 var prevOffset = sel.anchorOffset;
112 var node = sel.anchorNode;
113 collectWordBreaks(test, searchDirection);
114 sel.setPosition(node, wordBreaks[0]);
116 for (var index = 1; index < wordBreaks.length; ++index) {
117 sel.modify("move", searchDirection, "-webkit-visual-word");
118 positions.push({ node: sel.anchorNode, offset: sel.anchorOffset, point: caretCoordinates() });
119 sel.setPosition(node, wordBreaks[index]);
121 sel.modify("move", searchDirection, "-webkit-visual-word");
122 positions.push({ node: sel.anchorNode, offset: sel.anchorOffset, point: caretCoordinates() });
123 logPositions(positions);
124 validateData(positions);
128 function moveByWordForEveryPosition(sel, test, dir)
130 // Check ctrl-right-arrow works for every position.
131 sel.setPosition(test, 0);
132 var direction = "right";
135 moveByWord(sel, test, direction, dir);
136 // Check ctrl-left-arrow works for every position.
141 moveByWord(sel, test, direction, dir);
144 function runMoveLeftRight(tests, unit)
146 var sel = getSelection();
147 for (var i = 0; i < tests.length; ++i) {
148 var positionsMovingRight;
149 var positionsMovingLeft;
151 if (tests[i].getAttribute("dir") == 'ltr')
153 log("Test " + (i + 1) + ", LTR:\n");
154 moveByWordForEveryPosition(sel, tests[i], "ltr");
156 log("Test " + (i + 1) + ", RTL:\n");
157 moveByWordForEveryPosition(sel, tests[i], "rtl");
161 document.getElementById("testMoveByWord").style.display = "none";
165 log("\n======== Move By Word ====\n");
166 var tests = document.getElementsByClassName("test_move_by_word");
167 runMoveLeftRight(tests, "word");
170 onload = function() {
178 if (window.layoutTestController)
179 layoutTestController.dumpAsText();
183 <div id="testMoveByWord">
184 <!-- The numbers put in title are starting word boundaries.
185 The numbers printed out in the output are ending word boundaries. -->
186 <div dir=ltr class="test_move_by_word" title="0 4 8 12 16 19|19 16 12 8 4 0" contenteditable>abc def hij opq rst</div>
187 <div dir=rtl class="test_move_by_word" title="0 15 11 7 3 19|19 3 7 11 15 0" contenteditable>abc def hij opq rst</div>
188 <div dir=ltr class="test_move_by_word" title="0 15 11 7 3 19|19 3 7 11 15 0" contenteditable>ששש נננ בבב גגג קקק</div>
189 <div dir=rtl class="test_move_by_word" title="0 4 8 12 16 19|19 16 12 8 4 0" contenteditable>ששש נננ בבב גגג קקק</div>
190 <div dir=ltr class="test_move_by_word" title="0 4 8 11 16 20 23|23 20 16 11 8 4 0" contenteditable>abc def שנב סטז uvw xyz</div>
191 <div dir=rtl class="test_move_by_word" title="0 3 8 12 16 19 23|23 19 16 12 8 3 0" contenteditable>abc def שנב סטז uvw xyz</div>
192 <div dir=ltr class="test_move_by_word" title="0 4 8 11|11 8 4 0" contenteditable>שנב abc סטז</div>
193 <div dir=rtl class="test_move_by_word" title="0 4 8 11|11 8 4 0" contenteditable>שנב abc סטז</div>
196 <pre id="console"></pre>