aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2015-08-05 09:28:39 -0700
committerPatrick Walton <pcwalton@mimiga.net>2015-08-11 11:42:20 -0700
commitae378a8c3e1b77fe4e1ab3b8602900d32844756c (patch)
tree0873c035bdd1684dde96ff5f6da8078fa58db541
parent9c528c6382ee4355f42824a7caad217c4eb8a3b0 (diff)
downloadservo-ae378a8c3e1b77fe4e1ab3b8602900d32844756c.tar.gz
servo-ae378a8c3e1b77fe4e1ab3b8602900d32844756c.zip
layout: Rewrite whitespace stripping.
This patch makes Servo unconditionally strip whitespace before text run scanning (assuming that the `white-space` property allows it). Whitespace stripping during reflow is now only used for handling whitespace at the ends of lines; reflow now never attempts to handle ignorable whitespace. Many CSS tests pass now. There are some new failures, however. The following reference tests now fail due to a pre-existing bug whereby whitespace is used to calculate the position of inline hypothetical boxes for elements with `display: inline; position: absolute`: * `absolute-replaced-height-036.htm` * `vertical-align-sub-001.htm` * `vertical-align-super-001.htm` The following reference tests fail due to a pre-existing bug whereby we don't handle `font-size: 0` properly in inline reflow: * `font-size-zero-1.htm` * `font-size-zero-2.htm` The following reference test fails due to the fact that it relied on our incorrect insertion of whitespace to make room for the black background: * `inline-formatting-context-007.htm`
-rw-r--r--components/gfx/text/util.rs2
-rw-r--r--components/layout/construct.rs79
-rw-r--r--components/layout/fragment.rs176
-rw-r--r--components/layout/inline.rs42
-rw-r--r--components/layout/text.rs11
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/absolute-replaced-height-036.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/bidi-breaking-001.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/block-in-inline-007.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/c5502-imrgn-r-003.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/c5525-fltwidth-003.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/content-175.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/floats-143.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/font-weight-applies-to-017.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/inline-formatting-context-007.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/insert-inline-in-blocks-n-inlines-begin-003.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/insert-inline-in-blocks-n-inlines-middle-003.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/ltr-basic.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/margin-collapse-137.htm.ini4
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/margin-collapse-138.htm.ini4
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/max-width-percentage-001.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/min-width-percentage-001.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/rtl-basic.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/text-transform-capitalize-001.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/text-transform-lowercase-001.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/text-transform-uppercase-001.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/vertical-align-sub-001.htm.ini (renamed from tests/wpt/metadata-css/css21_dev/html4/abspos-008.htm.ini)2
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/vertical-align-super-001.htm.ini (renamed from tests/wpt/metadata-css/css21_dev/html4/abspos-width-005.htm.ini)2
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/white-space-collapsing-bidi-003.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/white-space-normal-003.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/white-space-normal-004.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/white-space-pre-001.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/white-space-pre-002.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/width-percentage-001.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/width-percentage-002.htm.ini3
34 files changed, 216 insertions, 181 deletions
diff --git a/components/gfx/text/util.rs b/components/gfx/text/util.rs
index 1b78e42e792..855cb2d0dcd 100644
--- a/components/gfx/text/util.rs
+++ b/components/gfx/text/util.rs
@@ -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/. */
-#[derive(PartialEq, Eq, Copy, Clone)]
+#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum CompressionMode {
CompressNone,
CompressWhitespace,
diff --git a/components/layout/construct.rs b/components/layout/construct.rs
index 7194281e628..ce4417a5a00 100644
--- a/components/layout/construct.rs
+++ b/components/layout/construct.rs
@@ -26,6 +26,7 @@ use fragment::{Fragment, GeneratedContentInfo, IframeFragmentInfo};
use fragment::{CanvasFragmentInfo, ImageFragmentInfo, InlineAbsoluteFragmentInfo};
use fragment::{InlineAbsoluteHypotheticalFragmentInfo, TableColumnFragmentInfo};
use fragment::{InlineBlockFragmentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo};
+use fragment::{WhitespaceStrippingResult};
use incremental::{RECONSTRUCT_FLOW, RestyleDamage};
use inline::{InlineFlow, InlineFragmentNodeInfo};
use list_item::{ListItemFlow, ListStyleTypeContent};
@@ -58,6 +59,7 @@ use style::computed_values::{caption_side, display, empty_cells, float, list_sty
use style::computed_values::{position};
use style::properties::{self, ComputedValues};
use url::Url;
+use util::linked_list;
use util::opts;
/// The results of flow construction for a DOM node.
@@ -266,12 +268,6 @@ impl InlineFragmentsAccumulator {
}
}
-enum WhitespaceStrippingMode {
- None,
- FromStart,
- FromEnd,
-}
-
/// An object that knows how to create flows.
pub struct FlowConstructor<'a> {
/// The layout context.
@@ -414,27 +410,16 @@ impl<'a> FlowConstructor<'a> {
fragment_accumulator: InlineFragmentsAccumulator,
flow: &mut FlowRef,
flow_list: &mut Vec<FlowRef>,
- whitespace_stripping: WhitespaceStrippingMode,
node: &ThreadSafeLayoutNode) {
let mut fragments = fragment_accumulator.to_intermediate_inline_fragments();
if fragments.is_empty() {
return
};
- match whitespace_stripping {
- WhitespaceStrippingMode::None => {}
- WhitespaceStrippingMode::FromStart => {
- strip_ignorable_whitespace_from_start(&mut fragments.fragments);
- if fragments.is_empty() {
- return
- };
- }
- WhitespaceStrippingMode::FromEnd => {
- strip_ignorable_whitespace_from_end(&mut fragments.fragments);
- if fragments.is_empty() {
- return
- };
- }
+ strip_ignorable_whitespace_from_start(&mut fragments.fragments);
+ strip_ignorable_whitespace_from_end(&mut fragments.fragments);
+ if fragments.is_empty() {
+ return
}
// Build a list of all the inline-block fragments before fragments is moved.
@@ -504,8 +489,7 @@ impl<'a> FlowConstructor<'a> {
node: &ThreadSafeLayoutNode,
kid: ThreadSafeLayoutNode,
inline_fragment_accumulator: &mut InlineFragmentsAccumulator,
- abs_descendants: &mut Descendants,
- first_fragment: &mut bool) {
+ abs_descendants: &mut Descendants) {
match kid.swap_out_construction_result() {
ConstructionResult::None => {}
ConstructionResult::Flow(mut kid_flow, kid_abs_descendants) => {
@@ -527,7 +511,6 @@ impl<'a> FlowConstructor<'a> {
InlineFragmentsAccumulator::new()),
flow,
consecutive_siblings,
- WhitespaceStrippingMode::FromStart,
node);
if !consecutive_siblings.is_empty() {
let consecutive_siblings = mem::replace(consecutive_siblings, vec!());
@@ -554,15 +537,6 @@ impl<'a> FlowConstructor<'a> {
} = split;
inline_fragment_accumulator.push_all(predecessors);
- // If this is the first fragment in flow, then strip ignorable
- // whitespace per CSS 2.1 § 9.2.1.1.
- let whitespace_stripping = if *first_fragment {
- *first_fragment = false;
- WhitespaceStrippingMode::FromStart
- } else {
- WhitespaceStrippingMode::None
- };
-
// Flush any inline fragments that we were gathering up.
debug!("flushing {} inline box(es) to flow A",
inline_fragment_accumulator.fragments.fragments.len());
@@ -571,7 +545,6 @@ impl<'a> FlowConstructor<'a> {
InlineFragmentsAccumulator::new()),
flow,
consecutive_siblings,
- whitespace_stripping,
node);
// Push the flow generated by the {ib} split onto our list of
@@ -625,7 +598,6 @@ impl<'a> FlowConstructor<'a> {
let mut consecutive_siblings = vec!();
inline_fragment_accumulator.fragments.push_all(initial_fragments);
- let mut first_fragment = inline_fragment_accumulator.fragments.is_empty();
// List of absolute descendants, in tree order.
let mut abs_descendants = Descendants::new();
@@ -640,8 +612,7 @@ impl<'a> FlowConstructor<'a> {
node,
kid,
&mut inline_fragment_accumulator,
- &mut abs_descendants,
- &mut first_fragment);
+ &mut abs_descendants);
}
// Perform a final flush of any inline fragments that we were gathering up to handle {ib}
@@ -649,7 +620,6 @@ impl<'a> FlowConstructor<'a> {
self.flush_inline_fragments_to_flow_or_list(inline_fragment_accumulator,
&mut flow,
&mut consecutive_siblings,
- WhitespaceStrippingMode::FromEnd,
node);
if !consecutive_siblings.is_empty() {
self.generate_anonymous_missing_child(consecutive_siblings, &mut flow, node);
@@ -1665,10 +1635,21 @@ pub fn strip_ignorable_whitespace_from_start(this: &mut LinkedList<Fragment>) {
return // Fast path.
}
- while !this.is_empty() && this.front().as_ref().unwrap().is_ignorable_whitespace() {
- debug!("stripping ignorable whitespace from start");
- drop(this.pop_front());
+ let mut leading_fragments_consisting_of_solely_bidi_control_characters = LinkedList::new();
+ while !this.is_empty() {
+ match this.front_mut().as_mut().unwrap().strip_leading_whitespace_if_necessary() {
+ WhitespaceStrippingResult::RetainFragment => break,
+ WhitespaceStrippingResult::FragmentContainedOnlyBidiControlCharacters => {
+ leading_fragments_consisting_of_solely_bidi_control_characters.push_back(
+ this.pop_front().unwrap())
+ }
+ WhitespaceStrippingResult::FragmentContainedOnlyWhitespace => {
+ this.pop_front();
+ }
+ }
}
+ linked_list::prepend_from(this,
+ &mut leading_fragments_consisting_of_solely_bidi_control_characters)
}
/// Strips ignorable whitespace from the end of a list of fragments.
@@ -1677,10 +1658,20 @@ pub fn strip_ignorable_whitespace_from_end(this: &mut LinkedList<Fragment>) {
return
}
- while !this.is_empty() && this.back().as_ref().unwrap().is_ignorable_whitespace() {
- debug!("stripping ignorable whitespace from end");
- drop(this.pop_back());
+ let mut trailing_fragments_consisting_of_solely_bidi_control_characters = LinkedList::new();
+ while !this.is_empty() {
+ match this.back_mut().as_mut().unwrap().strip_trailing_whitespace_if_necessary() {
+ WhitespaceStrippingResult::RetainFragment => break,
+ WhitespaceStrippingResult::FragmentContainedOnlyBidiControlCharacters => {
+ trailing_fragments_consisting_of_solely_bidi_control_characters.push_front(
+ this.pop_back().unwrap())
+ }
+ WhitespaceStrippingResult::FragmentContainedOnlyWhitespace => {
+ this.pop_back();
+ }
+ }
}
+ this.append(&mut trailing_fragments_consisting_of_solely_bidi_control_characters);
}
/// If the 'unicode-bidi' property has a value other than 'normal', return the bidi control codes
diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs
index d2b21b0a178..be3aaa4b9f2 100644
--- a/components/layout/fragment.rs
+++ b/components/layout/fragment.rs
@@ -23,6 +23,7 @@ use euclid::{Point2D, Rect, Size2D};
use gfx::display_list::{BLUR_INFLATION_FACTOR, OpaqueNode};
use gfx::text::glyph::CharIndex;
use gfx::text::text_run::{TextRun, TextRunSlice};
+use gfx;
use ipc_channel::ipc::IpcSender;
use msg::constellation_msg::{ConstellationChan, Msg, PipelineId, SubpageId};
use net_traits::image::base::Image;
@@ -210,6 +211,9 @@ impl fmt::Debug for SpecificFragmentInfo {
write!(f, " \"{}\"", slice_chars(&*info.run.text, info.range.begin().get() as usize,
info.range.end().get() as usize))
}
+ SpecificFragmentInfo::UnscannedText(ref info) => {
+ write!(f, " \"{}\"", info.text)
+ }
_ => Ok(())
}
}
@@ -2102,35 +2106,144 @@ impl Fragment {
}
}
- pub fn strip_leading_whitespace_if_necessary(&mut self) {
- let mut scanned_text_fragment_info = match self.specific {
+ pub fn strip_leading_whitespace_if_necessary(&mut self) -> WhitespaceStrippingResult {
+ if self.style.get_inheritedtext().white_space == white_space::T::pre {
+ return WhitespaceStrippingResult::RetainFragment
+ }
+
+ match self.specific {
SpecificFragmentInfo::ScannedText(ref mut scanned_text_fragment_info) => {
- scanned_text_fragment_info
+ let mut leading_whitespace_character_count = 0;
+ {
+ let text = slice_chars(
+ &*scanned_text_fragment_info.run.text,
+ scanned_text_fragment_info.range.begin().to_usize(),
+ scanned_text_fragment_info.range.end().to_usize());
+ for character in text.chars() {
+ if util::str::char_is_whitespace(character) {
+ leading_whitespace_character_count += 1
+ } else {
+ break
+ }
+ }
+ }
+
+ let whitespace_range = Range::new(scanned_text_fragment_info.range.begin(),
+ CharIndex(leading_whitespace_character_count));
+ let text_bounds =
+ scanned_text_fragment_info.run.metrics_for_range(&whitespace_range).bounding_box;
+ self.border_box.size.inline = self.border_box.size.inline - text_bounds.size.width;
+ scanned_text_fragment_info.content_size.inline =
+ scanned_text_fragment_info.content_size.inline - text_bounds.size.width;
+
+ scanned_text_fragment_info.range.adjust_by(
+ CharIndex(leading_whitespace_character_count),
+ -CharIndex(leading_whitespace_character_count));
+
+ return WhitespaceStrippingResult::RetainFragment
+ }
+ SpecificFragmentInfo::UnscannedText(ref mut unscanned_text_fragment_info) => {
+ let mut new_text_string = String::new();
+ let mut modified = false;
+ for (i, character) in unscanned_text_fragment_info.text.char_indices() {
+ if gfx::text::util::is_bidi_control(character) {
+ new_text_string.push(character);
+ continue
+ }
+ if util::str::char_is_whitespace(character) {
+ modified = true;
+ continue
+ }
+ new_text_string.push_str(&unscanned_text_fragment_info.text[i..]);
+ break
+ }
+ if modified {
+ unscanned_text_fragment_info.text = new_text_string.into_boxed_slice();
+ }
+
+ WhitespaceStrippingResult::from_unscanned_text_fragment_info(
+ &unscanned_text_fragment_info)
}
- _ => return,
- };
+ _ => WhitespaceStrippingResult::RetainFragment,
+ }
+ }
+ /// Returns true if the entire fragment was stripped.
+ pub fn strip_trailing_whitespace_if_necessary(&mut self) -> WhitespaceStrippingResult {
if self.style.get_inheritedtext().white_space == white_space::T::pre {
- return
- }
-
- let mut leading_whitespace_character_count = 0;
- {
- let text = slice_chars(
- &*scanned_text_fragment_info.run.text,
- scanned_text_fragment_info.range.begin().to_usize(),
- scanned_text_fragment_info.range.end().to_usize());
- for character in text.chars() {
- if util::str::char_is_whitespace(character) {
- leading_whitespace_character_count += 1
- } else {
+ return WhitespaceStrippingResult::RetainFragment
+ }
+
+ match self.specific {
+ SpecificFragmentInfo::ScannedText(ref mut scanned_text_fragment_info) => {
+ // FIXME(pcwalton): Is there a more clever (i.e. faster) way to do this?
+ debug!("stripping trailing whitespace: range={:?}, len={}",
+ scanned_text_fragment_info.range,
+ scanned_text_fragment_info.run.text.chars().count());
+ let mut trailing_whitespace_character_count = 0;
+ let text_bounds;
+ {
+ let text = slice_chars(&*scanned_text_fragment_info.run.text,
+ scanned_text_fragment_info.range.begin().to_usize(),
+ scanned_text_fragment_info.range.end().to_usize());
+ for ch in text.chars().rev() {
+ if util::str::char_is_whitespace(ch) {
+ trailing_whitespace_character_count += 1
+ } else {
+ break
+ }
+ }
+
+ let whitespace_range =
+ Range::new(scanned_text_fragment_info.range.end() -
+ CharIndex(trailing_whitespace_character_count),
+ CharIndex(trailing_whitespace_character_count));
+ text_bounds = scanned_text_fragment_info.run
+ .metrics_for_range(&whitespace_range)
+ .bounding_box;
+ self.border_box.size.inline = self.border_box.size.inline -
+ text_bounds.size.width;
+ }
+
+ scanned_text_fragment_info.content_size.inline =
+ scanned_text_fragment_info.content_size.inline - text_bounds.size.width;
+
+ if trailing_whitespace_character_count != 0 {
+ scanned_text_fragment_info.range.extend_by(
+ CharIndex(-trailing_whitespace_character_count));
+ }
+
+ WhitespaceStrippingResult::RetainFragment
+ }
+ SpecificFragmentInfo::UnscannedText(ref mut unscanned_text_fragment_info) => {
+ let mut trailing_bidi_control_characters_to_retain = Vec::new();
+ let (mut modified, mut last_character_index) = (true, 0);
+ for (i, character) in unscanned_text_fragment_info.text.char_indices().rev() {
+ if gfx::text::util::is_bidi_control(character) {
+ trailing_bidi_control_characters_to_retain.push(character);
+ continue
+ }
+ if util::str::char_is_whitespace(character) {
+ modified = true;
+ continue
+ }
+ last_character_index = i + character.len_utf8();
break
}
+ if modified {
+ let mut text = unscanned_text_fragment_info.text.to_string();
+ text.truncate(last_character_index);
+ for character in trailing_bidi_control_characters_to_retain.iter().rev() {
+ text.push(*character);
+ }
+ unscanned_text_fragment_info.text = text.into_boxed_slice();
+ }
+
+ WhitespaceStrippingResult::from_unscanned_text_fragment_info(
+ &unscanned_text_fragment_info)
}
+ _ => WhitespaceStrippingResult::RetainFragment,
}
-
- scanned_text_fragment_info.range.adjust_by(CharIndex(leading_whitespace_character_count),
- -CharIndex(leading_whitespace_character_count));
}
pub fn inline_styles<'a>(&'a self) -> InlineStyleIterator<'a> {
@@ -2232,3 +2345,24 @@ impl<'a> InlineStyleIterator<'a> {
}
}
}
+
+#[derive(Copy, Clone, Debug)]
+pub enum WhitespaceStrippingResult {
+ RetainFragment,
+ FragmentContainedOnlyBidiControlCharacters,
+ FragmentContainedOnlyWhitespace,
+}
+
+impl WhitespaceStrippingResult {
+ fn from_unscanned_text_fragment_info(info: &UnscannedTextFragmentInfo)
+ -> WhitespaceStrippingResult {
+ if info.text.is_empty() {
+ WhitespaceStrippingResult::FragmentContainedOnlyWhitespace
+ } else if info.text.chars().all(gfx::text::util::is_bidi_control) {
+ WhitespaceStrippingResult::FragmentContainedOnlyBidiControlCharacters
+ } else {
+ WhitespaceStrippingResult::RetainFragment
+ }
+ }
+}
+
diff --git a/components/layout/inline.rs b/components/layout/inline.rs
index 359660e05ed..22e6366cf82 100644
--- a/components/layout/inline.rs
+++ b/components/layout/inline.rs
@@ -21,8 +21,6 @@ use euclid::{Point2D, Rect, Size2D};
use gfx::display_list::OpaqueNode;
use gfx::font::FontMetrics;
use gfx::font_context::FontContext;
-use gfx::text::glyph::CharIndex;
-use gfx::text::text_run::TextRun;
use std::cmp::max;
use std::collections::VecDeque;
use std::fmt;
@@ -36,7 +34,6 @@ use unicode_bidi;
use util::geometry::{Au, MAX_AU, ZERO_RECT};
use util::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
use util::range::{Range, RangeIndex};
-use util::str::slice_chars;
use util;
// From gfxFontConstants.h in Firefox
@@ -408,21 +405,27 @@ impl LineBreaker {
}
let last_fragment_index = self.pending_line.range.end() - FragmentIndex(1);
let mut fragment = &mut self.new_fragments[last_fragment_index.get() as usize];
+
+ let mut old_fragment_inline_size = None;
+ if let SpecificFragmentInfo::ScannedText(_) = fragment.specific {
+ old_fragment_inline_size = Some(fragment.border_box.size.inline +
+ fragment.margin.inline_start_end());
+ }
+
+ fragment.strip_trailing_whitespace_if_necessary();
+
if let SpecificFragmentInfo::ScannedText(ref mut scanned_text_fragment_info) =
fragment.specific {
let scanned_text_fragment_info = &mut **scanned_text_fragment_info;
- let mut range = &mut scanned_text_fragment_info.range;
- strip_trailing_whitespace_if_necessary(&*scanned_text_fragment_info.run, range);
+ let range = &mut scanned_text_fragment_info.range;
- let old_fragment_inline_size = fragment.border_box.size.inline +
- fragment.margin.inline_start_end();
scanned_text_fragment_info.content_size.inline =
scanned_text_fragment_info.run.metrics_for_range(range).advance_width;
fragment.border_box.size.inline = scanned_text_fragment_info.content_size.inline +
fragment.border_padding.inline_start_end();
self.pending_line.bounds.size.inline = self.pending_line.bounds.size.inline -
- (old_fragment_inline_size - (fragment.border_box.size.inline +
- fragment.margin.inline_start_end()))
+ (old_fragment_inline_size.unwrap() -
+ (fragment.border_box.size.inline + fragment.margin.inline_start_end()));
}
}
@@ -1869,24 +1872,3 @@ enum LineFlushMode {
Flush,
}
-/// Given a range and a text run, adjusts the range to eliminate trailing whitespace.
-fn strip_trailing_whitespace_if_necessary(text_run: &TextRun, range: &mut Range<CharIndex>) {
- // FIXME(pcwalton): Is there a more clever (i.e. faster) way to do this?
- debug!("stripping trailing whitespace: range={:?}, len={}",
- range,
- text_run.text.chars().count());
- let text = slice_chars(&*text_run.text, range.begin().to_usize(), range.end().to_usize());
- let mut trailing_whitespace_character_count = 0;
- for ch in text.chars().rev() {
- if util::str::char_is_whitespace(ch) {
- trailing_whitespace_character_count += 1
- } else {
- break
- }
- }
-
- if trailing_whitespace_character_count != 0 {
- range.extend_by(CharIndex(-trailing_whitespace_character_count));
- }
-}
-
diff --git a/components/layout/text.rs b/components/layout/text.rs
index a9141ddb9a0..fb1e2b9375e 100644
--- a/components/layout/text.rs
+++ b/components/layout/text.rs
@@ -90,7 +90,7 @@ impl TextRunScanner {
// FIXME(pcwalton): We want to be sure not to allocate multiple times, since this is a
// performance-critical spot, but this may overestimate and allocate too much memory.
let mut new_fragments = Vec::with_capacity(fragments.len());
- let mut last_whitespace = true;
+ let mut last_whitespace = false;
let mut paragraph_bytes_processed = 0;
while !fragments.is_empty() {
@@ -142,7 +142,7 @@ impl TextRunScanner {
debug_assert!(self.clump.len() == 1,
"WAT: can't coalesce non-text nodes in flush_clump_to_list()!");
out_fragments.push(self.clump.pop_front().unwrap());
- return last_whitespace
+ return false
}
}
@@ -398,14 +398,13 @@ fn split_first_fragment_at_newline_if_necessary(fragments: &mut LinkedList<Fragm
};
string_before =
- unscanned_text_fragment_info.text[..(position + 1)].to_owned().into_boxed_slice();
+ unscanned_text_fragment_info.text[..(position + 1)].to_owned();
unscanned_text_fragment_info.text =
unscanned_text_fragment_info.text[(position + 1)..].to_owned().into_boxed_slice();
}
first_fragment.transform(first_fragment.border_box.size,
- SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo {
- text: string_before,
- }))
+ SpecificFragmentInfo::UnscannedText(
+ UnscannedTextFragmentInfo::from_text(string_before)))
};
fragments.push_front(new_fragment);
diff --git a/tests/wpt/metadata-css/css21_dev/html4/absolute-replaced-height-036.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/absolute-replaced-height-036.htm.ini
new file mode 100644
index 00000000000..392bfcdf387
--- /dev/null
+++ b/tests/wpt/metadata-css/css21_dev/html4/absolute-replaced-height-036.htm.ini
@@ -0,0 +1,3 @@
+[absolute-replaced-height-036.htm]
+ type: reftest
+ expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/bidi-breaking-001.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/bidi-breaking-001.htm.ini
deleted file mode 100644
index c72b49545e2..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/bidi-breaking-001.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[bidi-breaking-001.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/block-in-inline-007.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/block-in-inline-007.htm.ini
deleted file mode 100644
index 2b961d66bc5..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/block-in-inline-007.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[block-in-inline-007.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/c5502-imrgn-r-003.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/c5502-imrgn-r-003.htm.ini
index 2b4ce534e8f..0d70e461e54 100644
--- a/tests/wpt/metadata-css/css21_dev/html4/c5502-imrgn-r-003.htm.ini
+++ b/tests/wpt/metadata-css/css21_dev/html4/c5502-imrgn-r-003.htm.ini
@@ -1,3 +1,4 @@
[c5502-imrgn-r-003.htm]
type: reftest
- expected: FAIL
+ expected:
+ if os == "mac": FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/c5525-fltwidth-003.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/c5525-fltwidth-003.htm.ini
deleted file mode 100644
index 4d4f6b0abd9..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/c5525-fltwidth-003.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[c5525-fltwidth-003.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/content-175.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/content-175.htm.ini
deleted file mode 100644
index 985f3341bda..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/content-175.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[content-175.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/floats-143.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/floats-143.htm.ini
deleted file mode 100644
index 18e916f6110..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/floats-143.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[floats-143.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/font-weight-applies-to-017.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/font-weight-applies-to-017.htm.ini
deleted file mode 100644
index 2681f67b12b..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/font-weight-applies-to-017.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[font-weight-applies-to-017.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/inline-formatting-context-007.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/inline-formatting-context-007.htm.ini
index b9f024e1851..8bc13abc629 100644
--- a/tests/wpt/metadata-css/css21_dev/html4/inline-formatting-context-007.htm.ini
+++ b/tests/wpt/metadata-css/css21_dev/html4/inline-formatting-context-007.htm.ini
@@ -1,4 +1,3 @@
[inline-formatting-context-007.htm]
type: reftest
- expected:
- if os == "mac": FAIL
+ expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/insert-inline-in-blocks-n-inlines-begin-003.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/insert-inline-in-blocks-n-inlines-begin-003.htm.ini
deleted file mode 100644
index 94c3a3dafb9..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/insert-inline-in-blocks-n-inlines-begin-003.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[insert-inline-in-blocks-n-inlines-begin-003.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/insert-inline-in-blocks-n-inlines-middle-003.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/insert-inline-in-blocks-n-inlines-middle-003.htm.ini
deleted file mode 100644
index 5210ddc3c38..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/insert-inline-in-blocks-n-inlines-middle-003.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[insert-inline-in-blocks-n-inlines-middle-003.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/ltr-basic.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/ltr-basic.htm.ini
deleted file mode 100644
index af0cafc5b44..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/ltr-basic.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[ltr-basic.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/margin-collapse-137.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/margin-collapse-137.htm.ini
deleted file mode 100644
index e67ac47b0fa..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/margin-collapse-137.htm.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[margin-collapse-137.htm]
- type: reftest
- expected:
- if os == "linux": FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/margin-collapse-138.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/margin-collapse-138.htm.ini
deleted file mode 100644
index a210ef90f7e..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/margin-collapse-138.htm.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[margin-collapse-138.htm]
- type: reftest
- expected:
- if os == "linux": FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/max-width-percentage-001.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/max-width-percentage-001.htm.ini
deleted file mode 100644
index 36517e6997e..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/max-width-percentage-001.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[max-width-percentage-001.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/min-width-percentage-001.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/min-width-percentage-001.htm.ini
deleted file mode 100644
index b5cd88ea4fd..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/min-width-percentage-001.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[min-width-percentage-001.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/rtl-basic.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/rtl-basic.htm.ini
deleted file mode 100644
index 42633ad1fbf..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/rtl-basic.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[rtl-basic.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/text-transform-capitalize-001.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/text-transform-capitalize-001.htm.ini
deleted file mode 100644
index 7c32cf23456..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/text-transform-capitalize-001.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[text-transform-capitalize-001.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/text-transform-lowercase-001.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/text-transform-lowercase-001.htm.ini
deleted file mode 100644
index 6ade2048556..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/text-transform-lowercase-001.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[text-transform-lowercase-001.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/text-transform-uppercase-001.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/text-transform-uppercase-001.htm.ini
deleted file mode 100644
index 7bfc3cdb85b..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/text-transform-uppercase-001.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[text-transform-uppercase-001.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/abspos-008.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/vertical-align-sub-001.htm.ini
index 32802cb85e0..c2e59e13bc8 100644
--- a/tests/wpt/metadata-css/css21_dev/html4/abspos-008.htm.ini
+++ b/tests/wpt/metadata-css/css21_dev/html4/vertical-align-sub-001.htm.ini
@@ -1,3 +1,3 @@
-[abspos-008.htm]
+[vertical-align-sub-001.htm]
type: reftest
expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/abspos-width-005.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/vertical-align-super-001.htm.ini
index 878cb95f3f5..f839dc96763 100644
--- a/tests/wpt/metadata-css/css21_dev/html4/abspos-width-005.htm.ini
+++ b/tests/wpt/metadata-css/css21_dev/html4/vertical-align-super-001.htm.ini
@@ -1,3 +1,3 @@
-[abspos-width-005.htm]
+[vertical-align-super-001.htm]
type: reftest
expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/white-space-collapsing-bidi-003.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/white-space-collapsing-bidi-003.htm.ini
deleted file mode 100644
index 4d98e27aa79..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/white-space-collapsing-bidi-003.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[white-space-collapsing-bidi-003.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/white-space-normal-003.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/white-space-normal-003.htm.ini
deleted file mode 100644
index d41d1dfc4fb..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/white-space-normal-003.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[white-space-normal-003.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/white-space-normal-004.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/white-space-normal-004.htm.ini
deleted file mode 100644
index b31c84b37b1..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/white-space-normal-004.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[white-space-normal-004.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/white-space-pre-001.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/white-space-pre-001.htm.ini
deleted file mode 100644
index e21ed4aafd9..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/white-space-pre-001.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[white-space-pre-001.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/white-space-pre-002.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/white-space-pre-002.htm.ini
deleted file mode 100644
index 99e24c86c87..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/white-space-pre-002.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[white-space-pre-002.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/width-percentage-001.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/width-percentage-001.htm.ini
deleted file mode 100644
index 0cf4f7f61ac..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/width-percentage-001.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[width-percentage-001.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/width-percentage-002.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/width-percentage-002.htm.ini
deleted file mode 100644
index e42f7d4970e..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/width-percentage-002.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[width-percentage-002.htm]
- type: reftest
- expected: FAIL