Skip to content

Commit

Permalink
Turn white-space into a shorthand
Browse files Browse the repository at this point in the history
Bumps Stylo to servo/stylo#37

`white-space` is split into `text-wrap-mode` and `white-space-collapse`:

| white-space | white-space-collapse | text-wrap-mode |
| ----------- | -------------------- | -------------- |
| normal      | collapse             | wrap           |
| nowrap      | collapse             | nowrap         |
| pre-wrap    | preserve             | wrap           |
| pre         | preserve             | nowrap         |
| pre-line    | preserve-breaks      | wrap           |
| -           | preserve-breaks      | nowrap         |

Note this introduces a combination that wasn't previously possible,
but I think the existing logic can handle it well enough.

The old `allow_wrap()` is replaced by checking whether `text-wrap-mode`
is set to `wrap`.

The old `preserve_newlines()` is replaced by checking whether
`white-space-collapse` is *not* set to `collapse`.

The old `preserve_spaces()` is replaced by checking whether
`white-space-collapse` is set to `preserve`.
  • Loading branch information
Loirooriol committed Apr 26, 2024
1 parent 66563ed commit 6027fc9
Show file tree
Hide file tree
Showing 23 changed files with 141 additions and 454 deletions.
26 changes: 13 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 9 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ keyboard-types = "0.6"
lazy_static = "1.4"
libc = "0.2"
log = "0.4"
malloc_size_of = { git = "https://github.com/servo/stylo", branch = "2024-04-16", features = ["servo"] }
malloc_size_of = { git = "https://github.com/servo/stylo", rev = "refs/pull/37/head", features = ["servo"] }
malloc_size_of_derive = "0.1"
mime = "0.3.13"
mime_guess = "2.0.3"
Expand All @@ -87,31 +87,31 @@ rustls = { version = "0.21.12", features = ["dangerous_configuration"] }
rustls-pemfile = "1.0.4"
script_layout_interface = { path = "components/shared/script_layout" }
script_traits = { path = "components/shared/script" }
selectors = { git = "https://github.com/servo/stylo", branch = "2024-04-16" }
selectors = { git = "https://github.com/servo/stylo", rev = "refs/pull/37/head" }
serde = "1.0.198"
serde_bytes = "0.11"
serde_json = "1.0"
servo-media = { git = "https://github.com/servo/media" }
servo-media-dummy = { git = "https://github.com/servo/media" }
servo-media-gstreamer = { git = "https://github.com/servo/media" }
servo_arc = { git = "https://github.com/servo/stylo", branch = "2024-04-16" }
servo_atoms = { git = "https://github.com/servo/stylo", branch = "2024-04-16" }
size_of_test = { git = "https://github.com/servo/stylo", branch = "2024-04-16" }
servo_arc = { git = "https://github.com/servo/stylo", rev = "refs/pull/37/head" }
servo_atoms = { git = "https://github.com/servo/stylo", rev = "refs/pull/37/head" }
size_of_test = { git = "https://github.com/servo/stylo", rev = "refs/pull/37/head" }
smallbitvec = "2.5.3"
smallvec = "1.13"
sparkle = "0.1.26"
string_cache = "0.8"
string_cache_codegen = "0.5"
style = { git = "https://github.com/servo/stylo", branch = "2024-04-16", features = ["servo"] }
style_config = { git = "https://github.com/servo/stylo", branch = "2024-04-16" }
style_traits = { git = "https://github.com/servo/stylo", branch = "2024-04-16", features = ["servo"] }
style = { git = "https://github.com/servo/stylo", rev = "refs/pull/37/head", features = ["servo"] }
style_config = { git = "https://github.com/servo/stylo", rev = "refs/pull/37/head" }
style_traits = { git = "https://github.com/servo/stylo", rev = "refs/pull/37/head", features = ["servo"] }
# NOTE: the sm-angle feature only 2024-03-01rms!
surfman = { version = "0.9", features = ["chains", "sm-angle", "sm-angle-default"] }
syn = { version = "2", default-features = false, features = ["clone-impls", "derive", "parsing"] }
synstructure = "0.13"
thin-vec = "0.2.13"
time = "0.1.41"
to_shmem = { git = "https://github.com/servo/stylo", branch = "2024-04-16" }
to_shmem = { git = "https://github.com/servo/stylo", rev = "refs/pull/37/head" }
tokio = "1"
tokio-rustls = "0.24"
tungstenite = "0.20"
Expand Down
24 changes: 15 additions & 9 deletions components/layout/fragment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ use style::computed_values::overflow_wrap::T as OverflowWrap;
use style::computed_values::overflow_x::T as StyleOverflow;
use style::computed_values::position::T as Position;
use style::computed_values::text_decoration_line::T as TextDecorationLine;
use style::computed_values::text_wrap_mode::T as TextWrapMode;
use style::computed_values::transform_style::T as TransformStyle;
use style::computed_values::white_space::T as WhiteSpace;
use style::computed_values::white_space_collapse::T as WhiteSpaceCollapse;
use style::computed_values::word_break::T as WordBreak;
use style::logical_geometry::{Direction, LogicalMargin, LogicalRect, LogicalSize, WritingMode};
use style::properties::ComputedValues;
Expand Down Expand Up @@ -1539,8 +1540,12 @@ impl Fragment {
&self.selected_style
}

