mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
layout: Query and maintain the position of the insertion point
throughout layout for input elements.
This commit is contained in:
parent
34d9a6091b
commit
357419dc8d
6 changed files with 152 additions and 41 deletions
|
@ -176,9 +176,12 @@ impl TextRunScanner {
|
|||
let (mut run_info_list, mut run_info) = (Vec::new(), RunInfo::new());
|
||||
for (fragment_index, in_fragment) in self.clump.iter().enumerate() {
|
||||
let mut mapping = RunMapping::new(&run_info_list[..], &run_info, fragment_index);
|
||||
let text = match in_fragment.specific {
|
||||
let text;
|
||||
let insertion_point;
|
||||
match in_fragment.specific {
|
||||
SpecificFragmentInfo::UnscannedText(ref text_fragment_info) => {
|
||||
&text_fragment_info.text
|
||||
text = &text_fragment_info.text;
|
||||
insertion_point = text_fragment_info.insertion_point;
|
||||
}
|
||||
_ => panic!("Expected an unscanned text fragment!"),
|
||||
};
|
||||
|
@ -208,6 +211,7 @@ impl TextRunScanner {
|
|||
mapping.flush(&mut mappings,
|
||||
&mut run_info,
|
||||
&**text,
|
||||
insertion_point,
|
||||
compression,
|
||||
text_transform,
|
||||
&mut last_whitespace,
|
||||
|
@ -239,6 +243,7 @@ impl TextRunScanner {
|
|||
mapping.flush(&mut mappings,
|
||||
&mut run_info,
|
||||
&**text,
|
||||
insertion_point,
|
||||
compression,
|
||||
text_transform,
|
||||
&mut last_whitespace,
|
||||
|
@ -275,7 +280,13 @@ impl TextRunScanner {
|
|||
options.flags.insert(RTL_FLAG);
|
||||
}
|
||||
let mut font = fontgroup.fonts.get(run_info.font_index).unwrap().borrow_mut();
|
||||
Arc::new(TextRun::new(&mut *font, run_info.text, &options, run_info.bidi_level))
|
||||
ScannedTextRun {
|
||||
run: Arc::new(TextRun::new(&mut *font,
|
||||
run_info.text,
|
||||
&options,
|
||||
run_info.bidi_level)),
|
||||
insertion_point: run_info.insertion_point,
|
||||
}
|
||||
}).collect::<Vec<_>>()
|
||||
};
|
||||
|
||||
|
@ -296,19 +307,20 @@ impl TextRunScanner {
|
|||
};
|
||||
|
||||
let mut mapping = mappings.next().unwrap();
|
||||
let run = runs[mapping.text_run_index].clone();
|
||||
let scanned_run = runs[mapping.text_run_index].clone();
|
||||
|
||||
let requires_line_break_afterward_if_wrapping_on_newlines =
|
||||
run.text.char_at_reverse(mapping.byte_range.end()) == '\n';
|
||||
scanned_run.run.text.char_at_reverse(mapping.byte_range.end()) == '\n';
|
||||
if requires_line_break_afterward_if_wrapping_on_newlines {
|
||||
mapping.char_range.extend_by(CharIndex(-1));
|
||||
}
|
||||
|
||||
let text_size = old_fragment.border_box.size;
|
||||
let mut new_text_fragment_info = box ScannedTextFragmentInfo::new(
|
||||
run,
|
||||
scanned_run.run,
|
||||
mapping.char_range,
|
||||
text_size,
|
||||
&scanned_run.insertion_point,
|
||||
requires_line_break_afterward_if_wrapping_on_newlines);
|
||||
|
||||
let new_metrics = new_text_fragment_info.run.metrics_for_range(&mapping.char_range);
|
||||
|
@ -382,6 +394,7 @@ fn split_first_fragment_at_newline_if_necessary(fragments: &mut LinkedList<Fragm
|
|||
let new_fragment = {
|
||||
let mut first_fragment = fragments.front_mut().unwrap();
|
||||
let string_before;
|
||||
let insertion_point_before;
|
||||
{
|
||||
let unscanned_text_fragment_info = match first_fragment.specific {
|
||||
SpecificFragmentInfo::UnscannedText(ref mut unscanned_text_fragment_info) => {
|
||||
|
@ -403,12 +416,14 @@ 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();
|
||||
}
|
||||
first_fragment.transform(first_fragment.border_box.size,
|
||||
SpecificFragmentInfo::UnscannedText(
|
||||
UnscannedTextFragmentInfo::from_text(string_before)))
|
||||
UnscannedTextFragmentInfo::new(string_before,
|
||||
insertion_point_before)))
|
||||
};
|
||||
|
||||
fragments.push_front(new_fragment);
|
||||
|
@ -418,6 +433,8 @@ fn split_first_fragment_at_newline_if_necessary(fragments: &mut LinkedList<Fragm
|
|||
struct RunInfo {
|
||||
/// The text that will go in this text run.
|
||||
text: String,
|
||||
/// The insertion point in this text run, if applicable.
|
||||
insertion_point: Option<CharIndex>,
|
||||
/// The index of the applicable font in the font group.
|
||||
font_index: usize,
|
||||
/// A cached copy of the number of Unicode characters in the text run.
|
||||
|
@ -430,6 +447,7 @@ impl RunInfo {
|
|||
fn new() -> RunInfo {
|
||||
RunInfo {
|
||||
text: String::new(),
|
||||
insertion_point: None,
|
||||
font_index: 0,
|
||||
character_length: 0,
|
||||
bidi_level: 0,
|
||||
|
@ -472,6 +490,7 @@ impl RunMapping {
|
|||
mappings: &mut Vec<RunMapping>,
|
||||
run_info: &mut RunInfo,
|
||||
text: &str,
|
||||
insertion_point: Option<CharIndex>,
|
||||
compression: CompressionMode,
|
||||
text_transform: text_transform::T,
|
||||
last_whitespace: &mut bool,
|
||||
|
@ -489,6 +508,12 @@ impl RunMapping {
|
|||
old_byte_length,
|
||||
text_transform);
|
||||
|
||||
// Record the position of the insertion point if necessary.
|
||||
if let Some(insertion_point) = insertion_point {
|
||||
run_info.insertion_point =
|
||||
Some(CharIndex(run_info.character_length as isize + insertion_point.0))
|
||||
}
|
||||
|
||||
run_info.character_length = run_info.character_length + character_count;
|
||||
*start_position = end_position;
|
||||
|
||||
|
@ -570,3 +595,9 @@ fn apply_style_transform_if_necessary(string: &mut String,
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct ScannedTextRun {
|
||||
run: Arc<TextRun>,
|
||||
insertion_point: Option<CharIndex>,
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue