Don't fire select event when selection hasn't changed

This commit is contained in:
Jon Leighton 2017-12-09 22:23:47 +01:00
parent 648bfbeb02
commit e34f7c58c9
3 changed files with 19 additions and 98 deletions

View file

@ -136,6 +136,9 @@ pub trait TextControl: DerivedFrom<EventTarget> + DerivedFrom<Node> {
// https://html.spec.whatwg.org/multipage/#set-the-selection-range
fn set_selection_range(&self, start: Option<u32>, end: Option<u32>, direction: Option<SelectionDirection>) {
let mut textinput = self.textinput().borrow_mut();
let original_selection_state = textinput.selection_state();
// Step 1
let start = start.unwrap_or(0);
@ -143,16 +146,18 @@ pub trait TextControl: DerivedFrom<EventTarget> + DerivedFrom<Node> {
let end = end.unwrap_or(0);
// Steps 3-5
self.textinput().borrow_mut().set_selection_range(start, end, direction.unwrap_or(SelectionDirection::None));
textinput.set_selection_range(start, end, direction.unwrap_or(SelectionDirection::None));
// Step 6
let window = window_from_node(self);
let _ = window.user_interaction_task_source().queue_event(
&self.upcast::<EventTarget>(),
atom!("select"),
EventBubbles::Bubbles,
EventCancelable::NotCancelable,
&window);
if textinput.selection_state() != original_selection_state {
let window = window_from_node(self);
window.user_interaction_task_source().queue_event(
&self.upcast::<EventTarget>(),
atom!("select"),
EventBubbles::Bubbles,
EventCancelable::NotCancelable,
&window);
}
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
}

View file

@ -242,6 +242,12 @@ impl<T: ClipboardProvider> TextInput<T> {
self.selection_start_offset() .. self.selection_end_offset()
}
/// A tuple containing the (start, end, direction) of the current selection. Can be used to
/// compare whether selection state has changed.
pub fn selection_state(&self) -> (TextPoint, TextPoint, SelectionDirection) {
(self.selection_start(), self.selection_end(), self.selection_direction)
}
// Check that the selection is valid.
fn assert_ok_selection(&self) {
if let Some(begin) = self.selection_origin {

View file

@ -1,125 +1,35 @@
[select-event.html]
type: testharness
[textarea: select() a second time (must not fire select)]
expected: FAIL
[textarea: selectionStart a second time (must not fire select)]
expected: FAIL
[textarea: selectionEnd a second time (must not fire select)]
expected: FAIL
[textarea: selectionDirection a second time (must not fire select)]
expected: FAIL
[textarea: setSelectionRange() a second time (must not fire select)]
expected: FAIL
[textarea: setRangeText()]
expected: FAIL
[textarea: setRangeText() a second time (must not fire select)]
expected: FAIL
[input type text: select() a second time (must not fire select)]
expected: FAIL
[input type text: selectionStart a second time (must not fire select)]
expected: FAIL
[input type text: selectionEnd a second time (must not fire select)]
expected: FAIL
[input type text: selectionDirection a second time (must not fire select)]
expected: FAIL
[input type text: setSelectionRange() a second time (must not fire select)]
expected: FAIL
[input type text: setRangeText()]
expected: FAIL
[input type text: setRangeText() a second time (must not fire select)]
expected: FAIL
[input type search: select() a second time (must not fire select)]
expected: FAIL
[input type search: selectionStart a second time (must not fire select)]
expected: FAIL
[input type search: selectionEnd a second time (must not fire select)]
expected: FAIL
[input type search: selectionDirection a second time (must not fire select)]
expected: FAIL
[input type search: setSelectionRange() a second time (must not fire select)]
expected: FAIL
[input type search: setRangeText()]
expected: FAIL
[input type search: setRangeText() a second time (must not fire select)]
expected: FAIL
[input type tel: select() a second time (must not fire select)]
expected: FAIL
[input type tel: selectionStart a second time (must not fire select)]
expected: FAIL
[input type tel: selectionEnd a second time (must not fire select)]
expected: FAIL
[input type tel: selectionDirection a second time (must not fire select)]
expected: FAIL
[input type tel: setSelectionRange() a second time (must not fire select)]
expected: FAIL
[input type tel: setRangeText()]
expected: FAIL
[input type tel: setRangeText() a second time (must not fire select)]
expected: FAIL
[input type url: select() a second time (must not fire select)]
expected: FAIL
[input type url: selectionStart a second time (must not fire select)]
expected: FAIL
[input type url: selectionEnd a second time (must not fire select)]
expected: FAIL
[input type url: selectionDirection a second time (must not fire select)]
expected: FAIL
[input type url: setSelectionRange() a second time (must not fire select)]
expected: FAIL
[input type url: setRangeText()]
expected: FAIL
[input type url: setRangeText() a second time (must not fire select)]
expected: FAIL
[input type password: select() a second time (must not fire select)]
expected: FAIL
[input type password: selectionStart a second time (must not fire select)]
expected: FAIL
[input type password: selectionEnd a second time (must not fire select)]
expected: FAIL
[input type password: selectionDirection a second time (must not fire select)]
expected: FAIL
[input type password: setSelectionRange() a second time (must not fire select)]
expected: FAIL
[input type password: setRangeText()]
expected: FAIL