diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 78afb4630db..e048f419303 100755 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -31,6 +31,7 @@ use dom::mouseevent::MouseEvent; use dom::node::{Node, NodeDamage, UnbindContext}; use dom::node::{document_from_node, window_from_node}; use dom::nodelist::NodeList; +use dom::textcontrol::TextControl; use dom::validation::Validatable; use dom::validitystate::ValidationFlags; use dom::virtualmethods::VirtualMethods; @@ -292,6 +293,12 @@ impl LayoutHTMLInputElementHelpers for LayoutDom { } } +impl TextControl for HTMLInputElement { + fn textinput(&self) -> &DomRefCell> { + &self.textinput + } +} + impl HTMLInputElementMethods for HTMLInputElement { // https://html.spec.whatwg.org/multipage/#dom-input-accept make_getter!(Accept, "accept"); @@ -567,42 +574,39 @@ impl HTMLInputElementMethods for HTMLInputElement { } } - // https://html.spec.whatwg.org/multipage/#dom-input-selectionstart + // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectionstart fn SelectionStart(&self) -> u32 { - self.textinput.borrow().get_selection_start() + self.dom_selection_start() } // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectionstart fn SetSelectionStart(&self, start: u32) { - self.set_selection_range(start, self.SelectionEnd(), self.selection_direction()); + self.set_dom_selection_start(start); } // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectionend fn SelectionEnd(&self) -> u32 { - self.textinput.borrow().get_absolute_insertion_point() as u32 + self.dom_selection_end() } // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectionend fn SetSelectionEnd(&self, end: u32) { - self.set_selection_range(self.SelectionStart(), end, self.selection_direction()); + self.set_dom_selection_end(end) } // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectiondirection fn SelectionDirection(&self) -> DOMString { - DOMString::from(self.textinput.borrow().selection_direction) + self.dom_selection_direction() } // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectiondirection fn SetSelectionDirection(&self, direction: DOMString) { - self.textinput.borrow_mut().selection_direction = SelectionDirection::from(direction); + self.set_dom_selection_direction(direction); } // https://html.spec.whatwg.org/multipage/#dom-textarea/input-setselectionrange fn SetSelectionRange(&self, start: u32, end: u32, direction: Option) { - // Step 4 - let direction = direction.map_or(SelectionDirection::None, |d| SelectionDirection::from(d)); - - self.set_selection_range(start, end, direction); + self.set_dom_selection_range(start, end, direction); } // Select the files based on filepaths passed in, @@ -875,30 +879,6 @@ impl HTMLInputElement { _ => () } } - - fn selection_direction(&self) -> SelectionDirection { - self.textinput.borrow().selection_direction - } - - // https://html.spec.whatwg.org/multipage/#set-the-selection-range - fn set_selection_range(&self, start: u32, end: u32, direction: SelectionDirection) { - // Step 5 - self.textinput.borrow_mut().selection_direction = direction; - - // Step 3 - self.textinput.borrow_mut().set_selection_range(start, end); - - // Step 6 - let window = window_from_node(self); - let _ = window.user_interaction_task_source().queue_event( - &self.upcast(), - atom!("select"), - EventBubbles::Bubbles, - EventCancelable::NotCancelable, - &window); - - self.upcast::().dirty(NodeDamage::OtherNodeDamage); - } } impl VirtualMethods for HTMLInputElement { diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs index ce9c879d664..aa728dc5a1c 100755 --- a/components/script/dom/htmltextareaelement.rs +++ b/components/script/dom/htmltextareaelement.rs @@ -23,6 +23,7 @@ use dom::keyboardevent::KeyboardEvent; use dom::node::{ChildrenMutation, Node, NodeDamage, UnbindContext}; use dom::node::{document_from_node, window_from_node}; use dom::nodelist::NodeList; +use dom::textcontrol::TextControl; use dom::validation::Validatable; use dom::virtualmethods::VirtualMethods; use dom_struct::dom_struct; @@ -140,6 +141,12 @@ impl HTMLTextAreaElement { } } +impl TextControl for HTMLTextAreaElement { + fn textinput(&self) -> &DomRefCell> { + &self.textinput + } +} + impl HTMLTextAreaElementMethods for HTMLTextAreaElement { // TODO A few of these attributes have default values and additional // constraints @@ -237,53 +244,39 @@ impl HTMLTextAreaElementMethods for HTMLTextAreaElement { self.upcast::().labels() } - // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectiondirection - fn SetSelectionDirection(&self, direction: DOMString) { - self.textinput.borrow_mut().selection_direction = SelectionDirection::from(direction); - } - - // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectiondirection - fn SelectionDirection(&self) -> DOMString { - DOMString::from(self.textinput.borrow().selection_direction) - } - - // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectionend - fn SetSelectionEnd(&self, end: u32) { - let selection_start = self.SelectionStart(); - self.textinput.borrow_mut().set_selection_range(selection_start, end); - self.upcast::().dirty(NodeDamage::OtherNodeDamage); - } - - // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectionend - fn SelectionEnd(&self) -> u32 { - self.textinput.borrow().get_absolute_insertion_point() as u32 + // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectionstart + fn SelectionStart(&self) -> u32 { + self.dom_selection_start() } // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectionstart fn SetSelectionStart(&self, start: u32) { - let selection_end = self.SelectionEnd(); - self.textinput.borrow_mut().set_selection_range(start, selection_end); - self.upcast::().dirty(NodeDamage::OtherNodeDamage); + self.set_dom_selection_start(start); } - // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectionstart - fn SelectionStart(&self) -> u32 { - self.textinput.borrow().get_selection_start() + // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectionend + fn SelectionEnd(&self) -> u32 { + self.dom_selection_end() + } + + // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectionend + fn SetSelectionEnd(&self, end: u32) { + self.set_dom_selection_end(end); + } + + // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectiondirection + fn SelectionDirection(&self) -> DOMString { + self.dom_selection_direction() + } + + // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectiondirection + fn SetSelectionDirection(&self, direction: DOMString) { + self.set_dom_selection_direction(direction); } // https://html.spec.whatwg.org/multipage/#dom-textarea/input-setselectionrange fn SetSelectionRange(&self, start: u32, end: u32, direction: Option) { - let direction = direction.map_or(SelectionDirection::None, |d| SelectionDirection::from(d)); - self.textinput.borrow_mut().selection_direction = direction; - self.textinput.borrow_mut().set_selection_range(start, end); - let window = window_from_node(self); - let _ = window.user_interaction_task_source().queue_event( - &self.upcast(), - atom!("select"), - EventBubbles::Bubbles, - EventCancelable::NotCancelable, - &window); - self.upcast::().dirty(NodeDamage::OtherNodeDamage); + self.set_dom_selection_range(start, end, direction); } } diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 4b34a6f3cac..cf10f1e4752 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -439,6 +439,7 @@ pub mod testrunner; pub mod testworklet; pub mod testworkletglobalscope; pub mod text; +pub mod textcontrol; pub mod textdecoder; pub mod textencoder; pub mod touch; diff --git a/components/script/dom/textcontrol.rs b/components/script/dom/textcontrol.rs new file mode 100644 index 00000000000..0b8870b1996 --- /dev/null +++ b/components/script/dom/textcontrol.rs @@ -0,0 +1,78 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use dom::bindings::cell::DomRefCell; +use dom::bindings::conversions::DerivedFrom; +use dom::bindings::str::DOMString; +use dom::event::{EventBubbles, EventCancelable}; +use dom::eventtarget::EventTarget; +use dom::node::{Node, NodeDamage, window_from_node}; +use script_traits::ScriptToConstellationChan; +use textinput::{SelectionDirection, TextInput}; + +pub trait TextControl: DerivedFrom + DerivedFrom { + fn textinput(&self) -> &DomRefCell>; + + // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectionstart + fn dom_selection_start(&self) -> u32 { + self.textinput().borrow().get_selection_start() + } + + // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectionstart + fn set_dom_selection_start(&self, start: u32) { + self.set_selection_range(start, self.dom_selection_end(), self.selection_direction()); + } + + // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectionend + fn dom_selection_end(&self) -> u32 { + self.textinput().borrow().get_absolute_insertion_point() as u32 + } + + // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectionend + fn set_dom_selection_end(&self, end: u32) { + self.set_selection_range(self.dom_selection_start(), end, self.selection_direction()); + } + + // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectiondirection + fn dom_selection_direction(&self) -> DOMString { + DOMString::from(self.selection_direction()) + } + + // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectiondirection + fn set_dom_selection_direction(&self, direction: DOMString) { + self.textinput().borrow_mut().selection_direction = SelectionDirection::from(direction); + } + + // https://html.spec.whatwg.org/multipage/#dom-textarea/input-setselectionrange + fn set_dom_selection_range(&self, start: u32, end: u32, direction: Option) { + // Step 4 + let direction = direction.map_or(SelectionDirection::None, |d| SelectionDirection::from(d)); + + self.set_selection_range(start, end, direction); + } + + fn selection_direction(&self) -> SelectionDirection { + self.textinput().borrow().selection_direction + } + + // https://html.spec.whatwg.org/multipage/#set-the-selection-range + fn set_selection_range(&self, start: u32, end: u32, direction: SelectionDirection) { + // Step 5 + self.textinput().borrow_mut().selection_direction = direction; + + // Step 3 + self.textinput().borrow_mut().set_selection_range(start, end); + + // Step 6 + let window = window_from_node(self); + let _ = window.user_interaction_task_source().queue_event( + &self.upcast::(), + atom!("select"), + EventBubbles::Bubbles, + EventCancelable::NotCancelable, + &window); + + self.upcast::().dirty(NodeDamage::OtherNodeDamage); + } +} diff --git a/tests/wpt/metadata/html/semantics/forms/textfieldselection/selection-start-end.html.ini b/tests/wpt/metadata/html/semantics/forms/textfieldselection/selection-start-end.html.ini index 83d352f76fe..cc755ee3c3a 100644 --- a/tests/wpt/metadata/html/semantics/forms/textfieldselection/selection-start-end.html.ini +++ b/tests/wpt/metadata/html/semantics/forms/textfieldselection/selection-start-end.html.ini @@ -1,6 +1,5 @@ [selection-start-end.html] type: testharness - expected: TIMEOUT [Setting selectionStart to a value larger than selectionEnd should increase selectionEnd] expected: FAIL @@ -22,30 +21,6 @@ [Initial .value set on textarea-not-appended-prefocused should set selectionStart to end of value] expected: FAIL - [onselect should fire when selectionStart is changed on textarea-appended] - expected: NOTRUN - - [onselect should fire when selectionStart is changed on textarea-not-appended] - expected: NOTRUN - - [onselect should fire when selectionStart is changed on textarea-appended-prefocused] - expected: NOTRUN - - [onselect should fire when selectionStart is changed on textarea-not-appended-prefocused] - expected: NOTRUN - - [onselect should fire when selectionEnd is changed on textarea-appended] - expected: NOTRUN - - [onselect should fire when selectionEnd is changed on textarea-not-appended] - expected: NOTRUN - - [onselect should fire when selectionEnd is changed on textarea-appended-prefocused] - expected: NOTRUN - - [onselect should fire when selectionEnd is changed on textarea-not-appended-prefocused] - expected: NOTRUN - [Initial .value set on textarea-appended should set selectionEnd to end of value] expected: FAIL