Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

display input caret for textarea. fixes #7758 #7761

Merged
merged 1 commit into from Oct 21, 2015
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -431,9 +431,19 @@ fn split_first_fragment_at_newline_if_necessary(fragments: &mut LinkedList<Fragm

string_before =
unscanned_text_fragment_info.text[..(position + 1)].to_owned();
insertion_point_before = unscanned_text_fragment_info.insertion_point;
unscanned_text_fragment_info.text =
unscanned_text_fragment_info.text[(position + 1)..].to_owned().into_boxed_str();
let offset = CharIndex(string_before.char_indices().count() as isize);
match unscanned_text_fragment_info.insertion_point {
Some(insertion_point) if insertion_point >= offset => {
insertion_point_before = None;
unscanned_text_fragment_info.insertion_point = Some(insertion_point - offset);
}
Some(_) | None => {
insertion_point_before = unscanned_text_fragment_info.insertion_point;
unscanned_text_fragment_info.insertion_point = None;
}
};
}
first_fragment.transform(first_fragment.border_box.size,
SpecificFragmentInfo::UnscannedText(
@@ -71,7 +71,7 @@ use style::node::TElementAttributes;
use style::properties::ComputedValues;
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock};
use url::Url;
use util::str::is_whitespace;
use util::str::{is_whitespace, search_index};

/// A wrapper so that layout can access only the methods that it should have access to. Layout must
/// only ever see these and must never see instances of `LayoutJS`.
@@ -918,24 +918,17 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
let this = unsafe {
self.get_jsmanaged()
};
let input = this.downcast();
if let Some(input) = input {
let insertion_point = unsafe {
input.get_insertion_point_for_layout()
};

if let Some(area) = this.downcast::<HTMLTextAreaElement>() {
let insertion_point = unsafe { area.get_absolute_insertion_point_for_layout() };
let text = unsafe { area.get_value_for_layout() };
return Some(CharIndex(search_index(insertion_point, text.char_indices())));
}
if let Some(input) = this.downcast::<HTMLInputElement>() {
let insertion_point = unsafe { input.get_insertion_point_for_layout() };
if let Some(insertion_point) = insertion_point {
let text = unsafe {
input.get_value_for_layout()
};

let mut character_count = 0;
for (character_index, _) in text.char_indices() {
if character_index == insertion_point.index {
return Some(CharIndex(character_count))
}
character_count += 1
}
return Some(CharIndex(character_count))
let text = unsafe { input.get_value_for_layout() };
return Some(CharIndex(search_index(insertion_point.index, text.char_indices())));
}
}
None
@@ -46,6 +46,8 @@ pub struct HTMLTextAreaElement {
pub trait LayoutHTMLTextAreaElementHelpers {
#[allow(unsafe_code)]
unsafe fn get_value_for_layout(self) -> String;
#[allow(unsafe_code)]
unsafe fn get_absolute_insertion_point_for_layout(self) -> usize;
}

pub trait RawLayoutHTMLTextAreaElementHelpers {
@@ -61,6 +63,12 @@ impl LayoutHTMLTextAreaElementHelpers for LayoutJS<HTMLTextAreaElement> {
unsafe fn get_value_for_layout(self) -> String {
(*self.unsafe_get()).textinput.borrow_for_layout().get_content()
}

#[allow(unrooted_must_root)]
#[allow(unsafe_code)]
unsafe fn get_absolute_insertion_point_for_layout(self) -> usize {
(*self.unsafe_get()).textinput.borrow_for_layout().get_absolute_insertion_point()
}
}

impl<'a> RawLayoutHTMLTextAreaElementHelpers for &'a HTMLTextAreaElement {
@@ -455,4 +455,14 @@ impl<T: ClipboardProvider> TextInput<T> {
self.edit_point.line = min(self.edit_point.line, self.lines.len() - 1);
self.edit_point.index = min(self.edit_point.index, self.current_line_length());
}

pub fn get_absolute_insertion_point(&self) -> usize {
self.lines.iter().enumerate().fold(0, |acc, (i, val)| {
if i < self.edit_point.line {
acc + val.len() + 1 // +1 for the \n
} else {
acc
}
}) + self.edit_point.index
}
}
@@ -11,7 +11,7 @@ use std::borrow::ToOwned;
use std::ffi::CStr;
use std::iter::{Filter, Peekable};
use std::ops::Deref;
use std::str::{FromStr, Split, from_utf8};
use std::str::{CharIndices, FromStr, Split, from_utf8};

pub type DOMString = String;
pub type StaticCharVec = &'static [char];
@@ -420,3 +420,16 @@ pub fn slice_chars(s: &str, begin: usize, end: usize) -> &str {
(Some(a), Some(b)) => unsafe { s.slice_unchecked(a, b) }
}
}

// searches a character index in CharIndices
// returns indices.count if not found
pub fn search_index(index: usize, indices: CharIndices) -> isize {
let mut character_count = 0;
for (character_index, _) in indices {
if character_index == index {
return character_count;
}
character_count += 1
}
character_count
}
@@ -2,7 +2,7 @@
* 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 util::str::{split_html_space_chars, str_join};
use util::str::{search_index, split_html_space_chars, str_join};


#[test]
@@ -34,3 +34,15 @@ pub fn test_str_join_many() {
let expected = "-alpha--beta-gamma-";
assert_eq!(actual, expected);
}

#[test]
pub fn test_search_index() {
let tuples = [("", 1, 0),
("foo", 8, 3),
("føo", 8, 3),
("foo", 2, 2),
("føo", 2, 3)];
for t in tuples.iter() {
assert_eq!(search_index(t.1, t.0.char_indices()), t.2);
};
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.