2011-04-26 Ryosuke Niwa <rniwa@webkit.org>
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 26 Apr 2011 16:40:12 +0000 (16:40 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 26 Apr 2011 16:40:12 +0000 (16:40 +0000)
        Reviewed by Dan Bernstein.

        [RTL] Arabic/AB - after typing a date, cursors doesn't go back
        https://bugs.webkit.org/show_bug.cgi?id=49111

        Added a test to move left and right within Arabic numerals and Arabic letters.

        We still fail to set the position offset properly when we moving to the left from before B
        to before A in "ABC123" (logical order) in a LTR block where ABC and 123 are Arabic letters
        and numerals respectively. This bug is to be fixed in the followup bugs.

        * editing/selection/move-left-right-expected.txt:
        * editing/selection/move-left-right.html:
2011-04-26  Ryosuke Niwa  <rniwa@webkit.org>

        Reviewed by Dan Bernstein.

        [RTL] Arabic/AB - after typing a date, cursors doesn't go back
        https://bugs.webkit.org/show_bug.cgi?id=49111

        Even when the offset corresponds to a position visually left of the box
        and there aren't any inline boxes on the left, the previous/next position
        may still correspond to some position in the same line.

        The bug was caused by our ignoring such cases. Fixed the bug by comparing
        previous/next position's inline box to the current box. If they match,
        then we stay on the same position because moving to the left visually at
        the left edge should not result in a position on the same line.

        Also fixed a bug that WebKit uses offsets that are not extrema when moved to
        the left edge or to the right edge, and a bug that WebKit could not move to
        the left from 12^3 CBA abc to 123 C^BA abc (there is no offset between 3 and C).

        Test cases are added to editing/selection/move-left-right.html

        * editing/VisiblePosition.cpp:
        (WebCore::VisiblePosition::leftVisuallyDistinctCandidate):
        (WebCore::VisiblePosition::rightVisuallyDistinctCandidate):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@84919 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/editing/selection/move-left-right-expected.txt
LayoutTests/editing/selection/move-left-right.html
Source/WebCore/ChangeLog
Source/WebCore/editing/VisiblePosition.cpp

index 189b2d5..4d5b70b 100644 (file)
@@ -1,3 +1,19 @@
+2011-04-26  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Reviewed by Dan Bernstein.
+
+        [RTL] Arabic/AB - after typing a date, cursors doesn't go back
+        https://bugs.webkit.org/show_bug.cgi?id=49111
+
+        Added a test to move left and right within Arabic numerals and Arabic letters.
+
+        We still fail to set the position offset properly when we moving to the left from before B
+        to before A in "ABC123" (logical order) in a LTR block where ABC and 123 are Arabic letters
+        and numerals respectively. This bug is to be fixed in the followup bugs.
+
+        * editing/selection/move-left-right-expected.txt:
+        * editing/selection/move-left-right.html:
+
 2011-04-26  Stephen White  <senorblanco@chromium.org>
 
         Unreviewed; chromium test_expectations update.
 2011-04-26  Stephen White  <senorblanco@chromium.org>
 
         Unreviewed; chromium test_expectations update.
index f2500a5..3b651ae 100644 (file)
@@ -47,196 +47,214 @@ Test 8, RTL:
   Moving left: "\n        ABCabcdef\n    "[9, 10, 11, 12, 17, 16, 15, 14, 13, 18]
   Moving right:  "\n        ABCabcdef\n    "[18, 13, 14, 15, 16, 17, 12, 11, 10, 9]
 Test 9, LTR:
   Moving left: "\n        ABCabcdef\n    "[9, 10, 11, 12, 17, 16, 15, 14, 13, 18]
   Moving right:  "\n        ABCabcdef\n    "[18, 13, 14, 15, 16, 17, 12, 11, 10, 9]
 Test 9, LTR:
+  Moving right: "123ABC"[0, 5, 4, 1, 2, 6]
+  Moving left:  "123ABC"[6, 2, 1, 4, 5, 0]
+Test 9, RTL:
+  Moving left: "123ABC"[0, 2, 1, 3, 4, 5, 6]
+  Moving right:  "123ABC"[6, 5, 4, 3, 1, 2, 0]
+Test 10, LTR:
+  Moving right: "ABC123"[0, 4, 5, 2, 1, 6]
+  Moving left:  "ABC123"[6, 1, 2, 5, 4, 0]
+Test 10, RTL:
+  Moving left: "ABC123"[0, 1, 2, 3, 5, 4, 6]
+  Moving right:  "ABC123"[6, 4, 5, 3, 2, 1, 0]
+Test 11, LTR:
   Moving right: "abc"[0, 1, 2, 3], "ABCdef\n    "[2, 1, 3, 4, 5, 6]
   Moving left:  "ABCdef\n    "[6, 5, 4, 3, 1, 2], "abc"[3, 2, 1, 0]
   Moving right: "abc"[0, 1, 2, 3], "ABCdef\n    "[2, 1, 3, 4, 5, 6]
   Moving left:  "ABCdef\n    "[6, 5, 4, 3, 1, 2], "abc"[3, 2, 1, 0]
-Test 9, RTL:
+Test 11, RTL:
   Moving left: "abc"[0, 2, 1, 3], "ABCdef\n    "[1, 2, 3, 5, 4, 6]
   Moving right:  "ABCdef\n    "[6, 4, 5, 3, 2, 1], "abc"[3, 1, 2, 0]
   Moving left: "abc"[0, 2, 1, 3], "ABCdef\n    "[1, 2, 3, 5, 4, 6]
   Moving right:  "ABCdef\n    "[6, 4, 5, 3, 2, 1], "abc"[3, 1, 2, 0]
-Test 10, LTR:
+Test 12, LTR:
   Moving right: "ABC"[0, 2, 1, 3], "abcDEF\n    "[1, 2, 3, 5, 4, 6]
   Moving left:  "abcDEF\n    "[6, 4, 5, 3, 2, 1], "ABC"[3, 1, 2, 0]
   Moving right: "ABC"[0, 2, 1, 3], "abcDEF\n    "[1, 2, 3, 5, 4, 6]
   Moving left:  "abcDEF\n    "[6, 4, 5, 3, 2, 1], "ABC"[3, 1, 2, 0]
-Test 10, RTL:
+Test 12, RTL:
   Moving left: "ABC"[0, 1, 2, 3], "abcDEF\n    "[2, 1, 3, 4, 5, 6]
   Moving right:  "abcDEF\n    "[6, 5, 4, 3, 1, 2], "ABC"[3, 2, 1, 0]
   Moving left: "ABC"[0, 1, 2, 3], "abcDEF\n    "[2, 1, 3, 4, 5, 6]
   Moving right:  "abcDEF\n    "[6, 5, 4, 3, 1, 2], "ABC"[3, 2, 1, 0]
-Test 11, LTR:
+Test 13, LTR:
   Moving right: "abcABC123DEFdef\n    "[0, 1, 2, 3, 11, 10, 6, 7, 8, 9, 5, 4, 12, 13, 14, 15]
   Moving left:  "abcABC123DEFdef\n    "[15, 14, 13, 12, 4, 5, 9, 8, 7, 6, 10, 11, 3, 2, 1, 0]
   Moving right: "abcABC123DEFdef\n    "[0, 1, 2, 3, 11, 10, 6, 7, 8, 9, 5, 4, 12, 13, 14, 15]
   Moving left:  "abcABC123DEFdef\n    "[15, 14, 13, 12, 4, 5, 9, 8, 7, 6, 10, 11, 3, 2, 1, 0]
-Test 11, RTL:
+Test 13, RTL:
   Moving left: "abcABC123DEFdef\n    "[0, 2, 1, 3, 4, 5, 6, 8, 7, 9, 10, 11, 12, 14, 13, 15]
   Moving right:  "abcABC123DEFdef\n    "[15, 13, 14, 12, 11, 10, 9, 7, 8, 6, 5, 4, 3, 1, 2, 0]
   Moving left: "abcABC123DEFdef\n    "[0, 2, 1, 3, 4, 5, 6, 8, 7, 9, 10, 11, 12, 14, 13, 15]
   Moving right:  "abcABC123DEFdef\n    "[15, 13, 14, 12, 11, 10, 9, 7, 8, 6, 5, 4, 3, 1, 2, 0]
-Test 12, LTR:
+Test 14, LTR:
   Moving right: "abcABC123\n    "[0, 1, 2, 3, 7, 8, 5, 4, 9]
   Moving left:  "abcABC123\n    "[9, 4, 5, 8, 7, 3, 2, 1, 0]
   Moving right: "abcABC123\n    "[0, 1, 2, 3, 7, 8, 5, 4, 9]
   Moving left:  "abcABC123\n    "[9, 4, 5, 8, 7, 3, 2, 1, 0]
-Test 12, RTL:
+Test 14, RTL:
   Moving left: "abcABC123\n    "[0, 2, 1, 3, 4, 5, 6, 8, 7, 9]
   Moving right:  "abcABC123\n    "[9, 7, 8, 6, 5, 4, 3, 1, 2, 0]
   Moving left: "abcABC123\n    "[0, 2, 1, 3, 4, 5, 6, 8, 7, 9]
   Moving right:  "abcABC123\n    "[9, 7, 8, 6, 5, 4, 3, 1, 2, 0]
-Test 13, LTR:
+Test 15, LTR:
   Moving right: "abcABC123def\n    "[0, 1, 2, 3, 7, 8, 5, 4, 9, 10, 11, 12]
   Moving left:  "abcABC123def\n    "[12, 11, 10, 9, 4, 5, 8, 7, 6, 2, 1, 0]
 WARNING: Moving to the left did not visit the same positions in reverse order as moving to the right.
   Moving right: "abcABC123def\n    "[0, 1, 2, 3, 7, 8, 5, 4, 9, 10, 11, 12]
   Moving left:  "abcABC123def\n    "[12, 11, 10, 9, 4, 5, 8, 7, 6, 2, 1, 0]
 WARNING: Moving to the left did not visit the same positions in reverse order as moving to the right.
-Test 13, RTL:
+Test 15, RTL:
   Moving left: "abcABC123def\n    "[0, 2, 1, 3, 4, 5, 6, 11, 10, 9, 8, 7, 12]
   Moving right:  "abcABC123def\n    "[12, 7, 8, 9, 10, 11, 6, 5, 4, 3, 1, 2, 0]
   Moving left: "abcABC123def\n    "[0, 2, 1, 3, 4, 5, 6, 11, 10, 9, 8, 7, 12]
   Moving right:  "abcABC123def\n    "[12, 7, 8, 9, 10, 11, 6, 5, 4, 3, 1, 2, 0]
-Test 14, LTR:
+Test 16, LTR:
   Moving right: "ABC123DEFabcGHI456JLM\n    "[0, 8, 7, 3, 4, 5, 6, 2, 1, 9, 10, 11, 12, 20, 19, 15, 16, 17, 18, 14, 13, 21]
   Moving left:  "ABC123DEFabcGHI456JLM\n    "[21, 13, 14, 18, 17, 16, 15, 19, 20, 12, 11, 10, 9, 1, 2, 6, 5, 4, 3, 7, 8, 0]
   Moving right: "ABC123DEFabcGHI456JLM\n    "[0, 8, 7, 3, 4, 5, 6, 2, 1, 9, 10, 11, 12, 20, 19, 15, 16, 17, 18, 14, 13, 21]
   Moving left:  "ABC123DEFabcGHI456JLM\n    "[21, 13, 14, 18, 17, 16, 15, 19, 20, 12, 11, 10, 9, 1, 2, 6, 5, 4, 3, 7, 8, 0]
-Test 14, RTL:
+Test 16, RTL:
   Moving left: "ABC123DEFabcGHI456JLM\n    "[0, 1, 2, 3, 5, 4, 6, 7, 8, 9, 11, 10, 12, 13, 14, 15, 17, 16, 18, 19, 20, 21]
   Moving right:  "ABC123DEFabcGHI456JLM\n    "[21, 20, 19, 18, 16, 17, 15, 14, 13, 12, 10, 11, 9, 8, 7, 6, 4, 5, 3, 2, 1, 0]
   Moving left: "ABC123DEFabcGHI456JLM\n    "[0, 1, 2, 3, 5, 4, 6, 7, 8, 9, 11, 10, 12, 13, 14, 15, 17, 16, 18, 19, 20, 21]
   Moving right:  "ABC123DEFabcGHI456JLM\n    "[21, 20, 19, 18, 16, 17, 15, 14, 13, 12, 10, 11, 9, 8, 7, 6, 4, 5, 3, 2, 1, 0]
-Test 15, LTR:
+Test 17, LTR:
   Moving right: "\n        before    AHYJ AQWJXMFUDJE\n    "[9, 10, 11, 12, 13, 14, 15, 16, 22, 21, 20, 23, 24, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 35]
   Moving left:  "\n        before    AHYJ AQWJXMFUDJE\n    "[35, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 24, 23, 20, 21, 22, 16, 15, 14, 13, 12, 11, 10, 9]
   Moving right: "\n        before    AHYJ AQWJXMFUDJE\n    "[9, 10, 11, 12, 13, 14, 15, 16, 22, 21, 20, 23, 24, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 35]
   Moving left:  "\n        before    AHYJ AQWJXMFUDJE\n    "[35, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 24, 23, 20, 21, 22, 16, 15, 14, 13, 12, 11, 10, 9]
-Test 15, RTL:
+Test 17, RTL:
   Moving left: "\n        before    AHYJ AQWJXMFUDJE\n    "[9, 14, 13, 12, 11, 10, 15, 16, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35]
   Moving right:  "\n        before    AHYJ AQWJXMFUDJE\n    "[35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 16, 15, 10, 11, 12, 13, 14, 9]
   Moving left: "\n        before    AHYJ AQWJXMFUDJE\n    "[9, 14, 13, 12, 11, 10, 15, 16, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35]
   Moving right:  "\n        before    AHYJ AQWJXMFUDJE\n    "[35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 16, 15, 10, 11, 12, 13, 14, 9]
-Test 16, LTR:
+Test 18, LTR:
   Moving right: "\n        MUQJ    after encyclopedia\n    "[9, 12, 11, 10, 13, 14, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35]
   Moving left:  "\n        MUQJ    after encyclopedia\n    "[35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 14, 13, 10, 11, 12, 9]
   Moving right: "\n        MUQJ    after encyclopedia\n    "[9, 12, 11, 10, 13, 14, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35]
   Moving left:  "\n        MUQJ    after encyclopedia\n    "[35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 14, 13, 10, 11, 12, 9]
-Test 16, RTL:
+Test 18, RTL:
   Moving left: "\n        MUQJ    after encyclopedia\n    "[9, 10, 11, 12, 13, 14, 21, 20, 19, 18, 22, 23, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 35]
   Moving right:  "\n        MUQJ    after encyclopedia\n    "[35, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 23, 22, 18, 19, 20, 21, 14, 13, 12, 11, 10, 9]
   Moving left: "\n        MUQJ    after encyclopedia\n    "[9, 10, 11, 12, 13, 14, 21, 20, 19, 18, 22, 23, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 35]
   Moving right:  "\n        MUQJ    after encyclopedia\n    "[35, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 23, 22, 18, 19, 20, 21, 14, 13, 12, 11, 10, 9]
-Test 17, LTR:
+Test 19, LTR:
   Moving right: "\n        before    AHYJ AQWJXMFUDJE\n    "[9, 10, 11, 12, 13, 14, 15, 16, 22, 21, 20, 23, 24, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 35]
   Moving left:  "\n        before    AHYJ AQWJXMFUDJE\n    "[35, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 24, 23, 20, 21, 22, 16, 15, 14, 13, 12, 11, 10, 9]
   Moving right: "\n        before    AHYJ AQWJXMFUDJE\n    "[9, 10, 11, 12, 13, 14, 15, 16, 22, 21, 20, 23, 24, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 35]
   Moving left:  "\n        before    AHYJ AQWJXMFUDJE\n    "[35, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 24, 23, 20, 21, 22, 16, 15, 14, 13, 12, 11, 10, 9]
-Test 17, RTL:
+Test 19, RTL:
   Moving left: "\n        before    AHYJ AQWJXMFUDJE\n    "[9, 14, 13, 12, 11, 10, 15, 16, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35]
   Moving right:  "\n        before    AHYJ AQWJXMFUDJE\n    "[35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 16, 15, 10, 11, 12, 13, 14, 9]
   Moving left: "\n        before    AHYJ AQWJXMFUDJE\n    "[9, 14, 13, 12, 11, 10, 15, 16, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35]
   Moving right:  "\n        before    AHYJ AQWJXMFUDJE\n    "[35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 16, 15, 10, 11, 12, 13, 14, 9]
-Test 18, LTR:
+Test 20, LTR:
   Moving right: "\n        MUQJ    after encyclopedia\n    "[9, 12, 11, 10, 13, 14, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35]
   Moving left:  "\n        MUQJ    after encyclopedia\n    "[35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 14, 13, 10, 11, 12, 9]
   Moving right: "\n        MUQJ    after encyclopedia\n    "[9, 12, 11, 10, 13, 14, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35]
   Moving left:  "\n        MUQJ    after encyclopedia\n    "[35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 14, 13, 10, 11, 12, 9]
-Test 18, RTL:
+Test 20, RTL:
   Moving left: "\n        MUQJ    after encyclopedia\n    "[9, 10, 11, 12, 13, 14, 21, 20, 19, 18, 22, 23, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 35]
   Moving right:  "\n        MUQJ    after encyclopedia\n    "[35, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 23, 22, 18, 19, 20, 21, 14, 13, 12, 11, 10, 9]
   Moving left: "\n        MUQJ    after encyclopedia\n    "[9, 10, 11, 12, 13, 14, 21, 20, 19, 18, 22, 23, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 35]
   Moving right:  "\n        MUQJ    after encyclopedia\n    "[35, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 23, 22, 18, 19, 20, 21, 14, 13, 12, 11, 10, 9]
-Test 19, LTR:
+Test 21, LTR:
   Moving right: "\n        This is JF[Y WY OJ[Y the boxes. \n    "[9, 10, 11, 12, 13, 14, 15, 16, 17, 20, 19, 18, 21, 22, 28, 27, 26, 25, 24, 23, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40]
   Moving left:  "\n        This is JF[Y WY OJ[Y the boxes. \n    "[40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 23, 24, 25, 26, 27, 28, 22, 21, 18, 19, 20, 17, 16, 15, 14, 13, 12, 11, 10, 9]
   Moving right: "\n        This is JF[Y WY OJ[Y the boxes. \n    "[9, 10, 11, 12, 13, 14, 15, 16, 17, 20, 19, 18, 21, 22, 28, 27, 26, 25, 24, 23, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40]
   Moving left:  "\n        This is JF[Y WY OJ[Y the boxes. \n    "[40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 23, 24, 25, 26, 27, 28, 22, 21, 18, 19, 20, 17, 16, 15, 14, 13, 12, 11, 10, 9]
-Test 19, RTL:
+Test 21, RTL:
   Moving left: "\n        This is JF[Y WY OJ[Y the boxes. \n    "[9, 15, 14, 13, 12, 11, 10, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 31, 33, 34, 38, 37, 36, 35, 39, 40]
   Moving right:  "\n        This is JF[Y WY OJ[Y the boxes. \n    "[40, 39, 35, 36, 37, 38, 34, 33, 31, 32, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 10, 11, 12, 13, 14, 15, 9]
   Moving left: "\n        This is JF[Y WY OJ[Y the boxes. \n    "[9, 15, 14, 13, 12, 11, 10, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 31, 33, 34, 38, 37, 36, 35, 39, 40]
   Moving right:  "\n        This is JF[Y WY OJ[Y the boxes. \n    "[40, 39, 35, 36, 37, 38, 34, 33, 31, 32, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 10, 11, 12, 13, 14, 15, 9]
-Test 20, LTR:
+Test 22, LTR:
   Moving right: "\n        This is JF[Y WY OJ[Y the boxes. \n    "[9, 10, 11, 12, 13, 14, 15, 16, 17, 20, 19, 18, 21, 22, 28, 27, 26, 25, 24, 23, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40]
   Moving left:  "\n        This is JF[Y WY OJ[Y the boxes. \n    "[40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 23, 24, 25, 26, 27, 28, 22, 21, 18, 19, 20, 17, 16, 15, 14, 13, 12, 11, 10, 9]
   Moving right: "\n        This is JF[Y WY OJ[Y the boxes. \n    "[9, 10, 11, 12, 13, 14, 15, 16, 17, 20, 19, 18, 21, 22, 28, 27, 26, 25, 24, 23, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40]
   Moving left:  "\n        This is JF[Y WY OJ[Y the boxes. \n    "[40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 23, 24, 25, 26, 27, 28, 22, 21, 18, 19, 20, 17, 16, 15, 14, 13, 12, 11, 10, 9]
-Test 20, RTL:
+Test 22, RTL:
   Moving left: "\n        This is JF[Y WY OJ[Y the boxes. \n    "[9, 15, 14, 13, 12, 11, 10, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 31, 33, 34, 38, 37, 36, 35, 39, 40]
   Moving right:  "\n        This is JF[Y WY OJ[Y the boxes. \n    "[40, 39, 35, 36, 37, 38, 34, 33, 31, 32, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 10, 11, 12, 13, 14, 15, 9]
   Moving left: "\n        This is JF[Y WY OJ[Y the boxes. \n    "[9, 15, 14, 13, 12, 11, 10, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 31, 33, 34, 38, 37, 36, 35, 39, 40]
   Moving right:  "\n        This is JF[Y WY OJ[Y the boxes. \n    "[40, 39, 35, 36, 37, 38, 34, 33, 31, 32, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 10, 11, 12, 13, 14, 15, 9]
-Test 21, LTR:
+Test 23, LTR:
   Moving right: "\n        Lorem\n        "[9, 10, 11, 12, 13, 14], <DIV>[0], "\n        ipsum\n    "[9, 10, 11, 12, 13, 14]
   Moving left:  "\n        ipsum\n    "[14, 13, 12, 11, 10, 9], <DIV>[0], "\n        Lorem\n        "[14, 13, 12, 11, 10, 9]
   Moving right: "\n        Lorem\n        "[9, 10, 11, 12, 13, 14], <DIV>[0], "\n        ipsum\n    "[9, 10, 11, 12, 13, 14]
   Moving left:  "\n        ipsum\n    "[14, 13, 12, 11, 10, 9], <DIV>[0], "\n        Lorem\n        "[14, 13, 12, 11, 10, 9]
-Test 21, RTL:
+Test 23, RTL:
   Moving left: "\n        Lorem\n        "[9, 13, 12, 11, 10, 14], <DIV>[0], "\n        ipsum\n    "[9, 13, 12, 11, 10, 14]
   Moving right:  "\n        ipsum\n    "[14, 10, 11, 12, 13, 9], <DIV>[0], "\n        Lorem\n        "[14, 10, 11, 12, 13, 9]
   Moving left: "\n        Lorem\n        "[9, 13, 12, 11, 10, 14], <DIV>[0], "\n        ipsum\n    "[9, 13, 12, 11, 10, 14]
   Moving right:  "\n        ipsum\n    "[14, 10, 11, 12, 13, 9], <DIV>[0], "\n        Lorem\n        "[14, 10, 11, 12, 13, 9]
-Test 22, LTR:
+Test 24, LTR:
   Moving right: "\n        WMH[\n        "[9, 12, 11, 10, 13], <DIV>[0], "\n        OWQU[\n    "[9, 13, 12, 11, 10, 14]
   Moving left:  "\n        OWQU[\n    "[14, 10, 11, 12, 13, 9], <DIV>[0], "\n        WMH[\n        "[13, 10, 11, 12, 9]
   Moving right: "\n        WMH[\n        "[9, 12, 11, 10, 13], <DIV>[0], "\n        OWQU[\n    "[9, 13, 12, 11, 10, 14]
   Moving left:  "\n        OWQU[\n    "[14, 10, 11, 12, 13, 9], <DIV>[0], "\n        WMH[\n        "[13, 10, 11, 12, 9]
-Test 22, RTL:
+Test 24, RTL:
   Moving left: "\n        WMH[\n        "[9, 10, 11, 12, 13], <DIV>[0], "\n        OWQU[\n    "[9, 10, 11, 12, 13, 14]
   Moving right:  "\n        OWQU[\n    "[14, 13, 12, 11, 10, 9], <DIV>[0], "\n        WMH[\n        "[13, 12, 11, 10, 9]
   Moving left: "\n        WMH[\n        "[9, 10, 11, 12, 13], <DIV>[0], "\n        OWQU[\n    "[9, 10, 11, 12, 13, 14]
   Moving right:  "\n        OWQU[\n    "[14, 13, 12, 11, 10, 9], <DIV>[0], "\n        WMH[\n        "[13, 12, 11, 10, 9]
-Test 23, LTR:
+Test 25, LTR:
   Moving right: "\n        abcdefABC"[9, 10, 11, 12, 13, 14, 15], "DEF\n    "[2, 1], <DIV>[2], "\n        abcdefABC"[18, 17, 16], "DEF\n    "[3]
   Moving left:  "DEF\n    "[3], "\n        abcdefABC"[16, 17, 18], <DIV>[2], "DEF\n    "[1, 2], "\n        abcdefABC"[15, 14, 13, 12, 11, 10, 9]
   Moving right: "\n        abcdefABC"[9, 10, 11, 12, 13, 14, 15], "DEF\n    "[2, 1], <DIV>[2], "\n        abcdefABC"[18, 17, 16], "DEF\n    "[3]
   Moving left:  "DEF\n    "[3], "\n        abcdefABC"[16, 17, 18], <DIV>[2], "DEF\n    "[1, 2], "\n        abcdefABC"[15, 14, 13, 12, 11, 10, 9]
-Test 23, RTL:
+Test 25, RTL:
   Moving left: "\n        abcdefABC"[9, 14, 13, 12, 11, 10, 15, 16, 17, 18], <DIV>[2], "DEF\n    "[1, 2, 3]
   Moving right:  "DEF\n    "[3, 2, 1], <DIV>[2], "\n        abcdefABC"[18, 17, 16, 15, 10, 11, 12, 13, 14, 9]
   Moving left: "\n        abcdefABC"[9, 14, 13, 12, 11, 10, 15, 16, 17, 18], <DIV>[2], "DEF\n    "[1, 2, 3]
   Moving right:  "DEF\n    "[3, 2, 1], <DIV>[2], "\n        abcdefABC"[18, 17, 16, 15, 10, 11, 12, 13, 14, 9]
-Test 24, LTR:
+Test 26, LTR:
   Moving right: "\n        ABCDEFabc"[9, 14, 13, 12, 11, 10, 15, 16, 17, 18], <DIV>[2], "def\n    "[1, 2, 3]
   Moving left:  "def\n    "[3, 2, 1], <DIV>[2], "\n        ABCDEFabc"[18, 17, 16, 15, 10, 11, 12, 13, 14, 9]
   Moving right: "\n        ABCDEFabc"[9, 14, 13, 12, 11, 10, 15, 16, 17, 18], <DIV>[2], "def\n    "[1, 2, 3]
   Moving left:  "def\n    "[3, 2, 1], <DIV>[2], "\n        ABCDEFabc"[18, 17, 16, 15, 10, 11, 12, 13, 14, 9]
-Test 24, RTL:
+Test 26, RTL:
   Moving left: "\n        ABCDEFabc"[9, 10, 11, 12, 13, 14, 15], "def\n    "[2, 1], <DIV>[2], "\n        ABCDEFabc"[18, 17, 16], "def\n    "[3]
   Moving right:  "def\n    "[3], "\n        ABCDEFabc"[16, 17, 18], <DIV>[2], "def\n    "[1, 2], "\n        ABCDEFabc"[15, 14, 13, 12, 11, 10, 9]
   Moving left: "\n        ABCDEFabc"[9, 10, 11, 12, 13, 14, 15], "def\n    "[2, 1], <DIV>[2], "\n        ABCDEFabc"[18, 17, 16], "def\n    "[3]
   Moving right:  "def\n    "[3], "\n        ABCDEFabc"[16, 17, 18], <DIV>[2], "def\n    "[1, 2], "\n        ABCDEFabc"[15, 14, 13, 12, 11, 10, 9]
-Test 25, LTR:
+Test 27, LTR:
   Moving right: "\n        abc"[9, 10, 11, 12], <DIV>[2], "DEFghi\n    "[2, 1], <DIV>[5, 4], "ABC"[3, 2, 1], "DEFghi\n    "[3, 4, 5, 6]
   Moving left:  "DEFghi\n    "[6, 5, 4, 3], "ABC"[1, 2, 3], <DIV>[4, 5], "DEFghi\n    "[1, 2], <DIV>[2], "\n        abc"[12, 11, 10, 9]
   Moving right: "\n        abc"[9, 10, 11, 12], <DIV>[2], "DEFghi\n    "[2, 1], <DIV>[5, 4], "ABC"[3, 2, 1], "DEFghi\n    "[3, 4, 5, 6]
   Moving left:  "DEFghi\n    "[6, 5, 4, 3], "ABC"[1, 2, 3], <DIV>[4, 5], "DEFghi\n    "[1, 2], <DIV>[2], "\n        abc"[12, 11, 10, 9]
-Test 25, RTL:
+Test 27, RTL:
   Moving left: "\n        abc"[9, 11, 10, 12], <DIV>[2], "ABC"[1, 2, 3], <DIV>[4, 5], "DEFghi\n    "[1, 2, 3, 5, 4, 6]
   Moving right:  "DEFghi\n    "[6, 4, 5, 3, 2, 1], <DIV>[5, 4], "ABC"[3, 2, 1], <DIV>[2], "\n        abc"[12, 10, 11, 9]
   Moving left: "\n        abc"[9, 11, 10, 12], <DIV>[2], "ABC"[1, 2, 3], <DIV>[4, 5], "DEFghi\n    "[1, 2, 3, 5, 4, 6]
   Moving right:  "DEFghi\n    "[6, 4, 5, 3, 2, 1], <DIV>[5, 4], "ABC"[3, 2, 1], <DIV>[2], "\n        abc"[12, 10, 11, 9]
-Test 26, LTR:
+Test 28, LTR:
   Moving right: "\n        ABC"[9, 11, 10, 12], <DIV>[2], "abc"[1, 2, 3], <DIV>[4, 5], "defDEF\n    "[1, 2, 3, 5, 4, 6]
   Moving left:  "defDEF\n    "[6, 4, 5, 3, 2, 1], <DIV>[5, 4], "abc"[3, 2, 1], <DIV>[2], "\n        ABC"[12, 10, 11, 9]
   Moving right: "\n        ABC"[9, 11, 10, 12], <DIV>[2], "abc"[1, 2, 3], <DIV>[4, 5], "defDEF\n    "[1, 2, 3, 5, 4, 6]
   Moving left:  "defDEF\n    "[6, 4, 5, 3, 2, 1], <DIV>[5, 4], "abc"[3, 2, 1], <DIV>[2], "\n        ABC"[12, 10, 11, 9]
-Test 26, RTL:
+Test 28, RTL:
   Moving left: "\n        ABC"[9, 10, 11, 12], <DIV>[2], "defDEF\n    "[2, 1], <DIV>[5, 4], "abc"[3, 2, 1], "defDEF\n    "[3, 4, 5, 6]
   Moving right:  "defDEF\n    "[6, 5, 4, 3], "abc"[1, 2, 3], <DIV>[4, 5], "defDEF\n    "[1, 2], <DIV>[2], "\n        ABC"[12, 11, 10, 9]
   Moving left: "\n        ABC"[9, 10, 11, 12], <DIV>[2], "defDEF\n    "[2, 1], <DIV>[5, 4], "abc"[3, 2, 1], "defDEF\n    "[3, 4, 5, 6]
   Moving right:  "defDEF\n    "[6, 5, 4, 3], "abc"[1, 2, 3], <DIV>[4, 5], "defDEF\n    "[1, 2], <DIV>[2], "\n        ABC"[12, 11, 10, 9]
-Test 27, LTR:
+Test 29, LTR:
   Moving right: "\n        abcABC"[9, 10, 11, 12], "DEF"[2, 1], "\n        abcABC"[15, 14, 13], "DEF"[3]
   Moving left:  "DEF"[3], "\n        abcABC"[13, 14, 15], "DEF"[1, 2], "\n        abcABC"[12, 11, 10, 9]
   Moving right: "\n        abcABC"[9, 10, 11, 12], "DEF"[2, 1], "\n        abcABC"[15, 14, 13], "DEF"[3]
   Moving left:  "DEF"[3], "\n        abcABC"[13, 14, 15], "DEF"[1, 2], "\n        abcABC"[12, 11, 10, 9]
-Test 27, RTL:
+Test 29, RTL:
   Moving left: "\n        abcABC"[9, 11, 10, 12, 13, 14, 15], "DEF"[1, 2, 3]
   Moving right:  "DEF"[3, 2, 1], "\n        abcABC"[15, 14, 13, 12, 10, 11, 9]
   Moving left: "\n        abcABC"[9, 11, 10, 12, 13, 14, 15], "DEF"[1, 2, 3]
   Moving right:  "DEF"[3, 2, 1], "\n        abcABC"[15, 14, 13, 12, 10, 11, 9]
-Test 28, LTR:
+Test 30, LTR:
   Moving right: "\n        ABCabc"[9, 11, 10, 12, 13, 14, 15], "def"[1, 2, 3]
   Moving left:  "def"[3, 2, 1], "\n        ABCabc"[15, 14, 13, 12, 10, 11, 9]
   Moving right: "\n        ABCabc"[9, 11, 10, 12, 13, 14, 15], "def"[1, 2, 3]
   Moving left:  "def"[3, 2, 1], "\n        ABCabc"[15, 14, 13, 12, 10, 11, 9]
-Test 28, RTL:
+Test 30, RTL:
   Moving left: "\n        ABCabc"[9, 10, 11, 12], "def"[2, 1], "\n        ABCabc"[15, 14, 13], "def"[3]
   Moving right:  "def"[3], "\n        ABCabc"[13, 14, 15], "def"[1, 2], "\n        ABCabc"[12, 11, 10, 9]
   Moving left: "\n        ABCabc"[9, 10, 11, 12], "def"[2, 1], "\n        ABCabc"[15, 14, 13], "def"[3]
   Moving right:  "def"[3], "\n        ABCabc"[13, 14, 15], "def"[1, 2], "\n        ABCabc"[12, 11, 10, 9]
-Test 29, LTR:
+Test 31, LTR:
   Moving right: "\n        ab"[9, 10, 11], "cABCdef"[1, 3, 2, 4, 5, 6, 7]
   Moving left:  "cABCdef"[7, 6, 5, 4, 2, 3, 1], "\n        ab"[11, 10, 9]
   Moving right: "\n        ab"[9, 10, 11], "cABCdef"[1, 3, 2, 4, 5, 6, 7]
   Moving left:  "cABCdef"[7, 6, 5, 4, 2, 3, 1], "\n        ab"[11, 10, 9]
-Test 29, RTL:
+Test 31, RTL:
   Moving left: "\n        ab"[9, 11, 10], "cABCdef"[1, 2, 3, 4, 6, 5, 7]
   Moving right:  "cABCdef"[7, 5, 6, 4, 3, 2, 1], "\n        ab"[10, 11, 9]
   Moving left: "\n        ab"[9, 11, 10], "cABCdef"[1, 2, 3, 4, 6, 5, 7]
   Moving right:  "cABCdef"[7, 5, 6, 4, 3, 2, 1], "\n        ab"[10, 11, 9]
-Test 30, LTR:
+Test 32, LTR:
   Moving right: "\n        AB"[9, 11, 10], "CabcDEF"[1, 2, 3, 4, 6, 5, 7]
   Moving left:  "CabcDEF"[7, 5, 6, 4, 3, 2, 1], "\n        AB"[10, 11, 9]
   Moving right: "\n        AB"[9, 11, 10], "CabcDEF"[1, 2, 3, 4, 6, 5, 7]
   Moving left:  "CabcDEF"[7, 5, 6, 4, 3, 2, 1], "\n        AB"[10, 11, 9]
-Test 30, RTL:
+Test 32, RTL:
   Moving left: "\n        AB"[9, 10, 11], "CabcDEF"[1, 3, 2, 4, 5, 6, 7]
   Moving right:  "CabcDEF"[7, 6, 5, 4, 2, 3, 1], "\n        AB"[11, 10, 9]
   Moving left: "\n        AB"[9, 10, 11], "CabcDEF"[1, 3, 2, 4, 5, 6, 7]
   Moving right:  "CabcDEF"[7, 6, 5, 4, 2, 3, 1], "\n        AB"[11, 10, 9]
-Test 31, LTR:
+Test 33, LTR:
   Moving right: "\n        abc"[9, 10, 11, 12], "ABCdef"[2, 1, 3, 4, 5, 6]
   Moving left:  "ABCdef"[6, 5, 4, 3, 1, 2], "\n        abc"[12, 11, 10, 9]
   Moving right: "\n        abc"[9, 10, 11, 12], "ABCdef"[2, 1, 3, 4, 5, 6]
   Moving left:  "ABCdef"[6, 5, 4, 3, 1, 2], "\n        abc"[12, 11, 10, 9]
-Test 31, RTL:
+Test 33, RTL:
   Moving left: "\n        abc"[9, 11, 10, 12], "ABCdef"[1, 2, 3, 5, 4, 6]
   Moving right:  "ABCdef"[6, 4, 5, 3, 2, 1], "\n        abc"[12, 10, 11, 9]
   Moving left: "\n        abc"[9, 11, 10, 12], "ABCdef"[1, 2, 3, 5, 4, 6]
   Moving right:  "ABCdef"[6, 4, 5, 3, 2, 1], "\n        abc"[12, 10, 11, 9]
-Test 32, LTR:
+Test 34, LTR:
   Moving right: "\n        ABC"[9, 11, 10, 12], "abcDEF"[1, 2, 3, 5, 4, 6]
   Moving left:  "abcDEF"[6, 4, 5, 3, 2, 1], "\n        ABC"[12, 10, 11, 9]
   Moving right: "\n        ABC"[9, 11, 10, 12], "abcDEF"[1, 2, 3, 5, 4, 6]
   Moving left:  "abcDEF"[6, 4, 5, 3, 2, 1], "\n        ABC"[12, 10, 11, 9]
-Test 32, RTL:
+Test 34, RTL:
   Moving left: "\n        ABC"[9, 10, 11, 12], "abcDEF"[2, 1, 3, 4, 5, 6]
   Moving right:  "abcDEF"[6, 5, 4, 3, 1, 2], "\n        ABC"[12, 11, 10, 9]
   Moving left: "\n        ABC"[9, 10, 11, 12], "abcDEF"[2, 1, 3, 4, 5, 6]
   Moving right:  "abcDEF"[6, 5, 4, 3, 1, 2], "\n        ABC"[12, 11, 10, 9]
-Test 33, LTR:
+Test 35, LTR:
   Moving right: "\n        abcAdef\n    "[9, 10, 11, 12, 13, 14, 15, 16]
   Moving left:  "\n        abcAdef\n    "[16, 15, 14, 13, 12, 11, 10, 9]
   Moving right: "\n        abcAdef\n    "[9, 10, 11, 12, 13, 14, 15, 16]
   Moving left:  "\n        abcAdef\n    "[16, 15, 14, 13, 12, 11, 10, 9]
-Test 33, RTL:
+Test 35, RTL:
   Moving left: "\n        abcAdef\n    "[9, 11, 10, 12, 13, 15, 14, 16]
   Moving right:  "\n        abcAdef\n    "[16, 14, 15, 13, 12, 10, 11, 9]
   Moving left: "\n        abcAdef\n    "[9, 11, 10, 12, 13, 15, 14, 16]
   Moving right:  "\n        abcAdef\n    "[16, 14, 15, 13, 12, 10, 11, 9]
-Test 34, LTR:
+Test 36, LTR:
   Moving right: "\n        ABCaDEF\n    "[9, 11, 10, 12, 13, 15, 14, 16]
   Moving left:  "\n        ABCaDEF\n    "[16, 14, 15, 13, 12, 10, 11, 9]
   Moving right: "\n        ABCaDEF\n    "[9, 11, 10, 12, 13, 15, 14, 16]
   Moving left:  "\n        ABCaDEF\n    "[16, 14, 15, 13, 12, 10, 11, 9]
-Test 34, RTL:
+Test 36, RTL:
   Moving left: "\n        ABCaDEF\n    "[9, 10, 11, 12, 13, 14, 15, 16]
   Moving right:  "\n        ABCaDEF\n    "[16, 15, 14, 13, 12, 11, 10, 9]
   Moving left: "\n        ABCaDEF\n    "[9, 10, 11, 12, 13, 14, 15, 16]
   Moving right:  "\n        ABCaDEF\n    "[16, 15, 14, 13, 12, 11, 10, 9]
-Test 35, LTR:
+Test 37, LTR:
   Moving right: "\n        abcABC"[9, 10, 11, 12, 14, 13, 15], "def"[1, 2, 3]
   Moving left:  "def"[3, 2, 1], "\n        abcABC"[15, 13, 14, 12, 11, 10, 9]
   Moving right: "\n        abcABC"[9, 10, 11, 12, 14, 13, 15], "def"[1, 2, 3]
   Moving left:  "def"[3, 2, 1], "\n        abcABC"[15, 13, 14, 12, 11, 10, 9]
-Test 35, RTL:
+Test 37, RTL:
   Moving left: "\n        abcABC"[9, 11, 10, 12, 13, 14, 15], "def"[2, 1, 3]
   Moving right:  "def"[3, 1, 2], "\n        abcABC"[15, 14, 13, 12, 10, 11, 9]
   Moving left: "\n        abcABC"[9, 11, 10, 12, 13, 14, 15], "def"[2, 1, 3]
   Moving right:  "def"[3, 1, 2], "\n        abcABC"[15, 14, 13, 12, 10, 11, 9]
-Test 36, LTR:
+Test 38, LTR:
   Moving right: "\n        ABCabc"[9, 11, 10, 12, 13, 14, 15], "DEF"[2, 1, 3]
   Moving left:  "DEF"[3, 1, 2], "\n        ABCabc"[15, 14, 13, 12, 10, 11, 9]
   Moving right: "\n        ABCabc"[9, 11, 10, 12, 13, 14, 15], "DEF"[2, 1, 3]
   Moving left:  "DEF"[3, 1, 2], "\n        ABCabc"[15, 14, 13, 12, 10, 11, 9]
-Test 36, RTL:
+Test 38, RTL:
   Moving left: "\n        ABCabc"[9, 10, 11, 12, 14, 13, 15], "DEF"[1, 2, 3]
   Moving right:  "DEF"[3, 2, 1], "\n        ABCabc"[15, 13, 14, 12, 11, 10, 9]
   Moving left: "\n        ABCabc"[9, 10, 11, 12, 14, 13, 15], "DEF"[1, 2, 3]
   Moving right:  "DEF"[3, 2, 1], "\n        ABCabc"[15, 13, 14, 12, 11, 10, 9]
-Test 37, LTR:
+Test 39, LTR:
   Moving right: "\n        abcA"[9, 10, 11, 12], "BCdef"[1], "\n        abcA"[13], "BCdef"[2, 3, 4, 5]
   Moving left:  "BCdef"[5, 4, 3, 2], "\n        abcA"[13], "BCdef"[1], "\n        abcA"[12, 11, 10, 9]
   Moving right: "\n        abcA"[9, 10, 11, 12], "BCdef"[1], "\n        abcA"[13], "BCdef"[2, 3, 4, 5]
   Moving left:  "BCdef"[5, 4, 3, 2], "\n        abcA"[13], "BCdef"[1], "\n        abcA"[12, 11, 10, 9]
-Test 37, RTL:
+Test 39, RTL:
   Moving left: "\n        abcA"[9, 11, 10, 12, 13], "BCdef"[1, 2, 4, 3, 5]
   Moving right:  "BCdef"[5, 3, 4, 2, 1], "\n        abcA"[13, 12, 10, 11, 9]
   Moving left: "\n        abcA"[9, 11, 10, 12, 13], "BCdef"[1, 2, 4, 3, 5]
   Moving right:  "BCdef"[5, 3, 4, 2, 1], "\n        abcA"[13, 12, 10, 11, 9]
-Test 38, LTR:
+Test 40, LTR:
   Moving right: "\n        ABCa"[9, 11, 10, 12, 13], "bcDEF"[1, 2, 4, 3, 5]
   Moving left:  "bcDEF"[5, 3, 4, 2, 1], "\n        ABCa"[13, 12, 10, 11, 9]
   Moving right: "\n        ABCa"[9, 11, 10, 12, 13], "bcDEF"[1, 2, 4, 3, 5]
   Moving left:  "bcDEF"[5, 3, 4, 2, 1], "\n        ABCa"[13, 12, 10, 11, 9]
-Test 38, RTL:
+Test 40, RTL:
   Moving left: "\n        ABCa"[9, 10, 11, 12], "bcDEF"[1], "\n        ABCa"[13], "bcDEF"[2, 3, 4, 5]
   Moving right:  "bcDEF"[5, 4, 3, 2], "\n        ABCa"[13], "bcDEF"[1], "\n        ABCa"[12, 11, 10, 9]
   Moving left: "\n        ABCa"[9, 10, 11, 12], "bcDEF"[1], "\n        ABCa"[13], "bcDEF"[2, 3, 4, 5]
   Moving right:  "bcDEF"[5, 4, 3, 2], "\n        ABCa"[13], "bcDEF"[1], "\n        ABCa"[12, 11, 10, 9]
-Test 39, LTR:
+Test 41, LTR:
   Moving right: "abc"[0, 1, 2, 3], "def"[0, 1, 2, 3]
   Moving left:  "def"[3, 2, 1, 0], "abc"[3, 2, 1, 0]
   Moving right: "abc"[0, 1, 2, 3], "def"[0, 1, 2, 3]
   Moving left:  "def"[3, 2, 1, 0], "abc"[3, 2, 1, 0]
-Test 39, RTL:
+Test 41, RTL:
   Moving left: "abc"[0, 2, 1, 3], "def"[0, 2, 1, 3]
   Moving right:  "def"[3, 1, 2, 0], "abc"[3, 1, 2, 0]
   Moving left: "abc"[0, 2, 1, 3], "def"[0, 2, 1, 3]
   Moving right:  "def"[3, 1, 2, 0], "abc"[3, 1, 2, 0]
-Test 40, LTR:
+Test 42, LTR:
   Moving right: "ABC"[0, 2, 1, 3], "DEF"[0, 2, 1, 3]
   Moving left:  "DEF"[3, 1, 2, 0], "ABC"[3, 1, 2, 0]
   Moving right: "ABC"[0, 2, 1, 3], "DEF"[0, 2, 1, 3]
   Moving left:  "DEF"[3, 1, 2, 0], "ABC"[3, 1, 2, 0]
-Test 40, RTL:
+Test 42, RTL:
   Moving left: "ABC"[0, 1, 2, 3], "DEF"[0, 1, 2, 3]
   Moving right:  "DEF"[3, 2, 1, 0], "ABC"[3, 2, 1, 0]
   Moving left: "ABC"[0, 1, 2, 3], "DEF"[0, 1, 2, 3]
   Moving right:  "DEF"[3, 2, 1, 0], "ABC"[3, 2, 1, 0]
+Test 43, LTR:
+  Moving right: "abcXXX123QQQdef"[0, 13, 14, 11, 10, 6, 7, 8, 9, 5, 4, 1, 2, 15]
+  Moving left:  "abcXXX123QQQdef"[15, 2, 1, 4, 5, 9, 8, 7, 6, 10, 11, 14, 13, 0]
+Test 43, RTL:
+  Moving left: "abcXXX123QQQdef"[0, 2, 1, 3, 4, 5, 6, 8, 7, 9, 10, 11, 12, 14, 13, 15]
+  Moving right:  "abcXXX123QQQdef"[15, 13, 14, 12, 11, 10, 9, 7, 8, 6, 5, 4, 3, 1, 2, 0]
 
 
index 90e1ba7..46595c3 100644 (file)
             var result = "";
             for (var i = 0; i < string.length; ++i) {
                 var char = string.charCodeAt(i);
             var result = "";
             for (var i = 0; i < string.length; ++i) {
                 var char = string.charCodeAt(i);
-                if (char >= 0x05d0)
+                if (char >= 0x0660) // Arabic numeral 0
+                    char = char - 0x660 + '0'.charCodeAt(0);
+                else if (char >= 0x0627) // Alif
+                    char = char - 0x0627 + 'A'.charCodeAt(0);
+                else if (char >= 0x05d0)
                     char -= 0x058f;
                 else if (char == 10) {
                     result += "\\n";
                     char -= 0x058f;
                 else if (char == 10) {
                     result += "\\n";
         אבגabcdef
     </div>
 
         אבגabcdef
     </div>
 
+    <div class="test">١٢٣ابة</div>
+
+    <div class="test">ابة١٢٣</div>
+
     <div class="test">
         <span>abc</span>אבגdef
     </div>
     <div class="test">
         <span>abc</span>אבגdef
     </div>
     <div class="test" style="white-space: pre;">אבג<!-- -->
 <!-- -->דהו</div>
 
     <div class="test" style="white-space: pre;">אבג<!-- -->
 <!-- -->דהו</div>
 
+    <div class="test">
+        <span dir="rtl">abcקקק123נננdef</span>
     </div>
 
     </div>
     </div>
 
     </div>
index 074cc98..64306ac 100644 (file)
@@ -1,3 +1,29 @@
+2011-04-26  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Reviewed by Dan Bernstein.
+
+        [RTL] Arabic/AB - after typing a date, cursors doesn't go back
+        https://bugs.webkit.org/show_bug.cgi?id=49111
+
+        Even when the offset corresponds to a position visually left of the box
+        and there aren't any inline boxes on the left, the previous/next position
+        may still correspond to some position in the same line.
+
+        The bug was caused by our ignoring such cases. Fixed the bug by comparing
+        previous/next position's inline box to the current box. If they match,
+        then we stay on the same position because moving to the left visually at
+        the left edge should not result in a position on the same line.
+
+        Also fixed a bug that WebKit uses offsets that are not extrema when moved to
+        the left edge or to the right edge, and a bug that WebKit could not move to
+        the left from 12^3 CBA abc to 123 C^BA abc (there is no offset between 3 and C).
+
+        Test cases are added to editing/selection/move-left-right.html
+
+        * editing/VisiblePosition.cpp:
+        (WebCore::VisiblePosition::leftVisuallyDistinctCandidate):
+        (WebCore::VisiblePosition::rightVisuallyDistinctCandidate):
+
 2011-04-26  Gabor Loki  <loki@webkit.org>
 
         Reviewed by Csaba Osztrogonác.
 2011-04-26  Gabor Loki  <loki@webkit.org>
 
         Reviewed by Csaba Osztrogonác.
index c3c05fd..cfaec47 100644 (file)
@@ -33,6 +33,7 @@
 #include "InlineTextBox.h"
 #include "Logging.h"
 #include "Range.h"
 #include "InlineTextBox.h"
 #include "Logging.h"
 #include "Range.h"
+#include "RootInlineBox.h"
 #include "Text.h"
 #include "htmlediting.h"
 #include "visible_units.h"
 #include "Text.h"
 #include "htmlediting.h"
 #include "visible_units.h"
@@ -134,8 +135,18 @@ Position VisiblePosition::leftVisuallyDistinctCandidate() const
             if (box->isLeftToRightDirection() ? offset < caretMinOffset : offset > caretMaxOffset) {
                 // Overshot to the left.
                 InlineBox* prevBox = box->prevLeafChild();
             if (box->isLeftToRightDirection() ? offset < caretMinOffset : offset > caretMaxOffset) {
                 // Overshot to the left.
                 InlineBox* prevBox = box->prevLeafChild();
-                if (!prevBox)
-                    return primaryDirection == LTR ? previousVisuallyDistinctCandidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition);
+                if (!prevBox) {
+                    Position positionOnLeft = primaryDirection == LTR ? previousVisuallyDistinctCandidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition);
+                    if (positionOnLeft.isNull())
+                        return Position();
+
+                    InlineBox* boxOnLeft;
+                    int offsetOnLeft;
+                    positionOnLeft.getInlineBoxAndOffset(m_affinity, primaryDirection, boxOnLeft, offsetOnLeft);
+                    if (boxOnLeft && boxOnLeft->root() == box->root())
+                        return Position();
+                    return positionOnLeft;
+                }
 
                 // Reposition at the other logical position corresponding to our edge's visual position and go for another round.
                 box = prevBox;
 
                 // Reposition at the other logical position corresponding to our edge's visual position and go for another round.
                 box = prevBox;
@@ -150,7 +161,16 @@ Position VisiblePosition::leftVisuallyDistinctCandidate() const
             InlineBox* prevBox = box->prevLeafChild();
 
             if (box->direction() == primaryDirection) {
             InlineBox* prevBox = box->prevLeafChild();
 
             if (box->direction() == primaryDirection) {
-                if (!prevBox || prevBox->bidiLevel() >= level)
+                if (!prevBox) {
+                    InlineBox* logicalStart = 0;
+                    if (primaryDirection == LTR ? box->root()->getLogicalStartBoxWithNode(logicalStart) : box->root()->getLogicalEndBoxWithNode(logicalStart)) {
+                        box = logicalStart;
+                        renderer = box->renderer();
+                        offset = primaryDirection == LTR ? box->caretMinOffset() : box->caretMaxOffset();
+                    }
+                    break;
+                }
+                if (prevBox->bidiLevel() >= level)
                     break;
 
                 level = prevBox->bidiLevel();
                     break;
 
                 level = prevBox->bidiLevel();
@@ -163,11 +183,7 @@ Position VisiblePosition::leftVisuallyDistinctCandidate() const
                 if (nextBox && nextBox->bidiLevel() == level)
                     break;
 
                 if (nextBox && nextBox->bidiLevel() == level)
                     break;
 
-                while (InlineBox* prevBox = box->prevLeafChild()) {
-                    if (prevBox->bidiLevel() < level)
-                        break;
-                    box = prevBox;
-                }
+                box = prevBox;
                 renderer = box->renderer();
                 offset = box->caretRightmostOffset();
                 if (box->direction() == primaryDirection)
                 renderer = box->renderer();
                 offset = box->caretRightmostOffset();
                 if (box->direction() == primaryDirection)
@@ -270,8 +286,18 @@ Position VisiblePosition::rightVisuallyDistinctCandidate() const
             if (box->isLeftToRightDirection() ? offset > caretMaxOffset : offset < caretMinOffset) {
                 // Overshot to the right.
                 InlineBox* nextBox = box->nextLeafChild();
             if (box->isLeftToRightDirection() ? offset > caretMaxOffset : offset < caretMinOffset) {
                 // Overshot to the right.
                 InlineBox* nextBox = box->nextLeafChild();
-                if (!nextBox)
-                    return primaryDirection == LTR ? nextVisuallyDistinctCandidate(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition);
+                if (!nextBox) {
+                    Position positionOnRight = primaryDirection == LTR ? nextVisuallyDistinctCandidate(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition);
+                    if (positionOnRight.isNull())
+                        return Position();
+
+                    InlineBox* boxOnRight;
+                    int offsetOnRight;
+                    positionOnRight.getInlineBoxAndOffset(m_affinity, primaryDirection, boxOnRight, offsetOnRight);
+                    if (boxOnRight && boxOnRight->root() == box->root())
+                        return Position();
+                    return positionOnRight;
+                }
 
                 // Reposition at the other logical position corresponding to our edge's visual position and go for another round.
                 box = nextBox;
 
                 // Reposition at the other logical position corresponding to our edge's visual position and go for another round.
                 box = nextBox;
@@ -286,7 +312,16 @@ Position VisiblePosition::rightVisuallyDistinctCandidate() const
             InlineBox* nextBox = box->nextLeafChild();
 
             if (box->direction() == primaryDirection) {
             InlineBox* nextBox = box->nextLeafChild();
 
             if (box->direction() == primaryDirection) {
-                if (!nextBox || nextBox->bidiLevel() >= level)
+                if (!nextBox) {
+                    InlineBox* logicalEnd = 0;
+                    if (primaryDirection == LTR ? box->root()->getLogicalEndBoxWithNode(logicalEnd) : box->root()->getLogicalStartBoxWithNode(logicalEnd)) {
+                        box = logicalEnd;
+                        renderer = box->renderer();
+                        offset = primaryDirection == LTR ? box->caretMaxOffset() : box->caretMinOffset();
+                    }
+                    break;
+                }
+                if (nextBox->bidiLevel() >= level)
                     break;
 
                 level = nextBox->bidiLevel();
                     break;
 
                 level = nextBox->bidiLevel();
@@ -299,12 +334,8 @@ Position VisiblePosition::rightVisuallyDistinctCandidate() const
                 if (prevBox && prevBox->bidiLevel() == level)   // For example, abc FED 123 ^ CBA
                     break;
 
                 if (prevBox && prevBox->bidiLevel() == level)   // For example, abc FED 123 ^ CBA
                     break;
 
-                // For example, abc 123 ^ CBA
-                while (InlineBox* nextBox = box->nextLeafChild()) {
-                    if (nextBox->bidiLevel() < level)
-                        break;
-                    box = nextBox;
-                }
+                // For example, abc 123 ^ CBA or 123 ^ CBA abc
+                box = nextBox;
                 renderer = box->renderer();
                 offset = box->caretLeftmostOffset();
                 if (box->direction() == primaryDirection)
                 renderer = box->renderer();
                 offset = box->caretLeftmostOffset();
                 if (box->direction() == primaryDirection)