| <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> |
| <html> |
| <head> |
| <script src="../../resources/js-test-pre.js"></script> |
| <meta charset="UTF-16"> |
| </head> |
| <style> |
| .userselect { user-select: none; -webkit-user-select: none; } |
| </style> |
| <body id="body"> |
| |
| <div id="text" tabindex="0">text</div> |
| <br> |
| text1 |
| |
| <div id="text2"> |
| c <img src="#" aria-label="blah" style="background-color: #aaaaaa; width: 100px; height: 100px;"> d |
| </div> |
| |
| <input type="password" id="psw"> |
| |
| <div class="userselect" id="text3">can't select</div> |
| |
| <div id="text4"> |
| abc |
| de |
| f |
| </div> |
| |
| <p id="text5">😃😏<p> |
| |
| <p id="text6">a b</p> |
| |
| <p id="description"></p> |
| <div id="console"></div> |
| |
| <script> |
| |
| description("This tests the next/previous text marker functions are implemented correctly."); |
| |
| if (window.accessibilityController) { |
| |
| var text = accessibilityController.accessibleElementById("text"); |
| // Get the actual text node. |
| text = text.childAtIndex(0); |
| |
| // Check that we can get the start/end marker for this range. |
| var textMarkerRange = text.textMarkerRangeForElement(text); |
| shouldBe("text.textMarkerRangeLength(textMarkerRange)", "4"); |
| |
| var startMarker = text.startTextMarkerForTextMarkerRange(textMarkerRange); |
| var endMarker = text.endTextMarkerForTextMarkerRange(textMarkerRange); |
| shouldBeTrue("text.accessibilityElementForTextMarker(startMarker).isEqual(text)"); |
| shouldBeTrue("text.accessibilityElementForTextMarker(endMarker).isEqual(text)"); |
| |
| // Check next text marker. (Advance 5 characters, it will land at <br>.) |
| var currentMarker, previousMarker, markerRange;; |
| var result = forward(5, previousMarker, startMarker, text); |
| previousMarker = result.previous; |
| currentMarker = result.current; |
| markerRange = text.textMarkerRangeForMarkers(previousMarker, currentMarker); |
| var newline = '\n'; |
| shouldBe("text.stringForTextMarkerRange(markerRange)", "newline"); |
| |
| // Advance one more characters, it will lande at "t" in "text1". |
| result = forward(1, previousMarker, currentMarker, text); |
| previousMarker = result.previous; |
| currentMarker = result.current; |
| markerRange = text.textMarkerRangeForMarkers(previousMarker, currentMarker); |
| shouldBe("text.stringForTextMarkerRange(markerRange)", "'t'"); |
| |
| // Check previous text marker. (Traverse backwards one character, it will land at <br>.) |
| result = backwards(1, previousMarker, currentMarker, text); |
| previousMarker = result.previous; |
| currentMarker = result.current; |
| markerRange = text.textMarkerRangeForMarkers(previousMarker, currentMarker); |
| shouldBe("text.stringForTextMarkerRange(markerRange)", "newline"); |
| |
| // Traverse backwards one more character, it will land at the last character of "text". |
| result = backwards(1, previousMarker, currentMarker, text); |
| previousMarker = result.previous; |
| currentMarker = result.current; |
| markerRange = text.textMarkerRangeForMarkers(previousMarker, currentMarker); |
| shouldBe("text.stringForTextMarkerRange(markerRange)", "'t'"); |
| |
| // Check the case with replaced node |
| var text2 = accessibilityController.accessibleElementById("text2"); |
| var textMarkerRange2 = text2.textMarkerRangeForElement(text2); |
| shouldBe("text2.textMarkerRangeLength(textMarkerRange2)", "5"); |
| var str = text2.stringForTextMarkerRange(textMarkerRange2).replace(String.fromCharCode(65532), "[ATTACHMENT]"); |
| debug("Object string for range: " + str); |
| |
| currentMarker = text2.startTextMarkerForTextMarkerRange(textMarkerRange2); |
| // Advance 5 characters, it will land at "d". |
| result = forward(5, previousMarker, currentMarker, text2); |
| previousMarker = result.previous; |
| currentMarker = result.current; |
| markerRange = text2.textMarkerRangeForMarkers(previousMarker, currentMarker); |
| shouldBe("text2.stringForTextMarkerRange(markerRange)", "'d'"); |
| |
| // Traverse backwards 6 characters, it will land at the last character of "text1". |
| result = backwards(6, previousMarker, currentMarker, text2); |
| previousMarker = result.previous; |
| currentMarker = result.current; |
| markerRange = text2.textMarkerRangeForMarkers(previousMarker, currentMarker); |
| shouldBe("text2.stringForTextMarkerRange(markerRange)", "'1'"); |
| |
| // Check the case with user-select:none, nextTextMarker/previousTextMarker should still work. |
| var text3 = accessibilityController.accessibleElementById("text3"); |
| text3 = text3.childAtIndex(0); |
| |
| // Advance to land at user-select:none node. |
| var marker1, marker2; |
| for (var i = 0; i < 18; i++) { |
| currentMarker = text3.nextTextMarker(currentMarker); |
| // i == 14, it should land on "e", and i == 17, it should land on "t" |
| if (i == 14) { |
| marker1 = currentMarker; |
| } |
| } |
| marker2 = currentMarker; |
| markerRange = text3.textMarkerRangeForMarkers(marker1, marker2); |
| shouldBe("text3.stringForTextMarkerRange(markerRange)", "'ect'"); |
| // Iterate backwards the second marker for 6 characters, the range should be "sel" |
| for (var i = 0; i < 6; i++) { |
| currentMarker = text3.previousTextMarker(currentMarker); |
| } |
| marker2 = currentMarker; |
| markerRange = text3.textMarkerRangeForMarkers(marker1, marker2); |
| shouldBe("text3.stringForTextMarkerRange(markerRange)", "'sel'"); |
| |
| // Check the case with password field. |
| var psw = accessibilityController.accessibleElementById("psw"); |
| var textMarkerRange3 = psw.textMarkerRangeForElement(psw); |
| var start = psw.startTextMarkerForTextMarkerRange(textMarkerRange3); |
| shouldBeTrue("!psw.accessibilityElementForTextMarker(start)"); |
| |
| // Check next/previous text marker call will skip password field |
| // We start from text2 and advance 6 characters, it should skip the password field and land on text3. |
| currentMarker = text2.startTextMarkerForTextMarkerRange(textMarkerRange2); |
| for (var i = 0; i < 6; i++) { |
| currentMarker = text2.nextTextMarker(currentMarker); |
| } |
| shouldBeTrue("text2.accessibilityElementForTextMarker(currentMarker).isEqual(text3)"); |
| // Check previous text marker, it should land on " d" node. |
| currentMarker = text2.previousTextMarker(currentMarker); |
| currentMarker = text2.previousTextMarker(currentMarker); |
| shouldBeTrue("text2.accessibilityElementForTextMarker(currentMarker).isEqual(text2.childAtIndex(2))"); |
| |
| |
| // Make sure that text node with line breaks, we can go through it with next/previous call. |
| text = accessibilityController.accessibleElementById("text4"); |
| textMarkerRange = text.textMarkerRangeForElement(text); |
| startMarker = text.startTextMarkerForTextMarkerRange(textMarkerRange); |
| currentMarker = startMarker; |
| for (var i = 0; i < 8; i++) { |
| previousMarker = currentMarker; |
| currentMarker = text.nextTextMarker(currentMarker); |
| } |
| markerRange = text.textMarkerRangeForMarkers(previousMarker, currentMarker) |
| shouldBe("text.stringForTextMarkerRange(markerRange)", "'f'"); |
| |
| endMarker = text.endTextMarkerForTextMarkerRange(textMarkerRange); |
| currentMarker = endMarker; |
| for (var i = 0; i < 7; i++) { |
| currentMarker = text.previousTextMarker(currentMarker); |
| } |
| markerRange = text.textMarkerRangeForMarkers(startMarker, currentMarker) |
| shouldBe("text.stringForTextMarkerRange(markerRange)", "'a'"); |
| |
| // Test case with emoji. |
| text = accessibilityController.accessibleElementById("text5"); |
| var emojiTextMarkerRange = text.textMarkerRangeForElement(text); |
| shouldBe("text.textMarkerRangeLength(emojiTextMarkerRange)", "4"); |
| // Make sure navigating next/previous text marker is by emoji. |
| startMarker = text.startTextMarkerForTextMarkerRange(emojiTextMarkerRange); |
| result = forward(2, previousMarker, startMarker, text); |
| shouldBe("text.stringForTextMarkerRange(text.textMarkerRangeForMarkers(result.previous, result.current))", "'😏'"); |
| result = backwards(1, result.previous, result.current, text); |
| shouldBe("text.stringForTextMarkerRange(text.textMarkerRangeForMarkers(result.previous, result.current))", "'😃'"); |
| |
| // Test case with collapsed whitespace. |
| text = accessibilityController.accessibleElementById("text6"); |
| var collapsedWhitespaceMarkerRange = text.textMarkerRangeForElement(text); |
| shouldBe("text.textMarkerRangeLength(collapsedWhitespaceMarkerRange)", "3"); |
| startMarker = text.startTextMarkerForTextMarkerRange(collapsedWhitespaceMarkerRange); |
| result = forward(1, previousMarker, startMarker, text); |
| shouldBe("text.stringForTextMarkerRange(text.textMarkerRangeForMarkers(result.previous, result.current))", "'a'"); |
| result = forward(1, result.previous, result.current, text); |
| shouldBe("text.stringForTextMarkerRange(text.textMarkerRangeForMarkers(result.previous, result.current))", "' '"); |
| result = forward(1, result.previous, result.current, text); |
| shouldBe("text.stringForTextMarkerRange(text.textMarkerRangeForMarkers(result.previous, result.current))", "'b'"); |
| result = backwards(1, result.previous, result.current, text); |
| shouldBe("text.stringForTextMarkerRange(text.textMarkerRangeForMarkers(result.previous, result.current))", "' '"); |
| result = backwards(1, result.previous, result.current, text); |
| shouldBe("text.stringForTextMarkerRange(text.textMarkerRangeForMarkers(result.previous, result.current))", "'a'"); |
| |
| function forward(count, previousMarker, currentMarker, obj) { |
| for (var i = 0; i < count; i++) { |
| previousMarker = currentMarker; |
| currentMarker = obj.nextTextMarker(currentMarker); |
| } |
| return { |
| previous: previousMarker, |
| current: currentMarker |
| }; |
| } |
| |
| function backwards(count, previousMarker, currentMarker, obj) { |
| for (var i = 0; i < count; i++) { |
| previousMarker = obj.previousTextMarker(previousMarker); |
| currentMarker = obj.previousTextMarker(currentMarker); |
| } |
| return { |
| previous: previousMarker, |
| current: currentMarker |
| }; |
| } |
| } |
| |
| </script> |
| |
| <script src="../../resources/js-test-post.js"></script> |
| </body> |
| </html> |