diff options
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/bindings/codegen/CodegenRust.py | 9 | ||||
-rw-r--r-- | components/script/dom/bindings/codegen/Configuration.py | 4 | ||||
-rw-r--r-- | components/script/dom/document.rs | 4 | ||||
-rw-r--r-- | components/script/dom/htmlinputelement.rs | 86 | ||||
-rw-r--r-- | components/script/dom/htmllinkelement.rs | 21 | ||||
-rw-r--r-- | components/script/dom/htmltableelement.rs | 65 | ||||
-rw-r--r-- | components/script/dom/htmltextareaelement.rs | 47 | ||||
-rw-r--r-- | components/script/dom/webglprogram.rs | 6 | ||||
-rw-r--r-- | components/script/dom/webglrenderingcontext.rs | 10 | ||||
-rw-r--r-- | components/script/dom/webidls/HTMLTableElement.webidl | 6 | ||||
-rw-r--r-- | components/script/dom/webidls/HTMLTextAreaElement.webidl | 8 | ||||
-rw-r--r-- | components/script/textinput.rs | 65 |
12 files changed, 222 insertions, 109 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 57b7be5c7bb..74dff1cce9f 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -36,6 +36,13 @@ TRACE_HOOK_NAME = '_trace' CONSTRUCT_HOOK_NAME = '_constructor' HASINSTANCE_HOOK_NAME = '_hasInstance' +RUST_KEYWORDS = {"abstract", "alignof", "as", "become", "box", "break", "const", "continue", + "else", "enum", "extern", "false", "final", "fn", "for", "if", "impl", "in", + "let", "loop", "macro", "match", "mod", "move", "mut", "offsetof", "override", + "priv", "proc", "pub", "pure", "ref", "return", "static", "self", "sizeof", + "struct", "super", "true", "trait", "type", "typeof", "unsafe", "unsized", + "use", "virtual", "where", "while", "yield"} + def replaceFileIfChanged(filename, newContents): """ @@ -5247,7 +5254,7 @@ class CGDictionary(CGThing): @staticmethod def makeMemberName(name): # Can't use Rust keywords as member names. - if name == "type": + if name in RUST_KEYWORDS: return name + "_" return name diff --git a/components/script/dom/bindings/codegen/Configuration.py b/components/script/dom/bindings/codegen/Configuration.py index c634665c410..99727f8acc0 100644 --- a/components/script/dom/bindings/codegen/Configuration.py +++ b/components/script/dom/bindings/codegen/Configuration.py @@ -2,6 +2,8 @@ # 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/. +import os + from WebIDL import IDLExternalInterface, IDLInterface, WebIDLError @@ -360,7 +362,7 @@ class Descriptor(DescriptorProvider): # Some utility methods def getModuleFromObject(object): - return object.location.filename().split('/')[-1].split('.webidl')[0] + 'Binding' + return os.path.basename(object.location.filename()).split('.webidl')[0] + 'Binding' def getTypesFromDescriptor(descriptor): diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index b76df5d6aa7..d87e80b7acc 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -2687,6 +2687,10 @@ impl DocumentMethods for Document { let window = window_from_node(self); let viewport = window.window_size().unwrap().visible_viewport; + if self.browsing_context().is_none() { + return None; + } + if x < 0.0 || y < 0.0 || x > viewport.width.get() || y > viewport.height.get() { return None; } diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 9c969ceec98..ab753053b8f 100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -42,7 +42,7 @@ use string_cache::Atom; use style::element_state::*; use textinput::KeyReaction::{DispatchInput, Nothing, RedrawSelection, TriggerDefaultAction}; use textinput::Lines::Single; -use textinput::TextInput; +use textinput::{TextInput, SelectionDirection}; use util::str::{DOMString, search_index}; const DEFAULT_SUBMIT_VALUE: &'static str = "Submit"; @@ -71,14 +71,6 @@ enum ValueMode { Filename, } -#[derive(JSTraceable, PartialEq, Copy, Clone)] -#[derive(HeapSizeOf)] -enum SelectionDirection { - Forward, - Backward, - None -} - #[dom_struct] pub struct HTMLInputElement { htmlelement: HTMLElement, @@ -94,8 +86,6 @@ pub struct HTMLInputElement { // https://html.spec.whatwg.org/multipage/#concept-input-value-dirty-flag value_dirty: Cell<bool>, - selection_direction: Cell<SelectionDirection>, - // TODO: selected files for file input } @@ -142,10 +132,9 @@ impl HTMLInputElement { value_changed: Cell::new(false), maxlength: Cell::new(DEFAULT_MAX_LENGTH), size: Cell::new(DEFAULT_INPUT_SIZE), - textinput: DOMRefCell::new(TextInput::new(Single, DOMString::new(), chan, None)), + textinput: DOMRefCell::new(TextInput::new(Single, DOMString::new(), chan, None, SelectionDirection::None)), activation_state: DOMRefCell::new(InputActivationState::new()), value_dirty: Cell::new(false), - selection_direction: Cell::new(SelectionDirection::None) } } @@ -177,33 +166,6 @@ impl HTMLInputElement { InputType::InputFile => ValueMode::Filename, } } - - // this method exists so that the functions SetSelectionStart() and SetSelectionEnd() - // don't needlessly allocate strings - fn set_selection_range(&self, start: u32, end: u32, direction: &SelectionDirection) { - let mut text_input = self.textinput.borrow_mut(); - - let mut start = start as usize; - let mut end = end as usize; - - let text_end = text_input.get_content().len(); - if start > text_end { - start = text_end; - } - if end > text_end { - end = text_end; - } - - if start >= end { - start = end; - } - - text_input.selection_begin = Some(text_input.get_text_point_for_absolute_point(start)); - text_input.edit_point = text_input.get_text_point_for_absolute_point(end); - self.selection_direction.set(*direction); - self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage); - } - } pub trait LayoutHTMLInputElementHelpers { @@ -547,60 +509,44 @@ impl HTMLInputElementMethods for HTMLInputElement { // https://html.spec.whatwg.org/multipage/#dom-input-selectionstart fn SelectionStart(&self) -> u32 { - let text_input = self.textinput.borrow(); - let selection_start = match text_input.selection_begin { - Some(selection_begin_point) => { - text_input.get_absolute_point_for_text_point(&selection_begin_point) - }, - None => text_input.get_absolute_insertion_point() - }; - - selection_start as u32 + self.textinput.borrow().get_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.get()); + let selection_end = self.SelectionEnd(); + self.textinput.borrow_mut().set_selection_range(start, selection_end); + self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage); } // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectionend fn SelectionEnd(&self) -> u32 { - let text_input = self.textinput.borrow(); - text_input.get_absolute_insertion_point() as u32 + self.textinput.borrow().get_absolute_insertion_point() as u32 } // 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.get()); + let selection_start = self.SelectionStart(); + self.textinput.borrow_mut().set_selection_range(selection_start, end); + self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage); } // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectiondirection fn SelectionDirection(&self) -> DOMString { - match self.selection_direction.get() { - SelectionDirection::Forward => DOMString::from("forward"), - SelectionDirection::Backward => DOMString::from("backward"), - SelectionDirection::None => DOMString::from("none"), - } + DOMString::from(self.textinput.borrow().selection_direction) } // https://html.spec.whatwg.org/multipage/#dom-textarea/input-selectiondirection fn SetSelectionDirection(&self, direction: DOMString) { - self.SetSelectionRange(self.SelectionStart(), self.SelectionEnd(), Some(direction)); + self.textinput.borrow_mut().selection_direction = SelectionDirection::from(direction); } // https://html.spec.whatwg.org/multipage/#dom-textarea/input-setselectionrange fn SetSelectionRange(&self, start: u32, end: u32, direction: Option<DOMString>) { - let selection_direction = match direction { - Some(selection_direction) => { - match &*selection_direction { - "forward" => SelectionDirection::Forward, - "backward" => SelectionDirection::Backward, - _ => SelectionDirection::None, - } - }, - None => SelectionDirection::None, - }; - self.set_selection_range(start, end, &selection_direction); + 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); + self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage); } } diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index e7af4f537be..1b058b4c671 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -190,9 +190,8 @@ impl VirtualMethods for HTMLLinkElement { impl HTMLLinkElement { fn handle_stylesheet_url(&self, href: &str) { - let window = window_from_node(self); - let window = window.r(); - match window.get_url().join(href) { + let document = document_from_node(self); + match document.base_url().join(href) { Ok(url) => { let element = self.upcast::<Element>(); @@ -206,8 +205,7 @@ impl HTMLLinkElement { let media = parse_media_query_list(&mut css_parser); // TODO: #8085 - Don't load external stylesheets if the node's mq doesn't match. - let doc = window.Document(); - let script_chan = window.networking_task_source(); + let script_chan = document.window().networking_task_source(); let elem = Trusted::new(self, script_chan.clone()); let context = Arc::new(Mutex::new(StylesheetContext { @@ -231,20 +229,19 @@ impl HTMLLinkElement { }); if self.parser_inserted.get() { - doc.increment_script_blocking_stylesheet_count(); + document.increment_script_blocking_stylesheet_count(); } - doc.load_async(LoadType::Stylesheet(url), response_target); + document.load_async(LoadType::Stylesheet(url), response_target); } Err(e) => debug!("Parsing url {} failed: {}", href, e) } } fn handle_favicon_url(&self, rel: &str, href: &str, sizes: &Option<String>) { - let window = window_from_node(self); - let window = window.r(); - match window.get_url().join(href) { + let document = document_from_node(self); + match document.base_url().join(href) { Ok(url) => { - let ConstellationChan(ref chan) = window.constellation_chan(); + let ConstellationChan(ref chan) = document.window().constellation_chan(); let event = ConstellationMsg::NewFavicon(url.clone()); chan.send(event).unwrap(); @@ -252,7 +249,7 @@ impl HTMLLinkElement { Some(ref sizes) => MozBrowserEvent::IconChange(rel.to_owned(), url.to_string(), sizes.to_owned()), None => MozBrowserEvent::IconChange(rel.to_owned(), url.to_string(), "".to_owned()) }; - window.Document().trigger_mozbrowser_event(mozbrowser_event); + document.trigger_mozbrowser_event(mozbrowser_event); } Err(e) => debug!("Parsing url {} failed: {}", href, e) } diff --git a/components/script/dom/htmltableelement.rs b/components/script/dom/htmltableelement.rs index 4ea908675b1..4b5cd44773d 100644 --- a/components/script/dom/htmltableelement.rs +++ b/components/script/dom/htmltableelement.rs @@ -4,10 +4,11 @@ use cssparser::RGBA; use dom::attr::{Attr, AttrValue}; +use dom::bindings::codegen::Bindings::HTMLCollectionBinding::HTMLCollectionMethods; use dom::bindings::codegen::Bindings::HTMLTableElementBinding; use dom::bindings::codegen::Bindings::HTMLTableElementBinding::HTMLTableElementMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; -use dom::bindings::error::{Error, ErrorResult}; +use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root, RootedReference}; use dom::document::Document; @@ -166,8 +167,8 @@ impl HTMLTableElementMethods for HTMLTableElement { } // https://html.spec.whatwg.org/multipage/#dom-table-createcaption - fn CreateCaption(&self) -> Root<HTMLElement> { - let caption = match self.GetCaption() { + fn CreateCaption(&self) -> Root<HTMLTableCaptionElement> { + match self.GetCaption() { Some(caption) => caption, None => { let caption = HTMLTableCaptionElement::new(atom!("caption"), @@ -176,8 +177,7 @@ impl HTMLTableElementMethods for HTMLTableElement { self.SetCaption(Some(caption.r())); caption } - }; - Root::upcast(caption) + } } // https://html.spec.whatwg.org/multipage/#dom-table-deletecaption @@ -282,6 +282,61 @@ impl HTMLTableElementMethods for HTMLTableElement { tbody } + // https://html.spec.whatwg.org/multipage/#dom-table-insertrow + fn InsertRow(&self, index: i32) -> Fallible<Root<HTMLTableRowElement>> { + let rows = self.Rows(); + let number_of_row_elements = rows.Length(); + + if index < -1 || index > number_of_row_elements as i32 { + return Err(Error::IndexSize); + } + + let new_row = HTMLTableRowElement::new(atom!("tr"), + None, + document_from_node(self).r()); + let node = self.upcast::<Node>(); + + if number_of_row_elements == 0 { + // append new row to last or new tbody in table + if let Some(last_tbody) = node.rev_children() + .filter_map(Root::downcast::<Element>) + .find(|n| n.is::<HTMLTableSectionElement>() && n.local_name() == &atom!("tbody")) { + last_tbody.upcast::<Node>().AppendChild(new_row.upcast::<Node>()) + .expect("InsertRow failed to append first row."); + } else { + let tbody = self.CreateTBody(); + node.AppendChild(tbody.upcast()) + .expect("InsertRow failed to append new tbody."); + + tbody.upcast::<Node>().AppendChild(new_row.upcast::<Node>()) + .expect("InsertRow failed to append first row."); + } + } else if index == number_of_row_elements as i32 || index == -1 { + // append new row to parent of last row in table + let last_row = rows.Item(number_of_row_elements - 1) + .expect("InsertRow failed to find last row in table."); + + let last_row_parent = + last_row.upcast::<Node>().GetParentNode() + .expect("InsertRow failed to find parent of last row in table."); + + last_row_parent.upcast::<Node>().AppendChild(new_row.upcast::<Node>()) + .expect("InsertRow failed to append last row."); + } else { + // insert new row before the index-th row in rows using the same parent + let ith_row = rows.Item(index as u32) + .expect("InsertRow failed to find a row in table."); + + let ith_row_parent = ith_row.upcast::<Node>().GetParentNode() + .expect("InsertRow failed to find parent of a row in table."); + + ith_row_parent.upcast::<Node>().InsertBefore(new_row.upcast::<Node>(), Some(ith_row.upcast::<Node>())) + .expect("InsertRow failed to append row"); + } + + Ok(new_row) + } + // https://html.spec.whatwg.org/multipage/#dom-table-bgcolor make_getter!(BgColor, "bgcolor"); diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs index a9f8f170889..d3eb7827031 100644 --- a/components/script/dom/htmltextareaelement.rs +++ b/components/script/dom/htmltextareaelement.rs @@ -31,7 +31,7 @@ use script_traits::ScriptMsg as ConstellationMsg; use std::cell::Cell; use string_cache::Atom; use style::element_state::*; -use textinput::{KeyReaction, Lines, TextInput}; +use textinput::{KeyReaction, Lines, TextInput, SelectionDirection}; use util::str::DOMString; #[dom_struct] @@ -106,7 +106,8 @@ impl HTMLTextAreaElement { htmlelement: HTMLElement::new_inherited_with_state(IN_ENABLED_STATE, localName, prefix, document), - textinput: DOMRefCell::new(TextInput::new(Lines::Multiple, DOMString::new(), chan, None)), + textinput: DOMRefCell::new(TextInput::new( + Lines::Multiple, DOMString::new(), chan, None, SelectionDirection::None)), value_changed: Cell::new(false), } } @@ -216,6 +217,48 @@ impl HTMLTextAreaElementMethods for HTMLTextAreaElement { fn Labels(&self) -> Root<NodeList> { self.upcast::<HTMLElement>().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::<Node>().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 SetSelectionStart(&self, start: u32) { + let selection_end = self.SelectionEnd(); + self.textinput.borrow_mut().set_selection_range(start, selection_end); + self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage); + } + + // 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-setselectionrange + fn SetSelectionRange(&self, start: u32, end: u32, direction: Option<DOMString>) { + 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); + self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage); + } } diff --git a/components/script/dom/webglprogram.rs b/components/script/dom/webglprogram.rs index d288e9422c4..0458e2ae2ca 100644 --- a/components/script/dom/webglprogram.rs +++ b/components/script/dom/webglprogram.rs @@ -147,7 +147,7 @@ impl WebGLProgram { } // Check if the name is reserved - if name.starts_with("webgl") || name.starts_with("_webgl_") { + if name.starts_with("gl_") || name.starts_with("webgl") || name.starts_with("_webgl_") { return Err(WebGLError::InvalidOperation); } @@ -185,6 +185,10 @@ impl WebGLProgram { } // Check if the name is reserved + if name.starts_with("gl_") { + return Err(WebGLError::InvalidOperation); + } + if name.starts_with("webgl") || name.starts_with("_webgl_") { return Ok(None); } diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 197dcce55f5..5f1b0589af4 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -979,12 +979,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { fn GetUniformLocation(&self, program: Option<&WebGLProgram>, name: DOMString) -> Option<Root<WebGLUniformLocation>> { - if let Some(program) = program { - handle_potential_webgl_error!(self, program.get_uniform_location(name), None) - .map(|location| WebGLUniformLocation::new(self.global().r(), location, program.id())) - } else { - None - } + program.and_then(|p| { + handle_potential_webgl_error!(self, p.get_uniform_location(name), None) + .map(|location| WebGLUniformLocation::new(self.global().r(), location, p.id())) + }) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 diff --git a/components/script/dom/webidls/HTMLTableElement.webidl b/components/script/dom/webidls/HTMLTableElement.webidl index af95685b5b5..dacd0da7aa2 100644 --- a/components/script/dom/webidls/HTMLTableElement.webidl +++ b/components/script/dom/webidls/HTMLTableElement.webidl @@ -6,7 +6,7 @@ // https://html.spec.whatwg.org/multipage/#htmltableelement interface HTMLTableElement : HTMLElement { attribute HTMLTableCaptionElement? caption; - HTMLElement createCaption(); + HTMLTableCaptionElement createCaption(); void deleteCaption(); [SetterThrows] attribute HTMLTableSectionElement? tHead; @@ -19,10 +19,8 @@ interface HTMLTableElement : HTMLElement { readonly attribute HTMLCollection tBodies; HTMLTableSectionElement createTBody(); readonly attribute HTMLCollection rows; - //HTMLElement insertRow(optional long index = -1); + [Throws] HTMLTableRowElement insertRow(optional long index = -1); //void deleteRow(long index); - // attribute boolean sortable; - //void stopSorting(); // also has obsolete members }; diff --git a/components/script/dom/webidls/HTMLTextAreaElement.webidl b/components/script/dom/webidls/HTMLTextAreaElement.webidl index 797a537d0cc..e5e2cabdb78 100644 --- a/components/script/dom/webidls/HTMLTextAreaElement.webidl +++ b/components/script/dom/webidls/HTMLTextAreaElement.webidl @@ -38,11 +38,11 @@ interface HTMLTextAreaElement : HTMLElement { readonly attribute NodeList labels; //void select(); - // attribute unsigned long selectionStart; - // attribute unsigned long selectionEnd; - // attribute DOMString selectionDirection; + attribute unsigned long selectionStart; + attribute unsigned long selectionEnd; + attribute DOMString selectionDirection; //void setRangeText(DOMString replacement); //void setRangeText(DOMString replacement, unsigned long start, unsigned long end, // optional SelectionMode selectionMode = "preserve"); - //void setSelectionRange(unsigned long start, unsigned long end, optional DOMString direction); + void setSelectionRange(unsigned long start, unsigned long end, optional DOMString direction); }; diff --git a/components/script/textinput.rs b/components/script/textinput.rs index 1be7962003c..ffd707c5d27 100644 --- a/components/script/textinput.rs +++ b/components/script/textinput.rs @@ -21,6 +21,33 @@ pub enum Selection { NotSelected } +#[derive(JSTraceable, PartialEq, Copy, Clone, HeapSizeOf)] +pub enum SelectionDirection { + Forward, + Backward, + None, +} + +impl From<DOMString> for SelectionDirection { + fn from(direction: DOMString) -> SelectionDirection { + match direction.as_ref() { + "forward" => SelectionDirection::Forward, + "backward" => SelectionDirection::Backward, + _ => SelectionDirection::None, + } + } +} + +impl From<SelectionDirection> for DOMString { + fn from(direction: SelectionDirection) -> DOMString { + match direction { + SelectionDirection::Forward => DOMString::from("forward"), + SelectionDirection::Backward => DOMString::from("backward"), + SelectionDirection::None => DOMString::from("none"), + } + } +} + #[derive(JSTraceable, Copy, Clone, HeapSizeOf, PartialEq)] pub struct TextPoint { /// 0-based line number @@ -45,7 +72,8 @@ pub struct TextInput<T: ClipboardProvider> { /// The maximum number of UTF-16 code units this text input is allowed to hold. /// /// https://html.spec.whatwg.org/multipage/#attr-fe-maxlength - pub max_length: Option<usize> + pub max_length: Option<usize>, + pub selection_direction: SelectionDirection, } /// Resulting action to be taken by the owner of a text input that is handling an event. @@ -138,14 +166,17 @@ fn len_of_first_n_code_units(text: &str, n: usize) -> usize { impl<T: ClipboardProvider> TextInput<T> { /// Instantiate a new text input control - pub fn new(lines: Lines, initial: DOMString, clipboard_provider: T, max_length: Option<usize>) -> TextInput<T> { + pub fn new(lines: Lines, initial: DOMString, + clipboard_provider: T, max_length: Option<usize>, + selection_direction: SelectionDirection) -> TextInput<T> { let mut i = TextInput { lines: vec!(), edit_point: Default::default(), selection_begin: None, multiline: lines == Lines::Multiple, clipboard_provider: clipboard_provider, - max_length: max_length + max_length: max_length, + selection_direction: selection_direction, }; i.set_content(initial); i @@ -607,4 +638,32 @@ impl<T: ClipboardProvider> TextInput<T> { line: line, index: index } } + + pub fn set_selection_range(&mut self, start: u32, end: u32) { + let mut start = start as usize; + let mut end = end as usize; + let text_end = self.get_content().len(); + + if start > text_end { + start = text_end; + } else if end > text_end { + end = text_end; + } else if start >= end { + start = end; + } + + self.selection_begin = Some(self.get_text_point_for_absolute_point(start)); + self.edit_point = self.get_text_point_for_absolute_point(end); + } + + pub fn get_selection_start(&self) -> u32 { + let selection_start = match self.selection_begin { + Some(selection_begin_point) => { + self.get_absolute_point_for_text_point(&selection_begin_point) + }, + None => self.get_absolute_insertion_point() + }; + + selection_start as u32 + } } |