+function positionPassWordBreak(position, wordBreak, searchDirection)
+{
+ // Hack for space collapse.
+ // sel.modify("move", dir, "character") not reach multi-space.
+ var node = position.node;
+ if (node.parentNode.id == "multispace") {
+ if (searchDirection == "right" && position.offset >= wordBreak
+ || searchDirection == "left" && position.offset <= wordBreak)
+ return true;
+ }
+ return false;
+}
+
+function moveByWordOnEveryChar(sel, test, searchDirection, dir)
+{
+ collectWordBreaks(test, searchDirection);
+ var wordBreakIndex = 1;
+ var prevOffset = sel.anchorOffset;
+ var prevNode = sel.anchorNode;
+
+ while (1) {
+ var positions = [];
+ positions.push({ node: sel.anchorNode, offset: sel.anchorOffset });
+ sel.modify("move", searchDirection, "-webkit-visual-word");
+
+ var position = { node: sel.anchorNode, offset: sel.anchorOffset };
+
+ if (wordBreakIndex >= wordBreaks.length) {
+ if (sel.anchorNode != prevNode || sel.anchorOffset != prevOffset) {
+ positions.push(position);
+ logPositions(positions);
+ log(" FAIL expected to stay in the same position\n");
+ }
+ } else if (!positionEqualToWordBreak(position, wordBreaks[wordBreakIndex])) {
+ positions.push(position);
+ logPositions(positions);
+ log(" FAIL expected ");
+ var withNodeData = logWordBreak(wordBreakIndex, true);
+ if (withNodeData)
+ log("]");
+ log("\n");
+ }
+
+ // Restore position and move by 1 character.
+ sel.setPosition(prevNode, prevOffset);
+ sel.modify("move", searchDirection, "character");
+ if (prevNode == sel.anchorNode && prevOffset == sel.anchorOffset)
+ break;
+
+ position = { node: sel.anchorNode, offset: sel.anchorOffset };
+ if (wordBreakIndex < wordBreaks.length
+ && (positionEqualToWordBreak(position, wordBreaks[wordBreakIndex])
+ || positionPassWordBreak(position, wordBreaks[wordBreakIndex], searchDirection)))
+ ++wordBreakIndex;
+
+ prevNode = sel.anchorNode;
+ prevOffset = sel.anchorOffset;
+ };
+}
+