layout: Add a basic support for list-style-position: outside (#32114)

This change adds very basic support for `list-style-position`.
Currently, the marker does not do any kind of baseline alignment with
the rest
of the list item contents and it also doesn't force the list item to be
at least as tall as the marker.

This adds a few new failures:

- Four failures because markers do not ensure that list-items have at
least the same block size as they do:
  - FAIL [expected PASS] /css/CSS2/lists/list-style-applies-to-012.xht
  - FAIL [expected PASS] /css/CSS2/lists/list-style-applies-to-014.xht
- FAIL [expected PASS]
/css/CSS2/lists/list-style-type-applies-to-012.xht
- FAIL [expected PASS]
/css/CSS2/lists/list-style-type-applies-to-014.xht
- One failure because we don't yet support the `::marker`
pseudo-selector:
- FAIL [expected PASS]
/css/css-position/position-absolute-dynamic-list-marker.html
- One failure because we don't support the list item exception for the
line height quirk:
  - FAIL [expected PASS] /quirks/line-height-in-list-item.tentative.html

Co-authored-by: Oriol Brufau <obrufau@igalia.com>

<!-- Please describe your changes on the following line: -->

Fixes #27383.

---
<!-- 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 #27383.
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because ___

<!-- Also, please make sure that "Allow edits from maintainers" checkbox
is checked, so that we can help you if you get stuck somewhere along the
way.-->

<!-- Pull requests that do not address these steps are welcome, but they
will require additional verification as part of the review process. -->

Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
Martin Robinson 2024-04-22 16:23:35 +02:00 committed by GitHub
parent 363651c7f7
commit 97376e6d96
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 167 additions and 240 deletions

View file

@ -13,10 +13,13 @@ use style::selector_parser::PseudoElement;
use style::str::char_is_whitespace;
use style::values::specified::text::TextDecorationLine;
use super::OutsideMarker;
use crate::cell::ArcRefCell;
use crate::context::LayoutContext;
use crate::dom::{BoxSlot, LayoutBox, NodeExt};
use crate::dom_traversal::{Contents, NodeAndStyleInfo, NonReplacedContents, TraversalHandler};
use crate::dom_traversal::{
Contents, NodeAndStyleInfo, NonReplacedContents, PseudoElementContentItem, TraversalHandler,
};
use crate::flow::float::FloatBox;
use crate::flow::inline::{InlineBox, InlineFormattingContext, InlineLevelBox};
use crate::flow::text_run::TextRun;
@ -98,6 +101,9 @@ enum BlockLevelCreator {
display_inside: DisplayInside,
contents: Contents,
},
OutsideMarker {
contents: Vec<PseudoElementContentItem>,
},
AnonymousTable {
table_block: ArcRefCell<BlockLevelBox>,
},
@ -195,17 +201,12 @@ impl BlockContainer {
if is_list_item {
if let Some(marker_contents) = crate::lists::make_marker(context, info) {
let _position = info.style.clone_list_style_position();
// FIXME: implement support for `outside` and remove this:
let position = ListStylePosition::Inside;
match position {
match info.style.clone_list_style_position() {
ListStylePosition::Inside => {
builder.handle_list_item_marker_inside(info, marker_contents)
},
ListStylePosition::Outside => {
// FIXME: implement layout for this case
// https://github.com/servo/servo/issues/27383
// and enable `list-style-position` and the `list-style` shorthand in Stylo.
builder.handle_list_item_marker_outside(info, marker_contents)
},
}
}
@ -452,6 +453,18 @@ where
);
}
fn handle_list_item_marker_outside(
&mut self,
info: &NodeAndStyleInfo<Node>,
contents: Vec<crate::dom_traversal::PseudoElementContentItem>,
) {
self.block_level_boxes.push(BlockLevelJob {
info: info.clone(),
box_slot: BoxSlot::dummy(),
kind: BlockLevelCreator::OutsideMarker { contents },
});
}
fn handle_inline_level_element(
&mut self,
info: &NodeAndStyleInfo<Node>,
@ -768,6 +781,29 @@ where
display_inside,
contents,
))),
BlockLevelCreator::OutsideMarker { contents } => {
let marker_style = context
.shared_context()
.stylist
.style_for_anonymous::<Node::ConcreteElement>(
&context.shared_context().guards,
&PseudoElement::ServoLegacyText, // FIMXE: use `PseudoElement::Marker` when we add it
&info.style,
);
let info = info.new_replacing_style(marker_style.clone());
let contents = NonReplacedContents::OfPseudoElement(contents);
let block_container = BlockContainer::construct(
context,
&info,
contents,
TextDecorationLine::empty(),
false, /* is_list_item */
);
ArcRefCell::new(BlockLevelBox::OutsideMarker(OutsideMarker {
style: marker_style,
block_container,
}))
},
BlockLevelCreator::AnonymousTable { table_block } => table_block,
};
self.box_slot