mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Auto merge of #12370 - emilio:wrap, r=mbrubeck
Fix line-breaking with white-space: pre-wrap/pre-line; <!-- Please describe your changes on the following line: --> Not sure if this is the appropriate fix, but we'll know soon. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #12369 <!-- Either: --> - [x] There are tests for these changes OR <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> r? @mbrubeck <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/12370) <!-- Reviewable:end -->
This commit is contained in:
commit
8ded106186
6 changed files with 74 additions and 22 deletions
|
@ -1541,11 +1541,10 @@ impl Fragment {
|
||||||
/// information are both optional due to the possibility of them being whitespace.
|
/// information are both optional due to the possibility of them being whitespace.
|
||||||
pub fn calculate_split_position(&self, max_inline_size: Au, starts_line: bool)
|
pub fn calculate_split_position(&self, max_inline_size: Au, starts_line: bool)
|
||||||
-> Option<SplitResult> {
|
-> Option<SplitResult> {
|
||||||
let text_fragment_info =
|
let text_fragment_info = match self.specific {
|
||||||
if let SpecificFragmentInfo::ScannedText(ref text_fragment_info) = self.specific {
|
SpecificFragmentInfo::ScannedText(ref text_fragment_info)
|
||||||
text_fragment_info
|
=> text_fragment_info,
|
||||||
} else {
|
_ => return None,
|
||||||
return None
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut flags = SplitOptions::empty();
|
let mut flags = SplitOptions::empty();
|
||||||
|
@ -1618,11 +1617,10 @@ impl Fragment {
|
||||||
flags: SplitOptions)
|
flags: SplitOptions)
|
||||||
-> Option<SplitResult>
|
-> Option<SplitResult>
|
||||||
where I: Iterator<Item=TextRunSlice<'a>> {
|
where I: Iterator<Item=TextRunSlice<'a>> {
|
||||||
let text_fragment_info =
|
let text_fragment_info = match self.specific {
|
||||||
if let SpecificFragmentInfo::ScannedText(ref text_fragment_info) = self.specific {
|
SpecificFragmentInfo::ScannedText(ref text_fragment_info)
|
||||||
text_fragment_info
|
=> text_fragment_info,
|
||||||
} else {
|
_ => return None,
|
||||||
return None
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut remaining_inline_size = max_inline_size;
|
let mut remaining_inline_size = max_inline_size;
|
||||||
|
@ -1661,7 +1659,8 @@ impl Fragment {
|
||||||
// see if we're going to overflow the line. If so, perform a best-effort split.
|
// 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 mut remaining_range = slice.text_run_range();
|
||||||
let split_is_empty = inline_start_range.is_empty() &&
|
let split_is_empty = inline_start_range.is_empty() &&
|
||||||
!self.requires_line_break_afterward_if_wrapping_on_newlines();
|
!(self.requires_line_break_afterward_if_wrapping_on_newlines() &&
|
||||||
|
!self.white_space().allow_wrap());
|
||||||
if split_is_empty {
|
if split_is_empty {
|
||||||
// We're going to overflow the line.
|
// We're going to overflow the line.
|
||||||
overflowing = true;
|
overflowing = true;
|
||||||
|
|
|
@ -459,10 +459,12 @@ impl LineBreaker {
|
||||||
kind: FloatKind::Left,
|
kind: FloatKind::Left,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let fragment_margin_box_inline_size = first_fragment.margin_box_inline_size();
|
||||||
|
|
||||||
// Simple case: if the fragment fits, then we can stop here.
|
// Simple case: if the fragment fits, then we can stop here.
|
||||||
if line_bounds.size.inline > first_fragment.margin_box_inline_size() {
|
if line_bounds.size.inline > fragment_margin_box_inline_size {
|
||||||
debug!("LineBreaker: fragment fits on line {}", self.lines.len());
|
debug!("LineBreaker: fragment fits on line {}", self.lines.len());
|
||||||
return (line_bounds, first_fragment.margin_box_inline_size());
|
return (line_bounds, fragment_margin_box_inline_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not, but we can't split the fragment, then we'll place the line here and it will
|
// If not, but we can't split the fragment, then we'll place the line here and it will
|
||||||
|
@ -471,7 +473,7 @@ impl LineBreaker {
|
||||||
debug!("LineBreaker: line doesn't fit, but is unsplittable");
|
debug!("LineBreaker: line doesn't fit, but is unsplittable");
|
||||||
}
|
}
|
||||||
|
|
||||||
(line_bounds, first_fragment.margin_box_inline_size())
|
(line_bounds, fragment_margin_box_inline_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Performs float collision avoidance. This is called when adding a fragment is going to
|
/// Performs float collision avoidance. This is called when adding a fragment is going to
|
||||||
|
|
|
@ -340,22 +340,21 @@ impl TextRunScanner {
|
||||||
let mut byte_range = Range::new(ByteIndex(mapping.byte_range.begin() as isize),
|
let mut byte_range = Range::new(ByteIndex(mapping.byte_range.begin() as isize),
|
||||||
ByteIndex(mapping.byte_range.length() as isize));
|
ByteIndex(mapping.byte_range.length() as isize));
|
||||||
|
|
||||||
|
let mut flags = ScannedTextFlags::empty();
|
||||||
|
let text_size = old_fragment.border_box.size;
|
||||||
|
|
||||||
let requires_line_break_afterward_if_wrapping_on_newlines =
|
let requires_line_break_afterward_if_wrapping_on_newlines =
|
||||||
scanned_run.run.text[mapping.byte_range.begin()..mapping.byte_range.end()]
|
scanned_run.run.text[mapping.byte_range.begin()..mapping.byte_range.end()]
|
||||||
.ends_with('\n');
|
.ends_with('\n');
|
||||||
|
|
||||||
if requires_line_break_afterward_if_wrapping_on_newlines {
|
if requires_line_break_afterward_if_wrapping_on_newlines {
|
||||||
byte_range.extend_by(ByteIndex(-1)); // Trim the '\n'
|
byte_range.extend_by(ByteIndex(-1)); // Trim the '\n'
|
||||||
|
flags.insert(REQUIRES_LINE_BREAK_AFTERWARD_IF_WRAPPING_ON_NEWLINES);
|
||||||
}
|
}
|
||||||
|
|
||||||
let text_size = old_fragment.border_box.size;
|
|
||||||
|
|
||||||
let mut flags = ScannedTextFlags::empty();
|
|
||||||
if mapping.selected {
|
if mapping.selected {
|
||||||
flags.insert(SELECTED);
|
flags.insert(SELECTED);
|
||||||
}
|
}
|
||||||
if requires_line_break_afterward_if_wrapping_on_newlines {
|
|
||||||
flags.insert(REQUIRES_LINE_BREAK_AFTERWARD_IF_WRAPPING_ON_NEWLINES);
|
|
||||||
}
|
|
||||||
|
|
||||||
let insertion_point = if mapping.contains_insertion_point(scanned_run.insertion_point) {
|
let insertion_point = if mapping.contains_insertion_point(scanned_run.insertion_point) {
|
||||||
scanned_run.insertion_point
|
scanned_run.insertion_point
|
||||||
|
|
|
@ -6150,6 +6150,18 @@
|
||||||
"url": "/_mozilla/css/test_variable_serialization_specified.html"
|
"url": "/_mozilla/css/test_variable_serialization_specified.html"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"css/white-space-pre-line-long-line.html": [
|
||||||
|
{
|
||||||
|
"path": "css/white-space-pre-line-long-line.html",
|
||||||
|
"url": "/_mozilla/css/white-space-pre-line-long-line.html"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"css/white-space-pre-wrap-long-line.html": [
|
||||||
|
{
|
||||||
|
"path": "css/white-space-pre-wrap-long-line.html",
|
||||||
|
"url": "/_mozilla/css/white-space-pre-wrap-long-line.html"
|
||||||
|
}
|
||||||
|
],
|
||||||
"mozilla/DOMParser.html": [
|
"mozilla/DOMParser.html": [
|
||||||
{
|
{
|
||||||
"path": "mozilla/DOMParser.html",
|
"path": "mozilla/DOMParser.html",
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
<!doctype html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>White space pre-line crashtest (#12369)</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
width: 70px;
|
||||||
|
white-space: pre-line;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div>This is an actual loooooooong line
|
||||||
|
Line 2</div>
|
||||||
|
<script>
|
||||||
|
async_test(function(t) {
|
||||||
|
window.addEventListener('load', function() {
|
||||||
|
t.done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<!doctype html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>White space pre-wrap crashtest (#12369)</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
width: 70px;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div>This is an actual loooooooong line
|
||||||
|
Line 2</div>
|
||||||
|
<script>
|
||||||
|
async_test(function(t) {
|
||||||
|
window.addEventListener('load', function() {
|
||||||
|
t.done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
Loading…
Add table
Add a link
Reference in a new issue