mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Disallow mutating the internals of TextInput
The TextInput::assert_ok_selection() method is meant to ensure that we are not getting into a state where a selection refers to a location in the control's contents which doesn't exist. However, before this change we could have a situation where the internals of the TextInput are changed by another part of the code, without using its public API. This could lead to us having an invalid selection. I did manage to trigger such a situation (see the test added in this commit) although it is quite contrived. There may be others that I didn't think of, and it's also possible that future changes could introduce new cases. (Including ones which trigger panics, if indexing is used on the assumption that the selection indices are always valid.) The current HTML specification doesn't explicitly say that selectionStart/End must remain within the length of the content, but that does seems to be the consensus reached in a discussion of this: https://github.com/whatwg/html/issues/2424 The test case I've added here is currently undefined in the spec which is why I've added it in tests/wpt/mozilla.
This commit is contained in:
parent
7e31ae35e1
commit
32f781234a
7 changed files with 255 additions and 198 deletions
|
@ -42,7 +42,7 @@ fn test_textinput_when_inserting_multiple_lines_over_a_selection_respects_max_le
|
|||
SelectionDirection::None,
|
||||
);
|
||||
|
||||
textinput.edit_point = TextPoint { line: 0, index: 1 };
|
||||
textinput.adjust_horizontal(1, Selection::NotSelected);
|
||||
textinput.adjust_horizontal(3, Selection::Selected);
|
||||
textinput.adjust_vertical(1, Selection::Selected);
|
||||
|
||||
|
@ -67,8 +67,7 @@ fn test_textinput_when_inserting_multiple_lines_still_respects_max_length() {
|
|||
SelectionDirection::None
|
||||
);
|
||||
|
||||
textinput.edit_point = TextPoint { line: 1, index: 0 };
|
||||
|
||||
textinput.adjust_vertical(1, Selection::NotSelected);
|
||||
textinput.insert_string("cruel\nterrible".to_string());
|
||||
|
||||
assert_eq!(textinput.get_content(), "hello\ncruel\nworld");
|
||||
|
@ -117,7 +116,7 @@ fn test_single_line_textinput_with_max_length_doesnt_allow_appending_characters_
|
|||
SelectionDirection::None,
|
||||
);
|
||||
|
||||
textinput.edit_point = TextPoint { line: 0, index: 1 };
|
||||
textinput.adjust_horizontal(1, Selection::NotSelected);
|
||||
textinput.adjust_horizontal(3, Selection::Selected);
|
||||
|
||||
// Selection is now "abcde"
|
||||
|
@ -220,9 +219,7 @@ fn test_textinput_delete_char() {
|
|||
assert_eq!(textinput.get_content(), "ab");
|
||||
|
||||
let mut textinput = text_input(Lines::Single, "abcdefg");
|
||||
textinput.adjust_horizontal(2, Selection::NotSelected);
|
||||
// Set an empty selection range.
|
||||
textinput.selection_origin = Some(textinput.edit_point);
|
||||
textinput.set_selection_range(2, 2, SelectionDirection::None);
|
||||
textinput.delete_char(Direction::Backward);
|
||||
assert_eq!(textinput.get_content(), "acdefg");
|
||||
}
|
||||
|
@ -300,16 +297,16 @@ fn test_textinput_adjust_vertical() {
|
|||
let mut textinput = text_input(Lines::Multiple, "abc\nde\nf");
|
||||
textinput.adjust_horizontal(3, Selection::NotSelected);
|
||||
textinput.adjust_vertical(1, Selection::NotSelected);
|
||||
assert_eq!(textinput.edit_point.line, 1);
|
||||
assert_eq!(textinput.edit_point.index, 2);
|
||||
assert_eq!(textinput.edit_point().line, 1);
|
||||
assert_eq!(textinput.edit_point().index, 2);
|
||||
|
||||
textinput.adjust_vertical(-1, Selection::NotSelected);
|
||||
assert_eq!(textinput.edit_point.line, 0);
|
||||
assert_eq!(textinput.edit_point.index, 2);
|
||||
assert_eq!(textinput.edit_point().line, 0);
|
||||
assert_eq!(textinput.edit_point().index, 2);
|
||||
|
||||
textinput.adjust_vertical(2, Selection::NotSelected);
|
||||
assert_eq!(textinput.edit_point.line, 2);
|
||||
assert_eq!(textinput.edit_point.index, 1);
|
||||
assert_eq!(textinput.edit_point().line, 2);
|
||||
assert_eq!(textinput.edit_point().index, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -317,32 +314,32 @@ fn test_textinput_adjust_vertical_multibyte() {
|
|||
let mut textinput = text_input(Lines::Multiple, "áé\nae");
|
||||
|
||||
textinput.adjust_horizontal_by_one(Direction::Forward, Selection::NotSelected);
|
||||
assert_eq!(textinput.edit_point.line, 0);
|
||||
assert_eq!(textinput.edit_point.index, 2);
|
||||
assert_eq!(textinput.edit_point().line, 0);
|
||||
assert_eq!(textinput.edit_point().index, 2);
|
||||
|
||||
textinput.adjust_vertical(1, Selection::NotSelected);
|
||||
assert_eq!(textinput.edit_point.line, 1);
|
||||
assert_eq!(textinput.edit_point.index, 1);
|
||||
assert_eq!(textinput.edit_point().line, 1);
|
||||
assert_eq!(textinput.edit_point().index, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_textinput_adjust_horizontal() {
|
||||
let mut textinput = text_input(Lines::Multiple, "abc\nde\nf");
|
||||
textinput.adjust_horizontal(4, Selection::NotSelected);
|
||||
assert_eq!(textinput.edit_point.line, 1);
|
||||
assert_eq!(textinput.edit_point.index, 0);
|
||||
assert_eq!(textinput.edit_point().line, 1);
|
||||
assert_eq!(textinput.edit_point().index, 0);
|
||||
|
||||
textinput.adjust_horizontal(1, Selection::NotSelected);
|
||||
assert_eq!(textinput.edit_point.line, 1);
|
||||
assert_eq!(textinput.edit_point.index, 1);
|
||||
assert_eq!(textinput.edit_point().line, 1);
|
||||
assert_eq!(textinput.edit_point().index, 1);
|
||||
|
||||
textinput.adjust_horizontal(2, Selection::NotSelected);
|
||||
assert_eq!(textinput.edit_point.line, 2);
|
||||
assert_eq!(textinput.edit_point.index, 0);
|
||||
assert_eq!(textinput.edit_point().line, 2);
|
||||
assert_eq!(textinput.edit_point().index, 0);
|
||||
|
||||
textinput.adjust_horizontal(-1, Selection::NotSelected);
|
||||
assert_eq!(textinput.edit_point.line, 1);
|
||||
assert_eq!(textinput.edit_point.index, 2);
|
||||
assert_eq!(textinput.edit_point().line, 1);
|
||||
assert_eq!(textinput.edit_point().index, 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -351,45 +348,45 @@ fn test_textinput_adjust_horizontal_by_word() {
|
|||
let mut textinput = text_input(Lines::Single, "abc def");
|
||||
textinput.adjust_horizontal_by_word(Direction::Forward, Selection::NotSelected);
|
||||
textinput.adjust_horizontal_by_word(Direction::Forward, Selection::NotSelected);
|
||||
assert_eq!(textinput.edit_point.line, 0);
|
||||
assert_eq!(textinput.edit_point.index, 7);
|
||||
assert_eq!(textinput.edit_point().line, 0);
|
||||
assert_eq!(textinput.edit_point().index, 7);
|
||||
textinput.adjust_horizontal_by_word(Direction::Backward, Selection::NotSelected);
|
||||
assert_eq!(textinput.edit_point.line, 0);
|
||||
assert_eq!(textinput.edit_point.index, 4);
|
||||
assert_eq!(textinput.edit_point().line, 0);
|
||||
assert_eq!(textinput.edit_point().index, 4);
|
||||
textinput.adjust_horizontal_by_word(Direction::Backward, Selection::NotSelected);
|
||||
assert_eq!(textinput.edit_point.line, 0);
|
||||
assert_eq!(textinput.edit_point.index, 0);
|
||||
assert_eq!(textinput.edit_point().line, 0);
|
||||
assert_eq!(textinput.edit_point().index, 0);
|
||||
|
||||
// Test new line case of movement word by word based on UAX#29 rules
|
||||
let mut textinput_2 = text_input(Lines::Multiple, "abc\ndef");
|
||||
textinput_2.adjust_horizontal_by_word(Direction::Forward, Selection::NotSelected);
|
||||
textinput_2.adjust_horizontal_by_word(Direction::Forward, Selection::NotSelected);
|
||||
assert_eq!(textinput_2.edit_point.line, 1);
|
||||
assert_eq!(textinput_2.edit_point.index, 3);
|
||||
assert_eq!(textinput_2.edit_point().line, 1);
|
||||
assert_eq!(textinput_2.edit_point().index, 3);
|
||||
textinput_2.adjust_horizontal_by_word(Direction::Backward, Selection::NotSelected);
|
||||
assert_eq!(textinput_2.edit_point.line, 1);
|
||||
assert_eq!(textinput_2.edit_point.index, 0);
|
||||
assert_eq!(textinput_2.edit_point().line, 1);
|
||||
assert_eq!(textinput_2.edit_point().index, 0);
|
||||
textinput_2.adjust_horizontal_by_word(Direction::Backward, Selection::NotSelected);
|
||||
assert_eq!(textinput_2.edit_point.line, 0);
|
||||
assert_eq!(textinput_2.edit_point.index, 0);
|
||||
assert_eq!(textinput_2.edit_point().line, 0);
|
||||
assert_eq!(textinput_2.edit_point().index, 0);
|
||||
|
||||
// Test non-standard sized characters case of movement word by word based on UAX#29 rules
|
||||
let mut textinput_3 = text_input(Lines::Single, "áéc d🌠bc");
|
||||
textinput_3.adjust_horizontal_by_word(Direction::Forward, Selection::NotSelected);
|
||||
assert_eq!(textinput_3.edit_point.line, 0);
|
||||
assert_eq!(textinput_3.edit_point.index, 5);
|
||||
assert_eq!(textinput_3.edit_point().line, 0);
|
||||
assert_eq!(textinput_3.edit_point().index, 5);
|
||||
textinput_3.adjust_horizontal_by_word(Direction::Forward, Selection::NotSelected);
|
||||
assert_eq!(textinput_3.edit_point.line, 0);
|
||||
assert_eq!(textinput_3.edit_point.index, 7);
|
||||
assert_eq!(textinput_3.edit_point().line, 0);
|
||||
assert_eq!(textinput_3.edit_point().index, 7);
|
||||
textinput_3.adjust_horizontal_by_word(Direction::Forward, Selection::NotSelected);
|
||||
assert_eq!(textinput_3.edit_point.line, 0);
|
||||
assert_eq!(textinput_3.edit_point.index, 13);
|
||||
assert_eq!(textinput_3.edit_point().line, 0);
|
||||
assert_eq!(textinput_3.edit_point().index, 13);
|
||||
textinput_3.adjust_horizontal_by_word(Direction::Backward, Selection::NotSelected);
|
||||
assert_eq!(textinput_3.edit_point.line, 0);
|
||||
assert_eq!(textinput_3.edit_point.index, 11);
|
||||
assert_eq!(textinput_3.edit_point().line, 0);
|
||||
assert_eq!(textinput_3.edit_point().index, 11);
|
||||
textinput_3.adjust_horizontal_by_word(Direction::Backward, Selection::NotSelected);
|
||||
assert_eq!(textinput_3.edit_point.line, 0);
|
||||
assert_eq!(textinput_3.edit_point.index, 6);
|
||||
assert_eq!(textinput_3.edit_point().line, 0);
|
||||
assert_eq!(textinput_3.edit_point().index, 6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -397,29 +394,29 @@ fn test_textinput_adjust_horizontal_to_line_end() {
|
|||
// Test standard case of movement to end based on UAX#29 rules
|
||||
let mut textinput = text_input(Lines::Single, "abc def");
|
||||
textinput.adjust_horizontal_to_line_end(Direction::Forward, Selection::NotSelected);
|
||||
assert_eq!(textinput.edit_point.line, 0);
|
||||
assert_eq!(textinput.edit_point.index, 7);
|
||||
assert_eq!(textinput.edit_point().line, 0);
|
||||
assert_eq!(textinput.edit_point().index, 7);
|
||||
|
||||
// Test new line case of movement to end based on UAX#29 rules
|
||||
let mut textinput_2 = text_input(Lines::Multiple, "abc\ndef");
|
||||
textinput_2.adjust_horizontal_to_line_end(Direction::Forward, Selection::NotSelected);
|
||||
assert_eq!(textinput_2.edit_point.line, 0);
|
||||
assert_eq!(textinput_2.edit_point.index, 3);
|
||||
assert_eq!(textinput_2.edit_point().line, 0);
|
||||
assert_eq!(textinput_2.edit_point().index, 3);
|
||||
textinput_2.adjust_horizontal_to_line_end(Direction::Forward, Selection::NotSelected);
|
||||
assert_eq!(textinput_2.edit_point.line, 0);
|
||||
assert_eq!(textinput_2.edit_point.index, 3);
|
||||
assert_eq!(textinput_2.edit_point().line, 0);
|
||||
assert_eq!(textinput_2.edit_point().index, 3);
|
||||
textinput_2.adjust_horizontal_to_line_end(Direction::Backward, Selection::NotSelected);
|
||||
assert_eq!(textinput_2.edit_point.line, 0);
|
||||
assert_eq!(textinput_2.edit_point.index, 0);
|
||||
assert_eq!(textinput_2.edit_point().line, 0);
|
||||
assert_eq!(textinput_2.edit_point().index, 0);
|
||||
|
||||
// Test non-standard sized characters case of movement to end based on UAX#29 rules
|
||||
let mut textinput_3 = text_input(Lines::Single, "áéc d🌠bc");
|
||||
textinput_3.adjust_horizontal_to_line_end(Direction::Forward, Selection::NotSelected);
|
||||
assert_eq!(textinput_3.edit_point.line, 0);
|
||||
assert_eq!(textinput_3.edit_point.index, 13);
|
||||
assert_eq!(textinput_3.edit_point().line, 0);
|
||||
assert_eq!(textinput_3.edit_point().index, 13);
|
||||
textinput_3.adjust_horizontal_to_line_end(Direction::Backward, Selection::NotSelected);
|
||||
assert_eq!(textinput_3.edit_point.line, 0);
|
||||
assert_eq!(textinput_3.edit_point.index, 0);
|
||||
assert_eq!(textinput_3.edit_point().line, 0);
|
||||
assert_eq!(textinput_3.edit_point().index, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -429,29 +426,29 @@ fn test_navigation_keyboard_shortcuts() {
|
|||
|
||||
// Test that CMD + Right moves to the end of the current line.
|
||||
textinput.handle_keydown_aux(None, Key::Right, KeyModifiers::SUPER);
|
||||
assert_eq!(textinput.edit_point.index, 11);
|
||||
assert_eq!(textinput.edit_point().index, 11);
|
||||
// Test that CMD + Right moves to the beginning of the current line.
|
||||
textinput.handle_keydown_aux(None, Key::Left, KeyModifiers::SUPER);
|
||||
assert_eq!(textinput.edit_point.index, 0);
|
||||
assert_eq!(textinput.edit_point().index, 0);
|
||||
// Test that CTRL + ALT + E moves to the end of the current line also.
|
||||
textinput.handle_keydown_aux(None, Key::E, KeyModifiers::CONTROL | KeyModifiers::ALT);
|
||||
assert_eq!(textinput.edit_point.index, 11);
|
||||
assert_eq!(textinput.edit_point().index, 11);
|
||||
// Test that CTRL + ALT + A moves to the beginning of the current line also.
|
||||
textinput.handle_keydown_aux(None, Key::A, KeyModifiers::CONTROL | KeyModifiers::ALT);
|
||||
assert_eq!(textinput.edit_point.index, 0);
|
||||
assert_eq!(textinput.edit_point().index, 0);
|
||||
|
||||
// Test that ALT + Right moves to the end of the word.
|
||||
textinput.handle_keydown_aux(None, Key::Right, KeyModifiers::ALT);
|
||||
assert_eq!(textinput.edit_point.index, 5);
|
||||
assert_eq!(textinput.edit_point().index, 5);
|
||||
// Test that CTRL + ALT + F moves to the end of the word also.
|
||||
textinput.handle_keydown_aux(None, Key::F, KeyModifiers::CONTROL | KeyModifiers::ALT);
|
||||
assert_eq!(textinput.edit_point.index, 11);
|
||||
assert_eq!(textinput.edit_point().index, 11);
|
||||
// Test that ALT + Left moves to the end of the word.
|
||||
textinput.handle_keydown_aux(None, Key::Left, KeyModifiers::ALT);
|
||||
assert_eq!(textinput.edit_point.index, 6);
|
||||
assert_eq!(textinput.edit_point().index, 6);
|
||||
// Test that CTRL + ALT + B moves to the end of the word also.
|
||||
textinput.handle_keydown_aux(None, Key::B, KeyModifiers::CONTROL | KeyModifiers::ALT);
|
||||
assert_eq!(textinput.edit_point.index, 0);
|
||||
assert_eq!(textinput.edit_point().index, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -470,12 +467,12 @@ fn test_textinput_handle_return() {
|
|||
#[test]
|
||||
fn test_textinput_select_all() {
|
||||
let mut textinput = text_input(Lines::Multiple, "abc\nde\nf");
|
||||
assert_eq!(textinput.edit_point.line, 0);
|
||||
assert_eq!(textinput.edit_point.index, 0);
|
||||
assert_eq!(textinput.edit_point().line, 0);
|
||||
assert_eq!(textinput.edit_point().index, 0);
|
||||
|
||||
textinput.select_all();
|
||||
assert_eq!(textinput.edit_point.line, 2);
|
||||
assert_eq!(textinput.edit_point.index, 1);
|
||||
assert_eq!(textinput.edit_point().line, 2);
|
||||
assert_eq!(textinput.edit_point().index, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -495,15 +492,15 @@ fn test_textinput_set_content() {
|
|||
textinput.set_content(DOMString::from("abc\nf"), true);
|
||||
assert_eq!(textinput.get_content(), "abc\nf");
|
||||
|
||||
assert_eq!(textinput.edit_point.line, 0);
|
||||
assert_eq!(textinput.edit_point.index, 0);
|
||||
assert_eq!(textinput.edit_point().line, 0);
|
||||
assert_eq!(textinput.edit_point().index, 0);
|
||||
textinput.adjust_horizontal(3, Selection::Selected);
|
||||
assert_eq!(textinput.edit_point.line, 0);
|
||||
assert_eq!(textinput.edit_point.index, 3);
|
||||
assert_eq!(textinput.edit_point().line, 0);
|
||||
assert_eq!(textinput.edit_point().index, 3);
|
||||
textinput.set_content(DOMString::from("de"), true);
|
||||
assert_eq!(textinput.get_content(), "de");
|
||||
assert_eq!(textinput.edit_point.line, 0);
|
||||
assert_eq!(textinput.edit_point.index, 2);
|
||||
assert_eq!(textinput.edit_point().line, 0);
|
||||
assert_eq!(textinput.edit_point().index, 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -520,7 +517,7 @@ fn test_clipboard_paste() {
|
|||
None,
|
||||
SelectionDirection::None);
|
||||
assert_eq!(textinput.get_content(), "defg");
|
||||
assert_eq!(textinput.edit_point.index, 0);
|
||||
assert_eq!(textinput.edit_point().index, 0);
|
||||
textinput.handle_keydown_aux(Some('v'), Key::V, MODIFIERS);
|
||||
assert_eq!(textinput.get_content(), "abcdefg");
|
||||
}
|
||||
|
@ -532,23 +529,23 @@ fn test_textinput_cursor_position_correct_after_clearing_selection() {
|
|||
// Single line - Forward
|
||||
textinput.adjust_horizontal(3, Selection::Selected);
|
||||
textinput.adjust_horizontal(1, Selection::NotSelected);
|
||||
assert_eq!(textinput.edit_point.index, 3);
|
||||
assert_eq!(textinput.edit_point().index, 3);
|
||||
|
||||
textinput.adjust_horizontal(-3, Selection::NotSelected);
|
||||
textinput.adjust_horizontal(3, Selection::Selected);
|
||||
textinput.adjust_horizontal_by_one(Direction::Forward, Selection::NotSelected);
|
||||
assert_eq!(textinput.edit_point.index, 3);
|
||||
assert_eq!(textinput.edit_point().index, 3);
|
||||
|
||||
// Single line - Backward
|
||||
textinput.adjust_horizontal(-3, Selection::NotSelected);
|
||||
textinput.adjust_horizontal(3, Selection::Selected);
|
||||
textinput.adjust_horizontal(-1, Selection::NotSelected);
|
||||
assert_eq!(textinput.edit_point.index, 0);
|
||||
assert_eq!(textinput.edit_point().index, 0);
|
||||
|
||||
textinput.adjust_horizontal(-3, Selection::NotSelected);
|
||||
textinput.adjust_horizontal(3, Selection::Selected);
|
||||
textinput.adjust_horizontal_by_one(Direction::Backward, Selection::NotSelected);
|
||||
assert_eq!(textinput.edit_point.index, 0);
|
||||
assert_eq!(textinput.edit_point().index, 0);
|
||||
|
||||
|
||||
let mut textinput = text_input(Lines::Multiple, "abc\nde\nf");
|
||||
|
@ -556,27 +553,27 @@ fn test_textinput_cursor_position_correct_after_clearing_selection() {
|
|||
// Multiline - Forward
|
||||
textinput.adjust_horizontal(4, Selection::Selected);
|
||||
textinput.adjust_horizontal(1, Selection::NotSelected);
|
||||
assert_eq!(textinput.edit_point.index, 0);
|
||||
assert_eq!(textinput.edit_point.line, 1);
|
||||
assert_eq!(textinput.edit_point().index, 0);
|
||||
assert_eq!(textinput.edit_point().line, 1);
|
||||
|
||||
textinput.adjust_horizontal(-4, Selection::NotSelected);
|
||||
textinput.adjust_horizontal(4, Selection::Selected);
|
||||
textinput.adjust_horizontal_by_one(Direction::Forward, Selection::NotSelected);
|
||||
assert_eq!(textinput.edit_point.index, 0);
|
||||
assert_eq!(textinput.edit_point.line, 1);
|
||||
assert_eq!(textinput.edit_point().index, 0);
|
||||
assert_eq!(textinput.edit_point().line, 1);
|
||||
|
||||
// Multiline - Backward
|
||||
textinput.adjust_horizontal(-4, Selection::NotSelected);
|
||||
textinput.adjust_horizontal(4, Selection::Selected);
|
||||
textinput.adjust_horizontal(-1, Selection::NotSelected);
|
||||
assert_eq!(textinput.edit_point.index, 0);
|
||||
assert_eq!(textinput.edit_point.line, 0);
|
||||
assert_eq!(textinput.edit_point().index, 0);
|
||||
assert_eq!(textinput.edit_point().line, 0);
|
||||
|
||||
textinput.adjust_horizontal(-4, Selection::NotSelected);
|
||||
textinput.adjust_horizontal(4, Selection::Selected);
|
||||
textinput.adjust_horizontal_by_one(Direction::Backward, Selection::NotSelected);
|
||||
assert_eq!(textinput.edit_point.index, 0);
|
||||
assert_eq!(textinput.edit_point.line, 0);
|
||||
assert_eq!(textinput.edit_point().index, 0);
|
||||
assert_eq!(textinput.edit_point().line, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -584,53 +581,53 @@ fn test_textinput_cursor_position_correct_after_clearing_selection() {
|
|||
fn test_textinput_set_selection_with_direction() {
|
||||
let mut textinput = text_input(Lines::Single, "abcdef");
|
||||
textinput.set_selection_range(2, 6, SelectionDirection::Forward);
|
||||
assert_eq!(textinput.edit_point.line, 0);
|
||||
assert_eq!(textinput.edit_point.index, 6);
|
||||
assert_eq!(textinput.selection_direction, SelectionDirection::Forward);
|
||||
assert_eq!(textinput.edit_point().line, 0);
|
||||
assert_eq!(textinput.edit_point().index, 6);
|
||||
assert_eq!(textinput.selection_direction(), SelectionDirection::Forward);
|
||||
|
||||
assert!(textinput.selection_origin.is_some());
|
||||
assert_eq!(textinput.selection_origin.unwrap().line, 0);
|
||||
assert_eq!(textinput.selection_origin.unwrap().index, 2);
|
||||
assert!(textinput.selection_origin().is_some());
|
||||
assert_eq!(textinput.selection_origin().unwrap().line, 0);
|
||||
assert_eq!(textinput.selection_origin().unwrap().index, 2);
|
||||
|
||||
textinput.set_selection_range(2, 6, SelectionDirection::Backward);
|
||||
assert_eq!(textinput.edit_point.line, 0);
|
||||
assert_eq!(textinput.edit_point.index, 2);
|
||||
assert_eq!(textinput.selection_direction, SelectionDirection::Backward);
|
||||
assert_eq!(textinput.edit_point().line, 0);
|
||||
assert_eq!(textinput.edit_point().index, 2);
|
||||
assert_eq!(textinput.selection_direction(), SelectionDirection::Backward);
|
||||
|
||||
assert!(textinput.selection_origin.is_some());
|
||||
assert_eq!(textinput.selection_origin.unwrap().line, 0);
|
||||
assert_eq!(textinput.selection_origin.unwrap().index, 6);
|
||||
assert!(textinput.selection_origin().is_some());
|
||||
assert_eq!(textinput.selection_origin().unwrap().line, 0);
|
||||
assert_eq!(textinput.selection_origin().unwrap().index, 6);
|
||||
|
||||
textinput = text_input(Lines::Multiple, "\n\n");
|
||||
textinput.set_selection_range(0, 1, SelectionDirection::Forward);
|
||||
assert_eq!(textinput.edit_point.line, 1);
|
||||
assert_eq!(textinput.edit_point.index, 0);
|
||||
assert_eq!(textinput.selection_direction, SelectionDirection::Forward);
|
||||
assert_eq!(textinput.edit_point().line, 1);
|
||||
assert_eq!(textinput.edit_point().index, 0);
|
||||
assert_eq!(textinput.selection_direction(), SelectionDirection::Forward);
|
||||
|
||||
assert!(textinput.selection_origin.is_some());
|
||||
assert_eq!(textinput.selection_origin.unwrap().line, 0);
|
||||
assert_eq!(textinput.selection_origin.unwrap().index, 0);
|
||||
assert!(textinput.selection_origin().is_some());
|
||||
assert_eq!(textinput.selection_origin().unwrap().line, 0);
|
||||
assert_eq!(textinput.selection_origin().unwrap().index, 0);
|
||||
|
||||
textinput = text_input(Lines::Multiple, "\n");
|
||||
textinput.set_selection_range(0, 1, SelectionDirection::Forward);
|
||||
assert_eq!(textinput.edit_point.line, 1);
|
||||
assert_eq!(textinput.edit_point.index, 0);
|
||||
assert_eq!(textinput.selection_direction, SelectionDirection::Forward);
|
||||
assert_eq!(textinput.edit_point().line, 1);
|
||||
assert_eq!(textinput.edit_point().index, 0);
|
||||
assert_eq!(textinput.selection_direction(), SelectionDirection::Forward);
|
||||
|
||||
assert!(textinput.selection_origin.is_some());
|
||||
assert_eq!(textinput.selection_origin.unwrap().line, 0);
|
||||
assert_eq!(textinput.selection_origin.unwrap().index, 0);
|
||||
assert!(textinput.selection_origin().is_some());
|
||||
assert_eq!(textinput.selection_origin().unwrap().line, 0);
|
||||
assert_eq!(textinput.selection_origin().unwrap().index, 0);
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_textinput_unicode_handling() {
|
||||
let mut textinput = text_input(Lines::Single, "éèùµ$£");
|
||||
assert_eq!(textinput.edit_point.index, 0);
|
||||
assert_eq!(textinput.edit_point().index, 0);
|
||||
textinput.set_edit_point_index(1);
|
||||
assert_eq!(textinput.edit_point.index, 2);
|
||||
assert_eq!(textinput.edit_point().index, 2);
|
||||
textinput.set_edit_point_index(4);
|
||||
assert_eq!(textinput.edit_point.index, 8);
|
||||
assert_eq!(textinput.edit_point().index, 8);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -39947,6 +39947,12 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"mozilla/textcontrol-selection-cannot-exceed-content.html": [
|
||||
[
|
||||
"/_mozilla/mozilla/textcontrol-selection-cannot-exceed-content.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"mozilla/timeout-in-discarded-document.html": [
|
||||
[
|
||||
"/_mozilla/mozilla/timeout-in-discarded-document.html",
|
||||
|
@ -71956,6 +71962,10 @@
|
|||
"094fbd794b78520d6c2d8aae549557bed3529a7a",
|
||||
"testharness"
|
||||
],
|
||||
"mozilla/textcontrol-selection-cannot-exceed-content.html": [
|
||||
"f8b982ba0abb23f8e53ef28413e8da2f8dd7ca17",
|
||||
"testharness"
|
||||
],
|
||||
"mozilla/timeout-in-discarded-document.html": [
|
||||
"7ff88491f20ee72ed40aa5ce4e84840b98d5eef5",
|
||||
"testharness"
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>The selection bounds of a text control should never exceed the content</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<input type="text" value="lorem ">
|
||||
|
||||
<script>
|
||||
test(() => {
|
||||
const el = document.querySelector("input");
|
||||
|
||||
el.setSelectionRange("lorem".length + 1, "lorem".length + 2);
|
||||
|
||||
assert_equals(el.selectionStart, "lorem".length + 1);
|
||||
assert_equals(el.selectionEnd, "lorem".length + 2);
|
||||
|
||||
// This will invoke the value sanitization algorithm for a url field, which strips trailing
|
||||
// whitespace from the raw value.
|
||||
el.type = "url";
|
||||
|
||||
assert_equals(el.selectionStart, "lorem".length);
|
||||
assert_equals(el.selectionEnd, "lorem".length);
|
||||
});
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue