mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
Use fragment index type for referring to inline DOM fragments
This commit is contained in:
parent
b54059e6d2
commit
2a7dd53021
2 changed files with 42 additions and 28 deletions
|
@ -30,7 +30,7 @@ use layout::floats::FloatKind;
|
||||||
use layout::flow::{Flow, ImmutableFlowUtils, MutableOwnedFlowUtils};
|
use layout::flow::{Flow, ImmutableFlowUtils, MutableOwnedFlowUtils};
|
||||||
use layout::flow::{Descendants, AbsDescendants};
|
use layout::flow::{Descendants, AbsDescendants};
|
||||||
use layout::flow_list::{Rawlink};
|
use layout::flow_list::{Rawlink};
|
||||||
use layout::inline::{InlineBoxes, InlineFlow};
|
use layout::inline::{FragmentIndex, InlineBoxes, InlineFlow};
|
||||||
use layout::table_wrapper::TableWrapperFlow;
|
use layout::table_wrapper::TableWrapperFlow;
|
||||||
use layout::table::TableFlow;
|
use layout::table::TableFlow;
|
||||||
use layout::table_caption::TableCaptionFlow;
|
use layout::table_caption::TableCaptionFlow;
|
||||||
|
@ -189,7 +189,7 @@ impl InlineBoxAccumulator {
|
||||||
|
|
||||||
fn from_inline_node(node: &ThreadSafeLayoutNode) -> InlineBoxAccumulator {
|
fn from_inline_node(node: &ThreadSafeLayoutNode) -> InlineBoxAccumulator {
|
||||||
let mut boxes = InlineBoxes::new();
|
let mut boxes = InlineBoxes::new();
|
||||||
boxes.map.push(node.style().clone(), Range::new(0, 0));
|
boxes.map.push(node.style().clone(), Range::empty());
|
||||||
InlineBoxAccumulator {
|
InlineBoxAccumulator {
|
||||||
boxes: boxes,
|
boxes: boxes,
|
||||||
has_enclosing_range: true,
|
has_enclosing_range: true,
|
||||||
|
@ -203,8 +203,8 @@ impl InlineBoxAccumulator {
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
if has_enclosing_range {
|
if has_enclosing_range {
|
||||||
let len = boxes.len() as int;
|
let len = FragmentIndex(boxes.len() as int);
|
||||||
boxes.map.get_mut(0).range.extend_to(len);
|
boxes.map.get_mut(FragmentIndex(0)).range.extend_to(len);
|
||||||
}
|
}
|
||||||
boxes
|
boxes
|
||||||
}
|
}
|
||||||
|
|
|
@ -472,7 +472,10 @@ impl<'a> Iterator<(&'a Box, InlineFragmentContext<'a>)> for BoxIterator<'a> {
|
||||||
fn next(&mut self) -> Option<(&'a Box, InlineFragmentContext<'a>)> {
|
fn next(&mut self) -> Option<(&'a Box, InlineFragmentContext<'a>)> {
|
||||||
match self.iter.next() {
|
match self.iter.next() {
|
||||||
None => None,
|
None => None,
|
||||||
Some((i, fragment)) => Some((fragment, InlineFragmentContext::new(self.map, i as int))),
|
Some((i, fragment)) => Some((
|
||||||
|
fragment,
|
||||||
|
InlineFragmentContext::new(self.map, FragmentIndex(i as int)),
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -488,7 +491,10 @@ impl<'a> Iterator<(&'a mut Box, InlineFragmentContext<'a>)> for MutBoxIterator<'
|
||||||
fn next(&mut self) -> Option<(&'a mut Box, InlineFragmentContext<'a>)> {
|
fn next(&mut self) -> Option<(&'a mut Box, InlineFragmentContext<'a>)> {
|
||||||
match self.iter.next() {
|
match self.iter.next() {
|
||||||
None => None,
|
None => None,
|
||||||
Some((i, fragment)) => Some((fragment, InlineFragmentContext::new(self.map, i as int))),
|
Some((i, fragment)) => Some((
|
||||||
|
fragment,
|
||||||
|
InlineFragmentContext::new(self.map, FragmentIndex(i as int)),
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -522,7 +528,7 @@ impl InlineBoxes {
|
||||||
|
|
||||||
/// Pushes a new inline box.
|
/// Pushes a new inline box.
|
||||||
pub fn push(&mut self, fragment: Box, style: Arc<ComputedValues>) {
|
pub fn push(&mut self, fragment: Box, style: Arc<ComputedValues>) {
|
||||||
self.map.push(style, Range::new(self.boxes.len() as int, 1));
|
self.map.push(style, Range::new(FragmentIndex(self.boxes.len() as int), FragmentIndex(1)));
|
||||||
self.boxes.push(fragment)
|
self.boxes.push(fragment)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,7 +538,7 @@ impl InlineBoxes {
|
||||||
boxes: other_boxes,
|
boxes: other_boxes,
|
||||||
map: other_map
|
map: other_map
|
||||||
} = other;
|
} = other;
|
||||||
let adjustment = self.boxes.len();
|
let adjustment = FragmentIndex(self.boxes.len() as int);
|
||||||
self.map.push_all(other_map, adjustment);
|
self.map.push_all(other_map, adjustment);
|
||||||
self.boxes.push_all_move(other_boxes);
|
self.boxes.push_all_move(other_boxes);
|
||||||
}
|
}
|
||||||
|
@ -975,18 +981,23 @@ impl fmt::Show for InlineFlow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
range_index! {
|
||||||
|
#[doc = "The index of a DOM element into the flat list of fragments."]
|
||||||
|
struct FragmentIndex(int)
|
||||||
|
}
|
||||||
|
|
||||||
/// Information that inline flows keep about a single nested element. This is used to recover the
|
/// Information that inline flows keep about a single nested element. This is used to recover the
|
||||||
/// DOM structure from the flat box list when it's needed.
|
/// DOM structure from the flat box list when it's needed.
|
||||||
pub struct FragmentRange {
|
pub struct FragmentRange {
|
||||||
/// The style of the DOM node that this range refers to.
|
/// The style of the DOM node that this range refers to.
|
||||||
pub style: Arc<ComputedValues>,
|
pub style: Arc<ComputedValues>,
|
||||||
/// The range, in indices into the fragment list.
|
/// The range, in indices into the fragment list.
|
||||||
pub range: Range<int>,
|
pub range: Range<FragmentIndex>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FragmentRange {
|
impl FragmentRange {
|
||||||
/// Creates a new fragment range from the given values.
|
/// Creates a new fragment range from the given values.
|
||||||
fn new(style: Arc<ComputedValues>, range: Range<int>) -> FragmentRange {
|
fn new(style: Arc<ComputedValues>, range: Range<FragmentIndex>) -> FragmentRange {
|
||||||
FragmentRange {
|
FragmentRange {
|
||||||
style: style,
|
style: style,
|
||||||
range: range,
|
range: range,
|
||||||
|
@ -1007,14 +1018,14 @@ impl FragmentRange {
|
||||||
|
|
||||||
struct FragmentFixupWorkItem {
|
struct FragmentFixupWorkItem {
|
||||||
style: Arc<ComputedValues>,
|
style: Arc<ComputedValues>,
|
||||||
new_start_index: int,
|
new_start_index: FragmentIndex,
|
||||||
old_end_index: int,
|
old_end_index: FragmentIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The type of an iterator over fragment ranges in the fragment map.
|
/// The type of an iterator over fragment ranges in the fragment map.
|
||||||
pub struct RangeIterator<'a> {
|
pub struct RangeIterator<'a> {
|
||||||
iter: Items<'a,FragmentRange>,
|
iter: Items<'a,FragmentRange>,
|
||||||
index: int,
|
index: FragmentIndex,
|
||||||
seen_first: bool,
|
seen_first: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1057,13 +1068,13 @@ impl FragmentMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds the given node to the fragment map.
|
/// Adds the given node to the fragment map.
|
||||||
pub fn push(&mut self, style: Arc<ComputedValues>, range: Range<int>) {
|
pub fn push(&mut self, style: Arc<ComputedValues>, range: Range<FragmentIndex>) {
|
||||||
self.list.push(FragmentRange::new(style, range))
|
self.list.push(FragmentRange::new(style, range))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pushes the ranges in another fragment map onto the end of this one, adjusting indices as
|
/// Pushes the ranges in another fragment map onto the end of this one, adjusting indices as
|
||||||
/// necessary.
|
/// necessary.
|
||||||
fn push_all(&mut self, other: FragmentMap, adjustment: uint) {
|
fn push_all(&mut self, other: FragmentMap, adjustment: FragmentIndex) {
|
||||||
let FragmentMap {
|
let FragmentMap {
|
||||||
list: other_list
|
list: other_list
|
||||||
} = other;
|
} = other;
|
||||||
|
@ -1074,19 +1085,19 @@ impl FragmentMap {
|
||||||
range: mut other_range
|
range: mut other_range
|
||||||
} = other_range;
|
} = other_range;
|
||||||
|
|
||||||
other_range.shift_by(adjustment as int);
|
other_range.shift_by(adjustment);
|
||||||
self.push(other_style, other_range)
|
self.push(other_style, other_range)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the range with the given index.
|
/// Returns the range with the given index.
|
||||||
pub fn get_mut<'a>(&'a mut self, index: int) -> &'a mut FragmentRange {
|
pub fn get_mut<'a>(&'a mut self, index: FragmentIndex) -> &'a mut FragmentRange {
|
||||||
&mut self.list.as_mut_slice()[index as uint]
|
&mut self.list.as_mut_slice()[index.to_uint()]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterates over all ranges that contain the box with the given index, outermost first.
|
/// Iterates over all ranges that contain the box with the given index, outermost first.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn ranges_for_index<'a>(&'a self, index: int) -> RangeIterator<'a> {
|
fn ranges_for_index<'a>(&'a self, index: FragmentIndex) -> RangeIterator<'a> {
|
||||||
RangeIterator {
|
RangeIterator {
|
||||||
iter: self.list.as_slice().iter(),
|
iter: self.list.as_slice().iter(),
|
||||||
index: index,
|
index: index,
|
||||||
|
@ -1112,12 +1123,13 @@ impl FragmentMap {
|
||||||
|
|
||||||
// FIXME(#2270, pcwalton): I don't think this will work if multiple old fragments
|
// FIXME(#2270, pcwalton): I don't think this will work if multiple old fragments
|
||||||
// correspond to the same node.
|
// correspond to the same node.
|
||||||
for (old_fragment_index, old_fragment) in old_fragments.iter().enumerate() {
|
for (i, old_fragment) in old_fragments.iter().enumerate() {
|
||||||
|
let old_fragment_index = FragmentIndex(i as int);
|
||||||
// Find the start of the corresponding new fragment.
|
// Find the start of the corresponding new fragment.
|
||||||
let new_fragment_start = match new_fragments_iter.peek() {
|
let new_fragment_start = match new_fragments_iter.peek() {
|
||||||
Some(&(index, new_fragment)) if new_fragment.node == old_fragment.node => {
|
Some(&(index, new_fragment)) if new_fragment.node == old_fragment.node => {
|
||||||
// We found the start of the corresponding new fragment.
|
// We found the start of the corresponding new fragment.
|
||||||
index as int
|
FragmentIndex(index as int)
|
||||||
}
|
}
|
||||||
Some(_) | None => {
|
Some(_) | None => {
|
||||||
// The old fragment got deleted entirely.
|
// The old fragment got deleted entirely.
|
||||||
|
@ -1140,7 +1152,7 @@ impl FragmentMap {
|
||||||
match old_list_iter.peek() {
|
match old_list_iter.peek() {
|
||||||
None => break,
|
None => break,
|
||||||
Some(fragment_range) => {
|
Some(fragment_range) => {
|
||||||
if fragment_range.range.begin() > old_fragment_index as int {
|
if fragment_range.range.begin() > old_fragment_index {
|
||||||
// We haven't gotten to the appropriate old fragment yet, so stop.
|
// We haven't gotten to the appropriate old fragment yet, so stop.
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -1167,7 +1179,7 @@ impl FragmentMap {
|
||||||
match worklist.as_slice().last() {
|
match worklist.as_slice().last() {
|
||||||
None => break,
|
None => break,
|
||||||
Some(last_work_item) => {
|
Some(last_work_item) => {
|
||||||
if last_work_item.old_end_index > old_fragment_index as int + 1 {
|
if last_work_item.old_end_index > old_fragment_index + FragmentIndex(1) {
|
||||||
// Haven't gotten to it yet.
|
// Haven't gotten to it yet.
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -1177,10 +1189,12 @@ impl FragmentMap {
|
||||||
let new_last_index = match new_fragments_iter.peek() {
|
let new_last_index = match new_fragments_iter.peek() {
|
||||||
None => {
|
None => {
|
||||||
// At the end.
|
// At the end.
|
||||||
new_fragments.len()
|
FragmentIndex(new_fragments.len() as int)
|
||||||
}
|
}
|
||||||
Some(&(index, _)) => index,
|
Some(&(index, _)) => {
|
||||||
} as int;
|
FragmentIndex(index as int)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
let FragmentFixupWorkItem {
|
let FragmentFixupWorkItem {
|
||||||
style,
|
style,
|
||||||
|
@ -1198,11 +1212,11 @@ impl FragmentMap {
|
||||||
/// conveniently to various fragment functions.
|
/// conveniently to various fragment functions.
|
||||||
pub struct InlineFragmentContext<'a> {
|
pub struct InlineFragmentContext<'a> {
|
||||||
map: &'a FragmentMap,
|
map: &'a FragmentMap,
|
||||||
index: int,
|
index: FragmentIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> InlineFragmentContext<'a> {
|
impl<'a> InlineFragmentContext<'a> {
|
||||||
pub fn new<'a>(map: &'a FragmentMap, index: int) -> InlineFragmentContext<'a> {
|
pub fn new<'a>(map: &'a FragmentMap, index: FragmentIndex) -> InlineFragmentContext<'a> {
|
||||||
InlineFragmentContext {
|
InlineFragmentContext {
|
||||||
map: map,
|
map: map,
|
||||||
index: index,
|
index: index,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue