Skip to content

Commit

Permalink
Don't fire select event when selection hasn't changed
Browse files Browse the repository at this point in the history
  • Loading branch information
jonleighton committed Jan 26, 2018
1 parent 648bfbe commit e34f7c5
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 98 deletions.
21 changes: 13 additions & 8 deletions components/script/dom/textcontrol.rs
Expand Up @@ -136,23 +136,28 @@ 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);

// Step 2
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);
}
Expand Down
6 changes: 6 additions & 0 deletions components/script/textinput.rs
Expand Up @@ -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 {
Expand Down
@@ -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

Expand Down

0 comments on commit e34f7c5

Please sign in to comment.