pub fn white_space(&self) -> WhiteSpace {
self.style().get_inherited_text().white_space
pub fn white_space_collapse(&self) -> WhiteSpaceCollapse {
self.style().get_inherited_text().white_space_collapse
}

pub fn text_wrap_mode(&self) -> TextWrapMode {
self.style().get_inherited_text().text_wrap_mode
}

pub fn color(&self) -> Color {
Expand Down Expand Up @@ -1586,7 +1591,7 @@ impl Fragment {
/// Returns true if this element can be split. This is true for text fragments, unless
/// `white-space: pre` or `white-space: nowrap` is set.
pub fn can_split(&self) -> bool {
self.is_scanned_text_fragment() && self.white_space().allow_wrap()
self.is_scanned_text_fragment() && self.text_wrap_mode() == TextWrapMode::Wrap
}

/// Returns true if and only if this fragment is a generated content fragment.
Expand Down Expand Up @@ -1703,7 +1708,7 @@ impl Fragment {
.metrics_for_range(range)
.advance_width;

let min_line_inline_size = if self_.white_space().allow_wrap() {
let min_line_inline_size = if self_.text_wrap_mode() == TextWrapMode::Wrap {
text_fragment_info.run.min_width_for_range(range)
} else {
max_line_inline_size
Expand Down Expand Up @@ -1968,7 +1973,7 @@ impl Fragment {
// see if we're going to overflow the line. If so, perform a best-effort split.
let mut remaining_range = slice.text_run_range();
let split_is_empty = inline_start_range.is_empty() &&
(self.white_space().allow_wrap() ||
(self.text_wrap_mode() == TextWrapMode::Wrap ||
!self.requires_line_break_afterward_if_wrapping_on_newlines());
if split_is_empty {
// We're going to overflow the line.
Expand Down Expand Up @@ -2520,7 +2525,8 @@ impl Fragment {
// FIXME: Should probably use a whitelist of styles that can safely differ (#3165)
if self.style().get_font() != other.style().get_font() ||
self.text_decoration_line() != other.text_decoration_line() ||
self.white_space() != other.white_space() ||
self.white_space_collapse() != other.white_space_collapse() ||
self.text_wrap_mode() != other.text_wrap_mode() ||
self.color() != other.color()
{
return false;
Expand Down Expand Up @@ -2893,7 +2899,7 @@ impl Fragment {
}

pub fn strip_leading_whitespace_if_necessary(&mut self) -> WhitespaceStrippingResult {
if self.white_space().preserve_spaces() {
if self.white_space_collapse() == WhiteSpaceCollapse::Preserve {
return WhitespaceStrippingResult::RetainFragment;
}

Expand Down Expand Up @@ -2963,7 +2969,7 @@ impl Fragment {

/// Returns true if the entire fragment was stripped.
pub fn strip_trailing_whitespace_if_necessary(&mut self) -> WhitespaceStrippingResult {
if self.white_space().preserve_spaces() {
if self.white_space_collapse() == WhiteSpaceCollapse::Preserve {
return WhitespaceStrippingResult::RetainFragment;
}

Expand Down
30 changes: 20 additions & 10 deletions components/layout/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ use style::computed_values::overflow_x::T as StyleOverflow;
use style::computed_values::position::T as Position;
use style::computed_values::text_align::T as TextAlign;
use style::computed_values::text_justify::T as TextJustify;
use style::computed_values::white_space::T as WhiteSpace;
use style::computed_values::text_wrap_mode::T as TextWrapMode;
use style::computed_values::white_space_collapse::T as WhiteSpaceCollapse;
use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
use style::properties::ComputedValues;
use style::servo::restyle_damage::ServoRestyleDamage;
Expand Down Expand Up @@ -622,7 +623,7 @@ impl LineBreaker {
if fragment.suppress_line_break_before() || !fragment.is_on_glyph_run_boundary() {
false
} else {
fragment.white_space().allow_wrap()
fragment.text_wrap_mode() == TextWrapMode::Wrap
}
};

Expand Down Expand Up @@ -663,7 +664,7 @@ impl LineBreaker {

// If we must flush the line after finishing this fragment due to `white-space: pre`,
// detect that.
let line_flush_mode = if fragment.white_space().preserve_newlines() {
let line_flush_mode = if fragment.white_space_collapse() != WhiteSpaceCollapse::Collapse {
if fragment.requires_line_break_afterward_if_wrapping_on_newlines() {
LineFlushMode::Flush
} else {
Expand All @@ -687,7 +688,7 @@ impl LineBreaker {

// If the wrapping mode prevents us from splitting, then back up and split at the last
// known good split point.
if !fragment.white_space().allow_wrap() {
if fragment.text_wrap_mode() == TextWrapMode::Nowrap {
debug!(
"LineBreaker: fragment can't split; falling back to last known good split point"
);
Expand Down Expand Up @@ -1494,10 +1495,16 @@ impl Flow for InlineFlow {
let mut intrinsic_sizes_for_nonbroken_run = IntrinsicISizesContribution::new();
for fragment in &mut self.fragments.fragments {
let intrinsic_sizes_for_fragment = fragment.compute_intrinsic_inline_sizes().finish();
match fragment.style.get_inherited_text().white_space {
WhiteSpace::Nowrap => intrinsic_sizes_for_nonbroken_run
.union_nonbreaking_inline(&intrinsic_sizes_for_fragment),
WhiteSpace::Pre => {
let style_text = fragment.style.get_inherited_text();
match (style_text.white_space_collapse, style_text.text_wrap_mode) {
(WhiteSpaceCollapse::Collapse, TextWrapMode::Nowrap) => {
intrinsic_sizes_for_nonbroken_run
.union_nonbreaking_inline(&intrinsic_sizes_for_fragment)
},
(
WhiteSpaceCollapse::Preserve | WhiteSpaceCollapse::PreserveBreaks,
TextWrapMode::Nowrap,
) => {
intrinsic_sizes_for_nonbroken_run
.union_nonbreaking_inline(&intrinsic_sizes_for_fragment);

Expand All @@ -1512,7 +1519,10 @@ impl Flow for InlineFlow {
intrinsic_sizes_for_inline_run = IntrinsicISizesContribution::new();
}
},
WhiteSpace::PreWrap | WhiteSpace::PreLine => {
(
WhiteSpaceCollapse::Preserve | WhiteSpaceCollapse::PreserveBreaks,
TextWrapMode::Wrap,
) => {
// Flush the intrinsic sizes we were gathering up for the nonbroken run, if
// necessary.
intrinsic_sizes_for_inline_run
Expand All @@ -1532,7 +1542,7 @@ impl Flow for InlineFlow {
intrinsic_sizes_for_inline_run = IntrinsicISizesContribution::new();
}
},
WhiteSpace::Normal => {
(WhiteSpaceCollapse::Collapse, TextWrapMode::Wrap) => {
// Flush the intrinsic sizes we were gathering up for the nonbroken run, if
// necessary.
intrinsic_sizes_for_inline_run
Expand Down
16 changes: 7 additions & 9 deletions components/layout/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use gfx::text::util::{self, CompressionMode};
use log::{debug, warn};
use range::Range;
use style::computed_values::text_rendering::T as TextRendering;
use style::computed_values::white_space::T as WhiteSpace;
use style::computed_values::white_space_collapse::T as WhiteSpaceCollapse;
use style::computed_values::word_break::T as WordBreak;
use style::logical_geometry::{LogicalSize, WritingMode};
use style::properties::style_structs::Font as FontStyleStruct;
Expand Down Expand Up @@ -46,7 +46,7 @@ fn text(fragments: &LinkedList<Fragment>) -> String {

for fragment in fragments {
if let SpecificFragmentInfo::UnscannedText(ref info) = fragment.specific {
if fragment.white_space().preserve_newlines() {
if fragment.white_space_collapse() != WhiteSpaceCollapse::Collapse {
text.push_str(&info.text);
} else {
text.push_str(&info.text.replace('\n', " "));
Expand Down Expand Up @@ -190,12 +190,10 @@ impl TextRunScanner {
let font_style = in_fragment.style().clone_font();
let inherited_text_style = in_fragment.style().get_inherited_text();
font_group = font_context.font_group(font_style);
compression = match in_fragment.white_space() {
WhiteSpace::Normal | WhiteSpace::Nowrap => {
CompressionMode::CompressWhitespaceNewline
},
WhiteSpace::Pre | WhiteSpace::PreWrap => CompressionMode::CompressNone,
WhiteSpace::PreLine => CompressionMode::CompressWhitespace,
compression = match in_fragment.white_space_collapse() {
WhiteSpaceCollapse::Collapse => CompressionMode::CompressWhitespaceNewline,
WhiteSpaceCollapse::Preserve => CompressionMode::CompressNone,
WhiteSpaceCollapse::PreserveBreaks => CompressionMode::CompressWhitespace,
};
text_transform = inherited_text_style.text_transform;
letter_spacing = inherited_text_style.letter_spacing;
Expand Down Expand Up @@ -568,7 +566,7 @@ fn split_first_fragment_at_newline_if_necessary(fragments: &mut LinkedList<Fragm
let string_before;
let selection_before;
{
if !first_fragment.white_space().preserve_newlines() {
if first_fragment.white_space_collapse() == WhiteSpaceCollapse::Collapse {
return;
}

Expand Down

0 comments on commit 6027fc9

Please sign in to comment.