mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Layout: Implement CSS Grid using taffy
(#32619)
* Add layout.grid.enabled pref Signed-off-by: Nico Burns <nico@nicoburns.com> * Add taffy dependency Signed-off-by: Nico Burns <nico@nicoburns.com> * Import taffy <-> stylo conversion code from taffy_stylo crate Signed-off-by: Nico Burns <nico@nicoburns.com> * Add `Grid` variant to DisplayInside Signed-off-by: Nico Burns <nico@nicoburns.com> * Implement CSS Grid using Taffy Signed-off-by: Nico Burns <nico@nicoburns.com> Import full stylo_taffy crate Signed-off-by: Nico Burns <nico@nicoburns.com> Squashed PR feedback changes Deduplicate is_document_only_whitespace Signed-off-by: Nico Burns <nico@nicoburns.com> Import taffy::AvailableSpace Signed-off-by: Nico Burns <nico@nicoburns.com> Rename FlexContext to TaffyContainerContext Signed-off-by: Nico Burns <nico@nicoburns.com> Eliminate references to flexbox in taffy/layout module Signed-off-by: Nico Burns <nico@nicoburns.com> Use constructors for geom types Signed-off-by: Nico Burns <nico@nicoburns.com> Remove comment about abspos elements splitting contiguous text runs Signed-off-by: Nico Burns <nico@nicoburns.com> Remove reference to flexbox in taffy/construct Signed-off-by: Nico Burns <nico@nicoburns.com> Deduplicate construction of flexbox/grid containers Signed-off-by: Nico Burns <nico@nicoburns.com> Make anonymous text runs InFlow Signed-off-by: Nico Burns <nico@nicoburns.com> Remove commented code Signed-off-by: Nico Burns <nico@nicoburns.com> Update comments Signed-off-by: Nico Burns <nico@nicoburns.com> Inline/vendor the stylo/taffy interop code Signed-off-by: Nico Burns <nico@nicoburns.com> * Update test expectations Signed-off-by: Nico Burns <nico@nicoburns.com> * Fix nits from PR review Signed-off-by: Nico Burns <nico@nicoburns.com> --------- Signed-off-by: Nico Burns <nico@nicoburns.com>
This commit is contained in:
parent
339062c890
commit
6cbd89dbb0
508 changed files with 2057 additions and 10408 deletions
20
Cargo.lock
generated
20
Cargo.lock
generated
|
@ -2607,6 +2607,12 @@ dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "grid"
|
||||||
|
version = "0.15.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "36119f3a540b086b4e436bb2b588cf98a68863470e0e880f4d0842f112a3183a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gstreamer"
|
name = "gstreamer"
|
||||||
version = "0.22.8"
|
version = "0.22.8"
|
||||||
|
@ -3952,6 +3958,7 @@ dependencies = [
|
||||||
"servo_url",
|
"servo_url",
|
||||||
"style",
|
"style",
|
||||||
"style_traits",
|
"style_traits",
|
||||||
|
"taffy",
|
||||||
"tracing",
|
"tracing",
|
||||||
"unicode-bidi",
|
"unicode-bidi",
|
||||||
"unicode-script",
|
"unicode-script",
|
||||||
|
@ -7216,6 +7223,19 @@ dependencies = [
|
||||||
"version-compare",
|
"version-compare",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "taffy"
|
||||||
|
version = "0.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4d0eb2760c1b126d8147f339b2359cc2e4c673f0630986b720f261d9fb297030"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec",
|
||||||
|
"grid",
|
||||||
|
"num-traits",
|
||||||
|
"serde",
|
||||||
|
"slotmap",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tar"
|
name = "tar"
|
||||||
version = "0.4.43"
|
version = "0.4.43"
|
||||||
|
|
|
@ -127,6 +127,7 @@ style_traits = { git = "https://github.com/servo/stylo", branch = "2024-11-01",
|
||||||
surfman = { git = "https://github.com/servo/surfman", rev = "c8d6b4b65aeab739ee7651602e29c8d58ceee123", features = ["chains"] }
|
surfman = { git = "https://github.com/servo/surfman", rev = "c8d6b4b65aeab739ee7651602e29c8d58ceee123", features = ["chains"] }
|
||||||
syn = { version = "2", default-features = false, features = ["clone-impls", "derive", "parsing"] }
|
syn = { version = "2", default-features = false, features = ["clone-impls", "derive", "parsing"] }
|
||||||
synstructure = "0.13"
|
synstructure = "0.13"
|
||||||
|
taffy = { version = "0.6.1", default-features = false, features = ["std", "serde", "grid"] }
|
||||||
thin-vec = "0.2.13"
|
thin-vec = "0.2.13"
|
||||||
tikv-jemalloc-sys = "0.6.0"
|
tikv-jemalloc-sys = "0.6.0"
|
||||||
tikv-jemallocator = "0.6.0"
|
tikv-jemallocator = "0.6.0"
|
||||||
|
|
|
@ -547,6 +547,9 @@ mod gen {
|
||||||
flexbox: {
|
flexbox: {
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
},
|
},
|
||||||
|
grid: {
|
||||||
|
enabled: bool,
|
||||||
|
},
|
||||||
legacy_layout: bool,
|
legacy_layout: bool,
|
||||||
#[serde(default = "default_layout_threads")]
|
#[serde(default = "default_layout_threads")]
|
||||||
threads: i64,
|
threads: i64,
|
||||||
|
|
|
@ -49,6 +49,7 @@ servo_geometry = { path = "../geometry" }
|
||||||
servo_url = { path = "../url" }
|
servo_url = { path = "../url" }
|
||||||
style = { workspace = true }
|
style = { workspace = true }
|
||||||
style_traits = { workspace = true }
|
style_traits = { workspace = true }
|
||||||
|
taffy = { workspace = true }
|
||||||
tracing = { workspace = true, optional = true }
|
tracing = { workspace = true, optional = true }
|
||||||
unicode-bidi = { workspace = true }
|
unicode-bidi = { workspace = true }
|
||||||
unicode-script = { workspace = true }
|
unicode-script = { workspace = true }
|
||||||
|
|
|
@ -2,80 +2,80 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
//! Layout construction code that is shared between modern layout modes (Flexbox and CSS Grid)
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||||
use style::values::specified::text::TextDecorationLine;
|
use style::values::computed::TextDecorationLine;
|
||||||
|
|
||||||
use super::{FlexContainer, FlexItemBox, FlexLevelBox};
|
|
||||||
use crate::cell::ArcRefCell;
|
|
||||||
use crate::context::LayoutContext;
|
use crate::context::LayoutContext;
|
||||||
use crate::dom::{BoxSlot, LayoutBox, NodeExt};
|
use crate::dom::{BoxSlot, NodeExt};
|
||||||
use crate::dom_traversal::{Contents, NodeAndStyleInfo, NonReplacedContents, TraversalHandler};
|
use crate::dom_traversal::{Contents, NodeAndStyleInfo, TraversalHandler};
|
||||||
use crate::flow::inline::construct::InlineFormattingContextBuilder;
|
use crate::flow::inline::construct::InlineFormattingContextBuilder;
|
||||||
use crate::flow::{BlockContainer, BlockFormattingContext};
|
use crate::flow::{BlockContainer, BlockFormattingContext};
|
||||||
use crate::formatting_contexts::{
|
use crate::formatting_contexts::{
|
||||||
IndependentFormattingContext, NonReplacedFormattingContext,
|
IndependentFormattingContext, NonReplacedFormattingContext,
|
||||||
NonReplacedFormattingContextContents,
|
NonReplacedFormattingContextContents,
|
||||||
};
|
};
|
||||||
use crate::positioned::AbsolutelyPositionedBox;
|
|
||||||
use crate::style_ext::DisplayGeneratingBox;
|
use crate::style_ext::DisplayGeneratingBox;
|
||||||
|
|
||||||
impl FlexContainer {
|
|
||||||
pub fn construct<'dom>(
|
|
||||||
context: &LayoutContext,
|
|
||||||
info: &NodeAndStyleInfo<impl NodeExt<'dom>>,
|
|
||||||
contents: NonReplacedContents,
|
|
||||||
propagated_text_decoration_line: TextDecorationLine,
|
|
||||||
) -> Self {
|
|
||||||
let text_decoration_line =
|
|
||||||
propagated_text_decoration_line | info.style.clone_text_decoration_line();
|
|
||||||
let mut builder = FlexContainerBuilder {
|
|
||||||
context,
|
|
||||||
info,
|
|
||||||
text_decoration_line,
|
|
||||||
contiguous_text_runs: Vec::new(),
|
|
||||||
jobs: Vec::new(),
|
|
||||||
has_text_runs: false,
|
|
||||||
};
|
|
||||||
contents.traverse(context, info, &mut builder);
|
|
||||||
builder.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <https://drafts.csswg.org/css-flexbox/#flex-items>
|
/// <https://drafts.csswg.org/css-flexbox/#flex-items>
|
||||||
struct FlexContainerBuilder<'a, 'dom, Node> {
|
pub(crate) struct ModernContainerBuilder<'a, 'dom, Node> {
|
||||||
context: &'a LayoutContext<'a>,
|
context: &'a LayoutContext<'a>,
|
||||||
info: &'a NodeAndStyleInfo<Node>,
|
info: &'a NodeAndStyleInfo<Node>,
|
||||||
text_decoration_line: TextDecorationLine,
|
text_decoration_line: TextDecorationLine,
|
||||||
contiguous_text_runs: Vec<FlexTextRun<'dom, Node>>,
|
contiguous_text_runs: Vec<ModernContainerTextRun<'dom, Node>>,
|
||||||
/// To be run in parallel with rayon in `finish`
|
/// To be run in parallel with rayon in `finish`
|
||||||
jobs: Vec<FlexLevelJob<'dom, Node>>,
|
jobs: Vec<ModernContainerJob<'dom, Node>>,
|
||||||
has_text_runs: bool,
|
has_text_runs: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum FlexLevelJob<'dom, Node> {
|
enum ModernContainerJob<'dom, Node> {
|
||||||
/// Or pseudo-element
|
ElementOrPseudoElement {
|
||||||
Element {
|
|
||||||
info: NodeAndStyleInfo<Node>,
|
info: NodeAndStyleInfo<Node>,
|
||||||
display: DisplayGeneratingBox,
|
display: DisplayGeneratingBox,
|
||||||
contents: Contents,
|
contents: Contents,
|
||||||
box_slot: BoxSlot<'dom>,
|
box_slot: BoxSlot<'dom>,
|
||||||
},
|
},
|
||||||
TextRuns(Vec<FlexTextRun<'dom, Node>>),
|
TextRuns(Vec<ModernContainerTextRun<'dom, Node>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FlexTextRun<'dom, Node> {
|
struct ModernContainerTextRun<'dom, Node> {
|
||||||
info: NodeAndStyleInfo<Node>,
|
info: NodeAndStyleInfo<Node>,
|
||||||
text: Cow<'dom, str>,
|
text: Cow<'dom, str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'dom, Node: 'dom> TraversalHandler<'dom, Node> for FlexContainerBuilder<'a, 'dom, Node>
|
impl<Node> ModernContainerTextRun<'_, Node> {
|
||||||
|
/// <https://drafts.csswg.org/css-text/#white-space>
|
||||||
|
fn is_only_document_white_space(&self) -> bool {
|
||||||
|
// FIXME: is this the right definition? See
|
||||||
|
// https://github.com/w3c/csswg-drafts/issues/5146
|
||||||
|
// https://github.com/w3c/csswg-drafts/issues/5147
|
||||||
|
self.text
|
||||||
|
.bytes()
|
||||||
|
.all(|byte| matches!(byte, b' ' | b'\n' | b'\t'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) enum ModernItemKind {
|
||||||
|
InFlow,
|
||||||
|
OutOfFlow,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) struct ModernItem<'dom> {
|
||||||
|
pub kind: ModernItemKind,
|
||||||
|
pub order: i32,
|
||||||
|
pub box_slot: Option<BoxSlot<'dom>>,
|
||||||
|
pub formatting_context: IndependentFormattingContext,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'dom, Node: 'dom> TraversalHandler<'dom, Node> for ModernContainerBuilder<'a, 'dom, Node>
|
||||||
where
|
where
|
||||||
Node: NodeExt<'dom>,
|
Node: NodeExt<'dom>,
|
||||||
{
|
{
|
||||||
fn handle_text(&mut self, info: &NodeAndStyleInfo<Node>, text: Cow<'dom, str>) {
|
fn handle_text(&mut self, info: &NodeAndStyleInfo<Node>, text: Cow<'dom, str>) {
|
||||||
self.contiguous_text_runs.push(FlexTextRun {
|
self.contiguous_text_runs.push(ModernContainerTextRun {
|
||||||
info: info.clone(),
|
info: info.clone(),
|
||||||
text,
|
text,
|
||||||
})
|
})
|
||||||
|
@ -89,12 +89,9 @@ where
|
||||||
contents: Contents,
|
contents: Contents,
|
||||||
box_slot: BoxSlot<'dom>,
|
box_slot: BoxSlot<'dom>,
|
||||||
) {
|
) {
|
||||||
// FIXME: are text runs considered "contiguous" if they are only separated
|
|
||||||
// by an out-of-flow abspos element?
|
|
||||||
// (That is, are they wrapped in the same anonymous flex item, or each its own?)
|
|
||||||
self.wrap_any_text_in_anonymous_block_container();
|
self.wrap_any_text_in_anonymous_block_container();
|
||||||
|
|
||||||
self.jobs.push(FlexLevelJob::Element {
|
self.jobs.push(ModernContainerJob::ElementOrPseudoElement {
|
||||||
info: info.clone(),
|
info: info.clone(),
|
||||||
display,
|
display,
|
||||||
contents,
|
contents,
|
||||||
|
@ -103,31 +100,39 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://drafts.csswg.org/css-text/#white-space>
|
impl<'a, 'dom, Node: 'dom> ModernContainerBuilder<'a, 'dom, Node>
|
||||||
fn is_only_document_white_space<Node>(run: &FlexTextRun<'_, Node>) -> bool {
|
|
||||||
// FIXME: is this the right definition? See
|
|
||||||
// https://github.com/w3c/csswg-drafts/issues/5146
|
|
||||||
// https://github.com/w3c/csswg-drafts/issues/5147
|
|
||||||
run.text
|
|
||||||
.bytes()
|
|
||||||
.all(|byte| matches!(byte, b' ' | b'\n' | b'\t'))
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'dom, Node: 'dom> FlexContainerBuilder<'a, 'dom, Node>
|
|
||||||
where
|
where
|
||||||
Node: NodeExt<'dom>,
|
Node: NodeExt<'dom>,
|
||||||
{
|
{
|
||||||
|
pub fn new(
|
||||||
|
context: &'a LayoutContext<'a>,
|
||||||
|
info: &'a NodeAndStyleInfo<Node>,
|
||||||
|
text_decoration_line: TextDecorationLine,
|
||||||
|
) -> Self {
|
||||||
|
ModernContainerBuilder {
|
||||||
|
context,
|
||||||
|
info,
|
||||||
|
text_decoration_line,
|
||||||
|
contiguous_text_runs: Vec::new(),
|
||||||
|
jobs: Vec::new(),
|
||||||
|
has_text_runs: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn wrap_any_text_in_anonymous_block_container(&mut self) {
|
fn wrap_any_text_in_anonymous_block_container(&mut self) {
|
||||||
let runs = std::mem::take(&mut self.contiguous_text_runs);
|
let runs = std::mem::take(&mut self.contiguous_text_runs);
|
||||||
if runs.iter().all(is_only_document_white_space) {
|
if runs
|
||||||
|
.iter()
|
||||||
|
.all(ModernContainerTextRun::is_only_document_white_space)
|
||||||
|
{
|
||||||
// There is no text run, or they all only contain document white space characters
|
// There is no text run, or they all only contain document white space characters
|
||||||
} else {
|
} else {
|
||||||
self.jobs.push(FlexLevelJob::TextRuns(runs));
|
self.jobs.push(ModernContainerJob::TextRuns(runs));
|
||||||
self.has_text_runs = true;
|
self.has_text_runs = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finish(mut self) -> FlexContainer {
|
pub(crate) fn finish(mut self) -> Vec<ModernItem<'dom>> {
|
||||||
self.wrap_any_text_in_anonymous_block_container();
|
self.wrap_any_text_in_anonymous_block_container();
|
||||||
|
|
||||||
let anonymous_style = if self.has_text_runs {
|
let anonymous_style = if self.has_text_runs {
|
||||||
|
@ -145,10 +150,10 @@ where
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut children = std::mem::take(&mut self.jobs)
|
let mut children: Vec<ModernItem> = std::mem::take(&mut self.jobs)
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.filter_map(|job| match job {
|
.filter_map(|job| match job {
|
||||||
FlexLevelJob::TextRuns(runs) => {
|
ModernContainerJob::TextRuns(runs) => {
|
||||||
let mut inline_formatting_context_builder =
|
let mut inline_formatting_context_builder =
|
||||||
InlineFormattingContextBuilder::new();
|
InlineFormattingContextBuilder::new();
|
||||||
for flex_text_run in runs.into_iter() {
|
for flex_text_run in runs.into_iter() {
|
||||||
|
@ -176,62 +181,58 @@ where
|
||||||
block_formatting_context,
|
block_formatting_context,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
let formatting_context =
|
||||||
|
IndependentFormattingContext::NonReplaced(non_replaced);
|
||||||
|
|
||||||
Some(ArcRefCell::new(FlexLevelBox::FlexItem(FlexItemBox {
|
Some(ModernItem {
|
||||||
independent_formatting_context: IndependentFormattingContext::NonReplaced(
|
kind: ModernItemKind::InFlow,
|
||||||
non_replaced,
|
order: 0,
|
||||||
),
|
box_slot: None,
|
||||||
block_content_size_cache: Default::default(),
|
formatting_context,
|
||||||
})))
|
})
|
||||||
},
|
},
|
||||||
FlexLevelJob::Element {
|
ModernContainerJob::ElementOrPseudoElement {
|
||||||
info,
|
info,
|
||||||
display,
|
display,
|
||||||
contents,
|
contents,
|
||||||
box_slot,
|
box_slot,
|
||||||
} => {
|
} => {
|
||||||
let display_inside = match display {
|
let is_abspos = info.style.get_box().position.is_absolutely_positioned();
|
||||||
DisplayGeneratingBox::OutsideInside { inside, .. } => inside,
|
let formatting_context = IndependentFormattingContext::construct(
|
||||||
DisplayGeneratingBox::LayoutInternal(_) => display.display_inside(),
|
self.context,
|
||||||
};
|
&info,
|
||||||
let box_ = if info.style.get_box().position.is_absolutely_positioned() {
|
display.display_inside(),
|
||||||
// https://drafts.csswg.org/css-flexbox/#abspos-items
|
contents,
|
||||||
ArcRefCell::new(FlexLevelBox::OutOfFlowAbsolutelyPositionedBox(
|
// Text decorations are not propagated to any out-of-flow descendants.
|
||||||
ArcRefCell::new(AbsolutelyPositionedBox::construct(
|
if is_abspos {
|
||||||
self.context,
|
TextDecorationLine::NONE
|
||||||
&info,
|
} else {
|
||||||
display_inside,
|
self.text_decoration_line
|
||||||
contents,
|
},
|
||||||
)),
|
);
|
||||||
))
|
|
||||||
|
if is_abspos {
|
||||||
|
Some(ModernItem {
|
||||||
|
kind: ModernItemKind::OutOfFlow,
|
||||||
|
order: 0,
|
||||||
|
box_slot: Some(box_slot),
|
||||||
|
formatting_context,
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
ArcRefCell::new(FlexLevelBox::FlexItem(FlexItemBox {
|
Some(ModernItem {
|
||||||
independent_formatting_context: IndependentFormattingContext::construct(
|
kind: ModernItemKind::InFlow,
|
||||||
self.context,
|
order: info.style.clone_order(),
|
||||||
&info,
|
box_slot: Some(box_slot),
|
||||||
display_inside,
|
formatting_context,
|
||||||
contents,
|
})
|
||||||
self.text_decoration_line,
|
}
|
||||||
),
|
|
||||||
block_content_size_cache: Default::default(),
|
|
||||||
}))
|
|
||||||
};
|
|
||||||
box_slot.set(LayoutBox::FlexLevel(box_.clone()));
|
|
||||||
Some(box_)
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-flexbox/#order-modified-document-order
|
// https://drafts.csswg.org/css-flexbox/#order-modified-document-order
|
||||||
children.sort_by_key(|child| match &*child.borrow() {
|
children.sort_by_key(|child| child.order);
|
||||||
FlexLevelBox::FlexItem(item) => item.style().clone_order(),
|
|
||||||
|
|
||||||
// “Absolutely-positioned children of a flex container are treated
|
children
|
||||||
// as having order: 0 for the purpose of determining their painting order
|
|
||||||
// relative to flex items.”
|
|
||||||
FlexLevelBox::OutOfFlowAbsolutelyPositionedBox(_) => 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
FlexContainer::new(&self.info.style, children)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -27,6 +27,7 @@ use crate::flow::inline::InlineItem;
|
||||||
use crate::flow::BlockLevelBox;
|
use crate::flow::BlockLevelBox;
|
||||||
use crate::geom::PhysicalSize;
|
use crate::geom::PhysicalSize;
|
||||||
use crate::replaced::{CanvasInfo, CanvasSource};
|
use crate::replaced::{CanvasInfo, CanvasSource};
|
||||||
|
use crate::taffy::TaffyItemBox;
|
||||||
|
|
||||||
/// The data that is stored in each DOM node that is used by layout.
|
/// The data that is stored in each DOM node that is used by layout.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
@ -44,6 +45,7 @@ pub(super) enum LayoutBox {
|
||||||
InlineBox(ArcRefCell<InlineBox>),
|
InlineBox(ArcRefCell<InlineBox>),
|
||||||
InlineLevel(ArcRefCell<InlineItem>),
|
InlineLevel(ArcRefCell<InlineItem>),
|
||||||
FlexLevel(ArcRefCell<FlexLevelBox>),
|
FlexLevel(ArcRefCell<FlexLevelBox>),
|
||||||
|
TaffyItemBox(ArcRefCell<TaffyItemBox>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A wrapper for [`InnerDOMLayoutData`]. This is necessary to give the entire data
|
/// A wrapper for [`InnerDOMLayoutData`]. This is necessary to give the entire data
|
||||||
|
|
|
@ -13,13 +13,17 @@ use style::properties::longhands::flex_wrap::computed_value::T as FlexWrap;
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::values::computed::{AlignContent, JustifyContent};
|
use style::values::computed::{AlignContent, JustifyContent};
|
||||||
use style::values::specified::align::AlignFlags;
|
use style::values::specified::align::AlignFlags;
|
||||||
|
use style::values::specified::text::TextDecorationLine;
|
||||||
|
|
||||||
use crate::cell::ArcRefCell;
|
use crate::cell::ArcRefCell;
|
||||||
|
use crate::construct_modern::{ModernContainerBuilder, ModernItemKind};
|
||||||
|
use crate::context::LayoutContext;
|
||||||
|
use crate::dom::{LayoutBox, NodeExt};
|
||||||
|
use crate::dom_traversal::{NodeAndStyleInfo, NonReplacedContents};
|
||||||
use crate::formatting_contexts::IndependentFormattingContext;
|
use crate::formatting_contexts::IndependentFormattingContext;
|
||||||
use crate::fragment_tree::BaseFragmentInfo;
|
use crate::fragment_tree::BaseFragmentInfo;
|
||||||
use crate::positioned::AbsolutelyPositionedBox;
|
use crate::positioned::AbsolutelyPositionedBox;
|
||||||
|
|
||||||
mod construct;
|
|
||||||
mod geom;
|
mod geom;
|
||||||
mod layout;
|
mod layout;
|
||||||
|
|
||||||
|
@ -95,14 +99,45 @@ pub(crate) struct FlexContainer {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FlexContainer {
|
impl FlexContainer {
|
||||||
pub(crate) fn new(
|
pub fn construct<'dom>(
|
||||||
style: &ServoArc<ComputedValues>,
|
context: &LayoutContext,
|
||||||
children: Vec<ArcRefCell<FlexLevelBox>>,
|
info: &NodeAndStyleInfo<impl NodeExt<'dom>>,
|
||||||
|
contents: NonReplacedContents,
|
||||||
|
propagated_text_decoration_line: TextDecorationLine,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
let text_decoration_line =
|
||||||
|
propagated_text_decoration_line | info.style.clone_text_decoration_line();
|
||||||
|
|
||||||
|
let mut builder = ModernContainerBuilder::new(context, info, text_decoration_line);
|
||||||
|
contents.traverse(context, info, &mut builder);
|
||||||
|
let items = builder.finish();
|
||||||
|
|
||||||
|
let children = items
|
||||||
|
.into_iter()
|
||||||
|
.map(|item| {
|
||||||
|
let box_ = match item.kind {
|
||||||
|
ModernItemKind::InFlow => ArcRefCell::new(FlexLevelBox::FlexItem(
|
||||||
|
FlexItemBox::new(item.formatting_context),
|
||||||
|
)),
|
||||||
|
ModernItemKind::OutOfFlow => {
|
||||||
|
let abs_pos_box =
|
||||||
|
ArcRefCell::new(AbsolutelyPositionedBox::new(item.formatting_context));
|
||||||
|
ArcRefCell::new(FlexLevelBox::OutOfFlowAbsolutelyPositionedBox(abs_pos_box))
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(box_slot) = item.box_slot {
|
||||||
|
box_slot.set(LayoutBox::FlexLevel(box_.clone()));
|
||||||
|
}
|
||||||
|
|
||||||
|
box_
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
children,
|
children,
|
||||||
style: style.clone(),
|
style: info.style.clone(),
|
||||||
config: FlexContainerConfig::new(style),
|
config: FlexContainerConfig::new(&info.style),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,6 +162,13 @@ impl std::fmt::Debug for FlexItemBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FlexItemBox {
|
impl FlexItemBox {
|
||||||
|
fn new(independent_formatting_context: IndependentFormattingContext) -> Self {
|
||||||
|
Self {
|
||||||
|
independent_formatting_context,
|
||||||
|
block_content_size_cache: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn style(&self) -> &ServoArc<ComputedValues> {
|
fn style(&self) -> &ServoArc<ComputedValues> {
|
||||||
self.independent_formatting_context.style()
|
self.independent_formatting_context.style()
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ use crate::geom::{LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSize};
|
||||||
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
||||||
use crate::replaced::ReplacedContent;
|
use crate::replaced::ReplacedContent;
|
||||||
use crate::style_ext::{ComputedValuesExt, Display, DisplayGeneratingBox, DisplayInside};
|
use crate::style_ext::{ComputedValuesExt, Display, DisplayGeneratingBox, DisplayInside};
|
||||||
|
use crate::taffy::{TaffyItemBox, TaffyItemBoxInner};
|
||||||
use crate::DefiniteContainingBlock;
|
use crate::DefiniteContainingBlock;
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
|
@ -127,6 +128,7 @@ impl BoxTree {
|
||||||
AbsolutelyPositionedBlockLevelBox(ArcRefCell<BlockLevelBox>),
|
AbsolutelyPositionedBlockLevelBox(ArcRefCell<BlockLevelBox>),
|
||||||
AbsolutelyPositionedInlineLevelBox(ArcRefCell<InlineItem>, usize),
|
AbsolutelyPositionedInlineLevelBox(ArcRefCell<InlineItem>, usize),
|
||||||
AbsolutelyPositionedFlexLevelBox(ArcRefCell<FlexLevelBox>),
|
AbsolutelyPositionedFlexLevelBox(ArcRefCell<FlexLevelBox>),
|
||||||
|
AbsolutelyPositionedTaffyLevelBox(ArcRefCell<TaffyItemBox>),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_point<'dom, Node>(
|
fn update_point<'dom, Node>(
|
||||||
|
@ -203,6 +205,17 @@ impl BoxTree {
|
||||||
},
|
},
|
||||||
_ => return None,
|
_ => return None,
|
||||||
},
|
},
|
||||||
|
LayoutBox::TaffyItemBox(taffy_level_box) => match &taffy_level_box
|
||||||
|
.borrow()
|
||||||
|
.taffy_level_box
|
||||||
|
{
|
||||||
|
TaffyItemBoxInner::OutOfFlowAbsolutelyPositionedBox(_)
|
||||||
|
if box_style.position.is_absolutely_positioned() =>
|
||||||
|
{
|
||||||
|
UpdatePoint::AbsolutelyPositionedTaffyLevelBox(taffy_level_box.clone())
|
||||||
|
},
|
||||||
|
_ => return None,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
Some((primary_style.clone(), display_inside, update_point))
|
Some((primary_style.clone(), display_inside, update_point))
|
||||||
}
|
}
|
||||||
|
@ -238,6 +251,12 @@ impl BoxTree {
|
||||||
out_of_flow_absolutely_positioned_box,
|
out_of_flow_absolutely_positioned_box,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
UpdatePoint::AbsolutelyPositionedTaffyLevelBox(taffy_level_box) => {
|
||||||
|
taffy_level_box.borrow_mut().taffy_level_box =
|
||||||
|
TaffyItemBoxInner::OutOfFlowAbsolutelyPositionedBox(
|
||||||
|
out_of_flow_absolutely_positioned_box,
|
||||||
|
);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ use crate::replaced::ReplacedContent;
|
||||||
use crate::sizing::{self, InlineContentSizesResult};
|
use crate::sizing::{self, InlineContentSizesResult};
|
||||||
use crate::style_ext::{AspectRatio, DisplayInside};
|
use crate::style_ext::{AspectRatio, DisplayInside};
|
||||||
use crate::table::Table;
|
use crate::table::Table;
|
||||||
|
use crate::taffy::TaffyContainer;
|
||||||
use crate::{
|
use crate::{
|
||||||
ConstraintSpace, ContainingBlock, IndefiniteContainingBlock, LogicalVec2, SizeConstraint,
|
ConstraintSpace, ContainingBlock, IndefiniteContainingBlock, LogicalVec2, SizeConstraint,
|
||||||
};
|
};
|
||||||
|
@ -58,6 +59,7 @@ pub(crate) struct ReplacedFormattingContext {
|
||||||
pub(crate) enum NonReplacedFormattingContextContents {
|
pub(crate) enum NonReplacedFormattingContextContents {
|
||||||
Flow(BlockFormattingContext),
|
Flow(BlockFormattingContext),
|
||||||
Flex(FlexContainer),
|
Flex(FlexContainer),
|
||||||
|
Grid(TaffyContainer),
|
||||||
Table(Table),
|
Table(Table),
|
||||||
// Other layout modes go here
|
// Other layout modes go here
|
||||||
}
|
}
|
||||||
|
@ -129,6 +131,14 @@ impl IndependentFormattingContext {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
DisplayInside::Grid => {
|
||||||
|
NonReplacedFormattingContextContents::Grid(TaffyContainer::construct(
|
||||||
|
context,
|
||||||
|
node_and_style_info,
|
||||||
|
non_replaced_contents,
|
||||||
|
propagated_text_decoration_line,
|
||||||
|
))
|
||||||
|
},
|
||||||
DisplayInside::Flex => {
|
DisplayInside::Flex => {
|
||||||
NonReplacedFormattingContextContents::Flex(FlexContainer::construct(
|
NonReplacedFormattingContextContents::Flex(FlexContainer::construct(
|
||||||
context,
|
context,
|
||||||
|
@ -268,6 +278,12 @@ impl NonReplacedFormattingContext {
|
||||||
containing_block_for_children,
|
containing_block_for_children,
|
||||||
containing_block,
|
containing_block,
|
||||||
),
|
),
|
||||||
|
NonReplacedFormattingContextContents::Grid(fc) => fc.layout(
|
||||||
|
layout_context,
|
||||||
|
positioning_context,
|
||||||
|
containing_block_for_children,
|
||||||
|
containing_block,
|
||||||
|
),
|
||||||
NonReplacedFormattingContextContents::Table(table) => table.layout(
|
NonReplacedFormattingContextContents::Table(table) => table.layout(
|
||||||
layout_context,
|
layout_context,
|
||||||
positioning_context,
|
positioning_context,
|
||||||
|
@ -331,6 +347,7 @@ impl NonReplacedFormattingContextContents {
|
||||||
.contents
|
.contents
|
||||||
.inline_content_sizes(layout_context, constraint_space),
|
.inline_content_sizes(layout_context, constraint_space),
|
||||||
Self::Flex(inner) => inner.inline_content_sizes(layout_context, constraint_space),
|
Self::Flex(inner) => inner.inline_content_sizes(layout_context, constraint_space),
|
||||||
|
Self::Grid(inner) => inner.inline_content_sizes(layout_context, constraint_space),
|
||||||
Self::Table(table) => table.inline_content_sizes(layout_context, constraint_space),
|
Self::Table(table) => table.inline_content_sizes(layout_context, constraint_space),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,10 @@ pub mod flow;
|
||||||
mod formatting_contexts;
|
mod formatting_contexts;
|
||||||
mod fragment_tree;
|
mod fragment_tree;
|
||||||
pub mod geom;
|
pub mod geom;
|
||||||
|
mod taffy;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod layout_debug;
|
pub mod layout_debug;
|
||||||
|
mod construct_modern;
|
||||||
mod lists;
|
mod lists;
|
||||||
mod positioned;
|
mod positioned;
|
||||||
pub mod query;
|
pub mod query;
|
||||||
|
|
|
@ -56,6 +56,10 @@ pub(crate) struct HoistedAbsolutelyPositionedBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbsolutelyPositionedBox {
|
impl AbsolutelyPositionedBox {
|
||||||
|
pub fn new(context: IndependentFormattingContext) -> Self {
|
||||||
|
Self { context }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn construct<'dom>(
|
pub fn construct<'dom>(
|
||||||
context: &LayoutContext,
|
context: &LayoutContext,
|
||||||
node_info: &NodeAndStyleInfo<impl NodeExt<'dom>>,
|
node_info: &NodeAndStyleInfo<impl NodeExt<'dom>>,
|
||||||
|
|
|
@ -91,6 +91,7 @@ pub(crate) enum DisplayInside {
|
||||||
Flow { is_list_item: bool },
|
Flow { is_list_item: bool },
|
||||||
FlowRoot { is_list_item: bool },
|
FlowRoot { is_list_item: bool },
|
||||||
Flex,
|
Flex,
|
||||||
|
Grid,
|
||||||
Table,
|
Table,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1064,7 +1065,7 @@ impl From<stylo::Display> for Display {
|
||||||
is_list_item: packed.is_list_item(),
|
is_list_item: packed.is_list_item(),
|
||||||
},
|
},
|
||||||
stylo::DisplayInside::Flex => DisplayInside::Flex,
|
stylo::DisplayInside::Flex => DisplayInside::Flex,
|
||||||
stylo::DisplayInside::Grid => todo!("Grid support is not yet implemented."),
|
stylo::DisplayInside::Grid => DisplayInside::Grid,
|
||||||
|
|
||||||
// These should not be values of DisplayInside, but oh well
|
// These should not be values of DisplayInside, but oh well
|
||||||
stylo::DisplayInside::None => return Display::None,
|
stylo::DisplayInside::None => return Display::None,
|
||||||
|
|
604
components/layout_2020/taffy/layout.rs
Normal file
604
components/layout_2020/taffy/layout.rs
Normal file
|
@ -0,0 +1,604 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use app_units::Au;
|
||||||
|
use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
|
||||||
|
use style::properties::ComputedValues;
|
||||||
|
use style::values::generics::length::{GenericLengthPercentageOrAuto, LengthPercentageOrAuto};
|
||||||
|
use style::values::specified::align::AlignFlags;
|
||||||
|
use style::values::specified::box_::DisplayInside;
|
||||||
|
use style::Zero;
|
||||||
|
use taffy::style_helpers::{TaffyMaxContent, TaffyMinContent};
|
||||||
|
use taffy::{AvailableSpace, MaybeMath};
|
||||||
|
|
||||||
|
use super::{TaffyContainer, TaffyItemBox, TaffyItemBoxInner, TaffyStyloStyle};
|
||||||
|
use crate::cell::ArcRefCell;
|
||||||
|
use crate::context::LayoutContext;
|
||||||
|
use crate::formatting_contexts::{Baselines, IndependentFormattingContext, IndependentLayout};
|
||||||
|
use crate::fragment_tree::{BoxFragment, CollapsedBlockMargins, Fragment};
|
||||||
|
use crate::geom::{
|
||||||
|
LogicalSides, LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSides, PhysicalSize, Size,
|
||||||
|
SizeConstraint,
|
||||||
|
};
|
||||||
|
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext, PositioningContextLength};
|
||||||
|
use crate::sizing::{ContentSizes, InlineContentSizesResult};
|
||||||
|
use crate::style_ext::ComputedValuesExt;
|
||||||
|
use crate::{ConstraintSpace, ContainingBlock};
|
||||||
|
|
||||||
|
const DUMMY_NODE_ID: taffy::NodeId = taffy::NodeId::new(u64::MAX);
|
||||||
|
|
||||||
|
fn resolve_content_size(constraint: AvailableSpace, content_sizes: ContentSizes) -> f32 {
|
||||||
|
match constraint {
|
||||||
|
AvailableSpace::Definite(limit) => {
|
||||||
|
let min = content_sizes.min_content.to_f32_px();
|
||||||
|
let max = content_sizes.max_content.to_f32_px();
|
||||||
|
limit.min(max).max(min)
|
||||||
|
},
|
||||||
|
AvailableSpace::MinContent => content_sizes.min_content.to_f32_px(),
|
||||||
|
AvailableSpace::MaxContent => content_sizes.max_content.to_f32_px(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn with_independant_formatting_context<T>(
|
||||||
|
item: &mut TaffyItemBoxInner,
|
||||||
|
cb: impl FnOnce(&mut IndependentFormattingContext) -> T,
|
||||||
|
) -> T {
|
||||||
|
match item {
|
||||||
|
TaffyItemBoxInner::InFlowBox(ref mut context) => cb(context),
|
||||||
|
TaffyItemBoxInner::OutOfFlowAbsolutelyPositionedBox(ref abspos_box) => {
|
||||||
|
let mut abspos_box = AtomicRefCell::borrow_mut(abspos_box);
|
||||||
|
cb(&mut abspos_box.context)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Layout parameters and intermediate results about a taffy container,
|
||||||
|
/// grouped to avoid passing around many parameters
|
||||||
|
struct TaffyContainerContext<'a> {
|
||||||
|
source_child_nodes: &'a [ArcRefCell<TaffyItemBox>],
|
||||||
|
layout_context: &'a LayoutContext<'a>,
|
||||||
|
positioning_context: &'a mut PositioningContext,
|
||||||
|
content_box_size_override: &'a ContainingBlock<'a>,
|
||||||
|
style: &'a ComputedValues,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ChildIter(std::ops::Range<usize>);
|
||||||
|
impl Iterator for ChildIter {
|
||||||
|
type Item = taffy::NodeId;
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.0.next().map(taffy::NodeId::from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl taffy::TraversePartialTree for TaffyContainerContext<'_> {
|
||||||
|
type ChildIter<'a> = ChildIter where Self: 'a;
|
||||||
|
|
||||||
|
fn child_ids(&self, _node_id: taffy::NodeId) -> Self::ChildIter<'_> {
|
||||||
|
ChildIter(0..self.source_child_nodes.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn child_count(&self, _node_id: taffy::NodeId) -> usize {
|
||||||
|
self.source_child_nodes.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_child_id(&self, _node_id: taffy::NodeId, index: usize) -> taffy::NodeId {
|
||||||
|
taffy::NodeId::from(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl taffy::LayoutPartialTree for TaffyContainerContext<'_> {
|
||||||
|
type CoreContainerStyle<'a> = TaffyStyloStyle<&'a ComputedValues> where Self: 'a;
|
||||||
|
type CacheMut<'b> = AtomicRefMut<'b, taffy::Cache> where Self: 'b;
|
||||||
|
|
||||||
|
fn get_core_container_style(&self, _node_id: taffy::NodeId) -> Self::CoreContainerStyle<'_> {
|
||||||
|
TaffyStyloStyle(self.style)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_unrounded_layout(&mut self, node_id: taffy::NodeId, layout: &taffy::Layout) {
|
||||||
|
let id = usize::from(node_id);
|
||||||
|
(*self.source_child_nodes[id]).borrow_mut().taffy_layout = *layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_cache_mut(&mut self, node_id: taffy::NodeId) -> AtomicRefMut<'_, taffy::Cache> {
|
||||||
|
let id = usize::from(node_id);
|
||||||
|
let mut_ref: AtomicRefMut<'_, _> = (*self.source_child_nodes[id]).borrow_mut();
|
||||||
|
AtomicRefMut::map(mut_ref, |node| &mut node.taffy_layout_cache)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compute_child_layout(
|
||||||
|
&mut self,
|
||||||
|
node_id: taffy::NodeId,
|
||||||
|
inputs: taffy::LayoutInput,
|
||||||
|
) -> taffy::LayoutOutput {
|
||||||
|
let mut child = (*self.source_child_nodes[usize::from(node_id)]).borrow_mut();
|
||||||
|
let child = &mut *child;
|
||||||
|
|
||||||
|
fn option_f32_to_lpa(input: Option<f32>) -> LengthPercentageOrAuto<Au> {
|
||||||
|
match input {
|
||||||
|
None => LengthPercentageOrAuto::Auto,
|
||||||
|
Some(length) => LengthPercentageOrAuto::LengthPercentage(Au::from_f32_px(length)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn option_f32_to_size(input: Option<f32>) -> Size<Au> {
|
||||||
|
match input {
|
||||||
|
None => Size::Initial,
|
||||||
|
Some(length) => Size::Numeric(Au::from_f32_px(length)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
with_independant_formatting_context(
|
||||||
|
&mut child.taffy_level_box,
|
||||||
|
|independent_context| -> taffy::LayoutOutput {
|
||||||
|
match independent_context {
|
||||||
|
IndependentFormattingContext::Replaced(replaced) => {
|
||||||
|
// TODO: re-evaluate sizing constraint conversions in light of recent layout_2020 changes
|
||||||
|
let containing_block = &self.content_box_size_override;
|
||||||
|
|
||||||
|
// Adjust known_dimensions from border box to content box
|
||||||
|
let pbm = replaced.style.padding_border_margin(containing_block);
|
||||||
|
let pb_sum = pbm.padding_border_sums.map(|v| v.to_f32_px());
|
||||||
|
let content_box_known_dimensions = taffy::Size {
|
||||||
|
width: inputs
|
||||||
|
.known_dimensions
|
||||||
|
.width
|
||||||
|
.map(|width| width - pb_sum.inline),
|
||||||
|
height: inputs
|
||||||
|
.known_dimensions
|
||||||
|
.height
|
||||||
|
.map(|height| height - pb_sum.block),
|
||||||
|
};
|
||||||
|
|
||||||
|
let content_box_size = replaced
|
||||||
|
.contents
|
||||||
|
.used_size_as_if_inline_element_from_content_box_sizes(
|
||||||
|
containing_block,
|
||||||
|
&replaced.style,
|
||||||
|
LogicalVec2 {
|
||||||
|
inline: option_f32_to_size(content_box_known_dimensions.width),
|
||||||
|
block: option_f32_to_size(content_box_known_dimensions.height),
|
||||||
|
},
|
||||||
|
LogicalVec2 {
|
||||||
|
inline: Size::Numeric(Au::zero()),
|
||||||
|
block: Size::Numeric(Au::zero()),
|
||||||
|
},
|
||||||
|
LogicalVec2 {
|
||||||
|
inline: Size::Initial,
|
||||||
|
block: Size::Initial,
|
||||||
|
},
|
||||||
|
pbm.padding_border_sums,
|
||||||
|
)
|
||||||
|
.to_physical_size(self.style.writing_mode);
|
||||||
|
|
||||||
|
child.child_fragments = replaced.contents.make_fragments(
|
||||||
|
&replaced.style,
|
||||||
|
containing_block,
|
||||||
|
content_box_size,
|
||||||
|
);
|
||||||
|
|
||||||
|
let computed_size = taffy::Size {
|
||||||
|
width: inputs.known_dimensions.width.unwrap_or_else(|| {
|
||||||
|
content_box_size.width.to_f32_px() +
|
||||||
|
pbm.padding_border_sums.inline.to_f32_px()
|
||||||
|
}),
|
||||||
|
height: inputs.known_dimensions.height.unwrap_or_else(|| {
|
||||||
|
content_box_size.height.to_f32_px() +
|
||||||
|
pbm.padding_border_sums.block.to_f32_px()
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
let size = inputs.known_dimensions.unwrap_or(computed_size);
|
||||||
|
taffy::LayoutOutput {
|
||||||
|
size,
|
||||||
|
..taffy::LayoutOutput::DEFAULT
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
IndependentFormattingContext::NonReplaced(non_replaced) => {
|
||||||
|
// TODO: re-evaluate sizing constraint conversions in light of recent layout_2020 changes
|
||||||
|
let containing_block = &self.content_box_size_override;
|
||||||
|
|
||||||
|
// Adjust known_dimensions from border box to content box
|
||||||
|
let pbm = non_replaced.style.padding_border_margin(containing_block);
|
||||||
|
let margin_sum = pbm.margin.auto_is(Au::zero).sum();
|
||||||
|
let content_box_inset =
|
||||||
|
(pbm.padding_border_sums + margin_sum).map(|v| v.to_f32_px());
|
||||||
|
let content_box_known_dimensions =
|
||||||
|
taffy::Size {
|
||||||
|
width: inputs.known_dimensions.width.map(|width| {
|
||||||
|
width - pbm.padding_border_sums.inline.to_f32_px()
|
||||||
|
}),
|
||||||
|
height: inputs.known_dimensions.height.map(|height| {
|
||||||
|
height - pbm.padding_border_sums.block.to_f32_px()
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Compute inline size
|
||||||
|
let inline_size = content_box_known_dimensions.width.unwrap_or_else(|| {
|
||||||
|
let constraint_space = ConstraintSpace {
|
||||||
|
// TODO: pass min- and max- size
|
||||||
|
block_size: SizeConstraint::new(
|
||||||
|
inputs.parent_size.height.map(Au::from_f32_px),
|
||||||
|
Au::zero(),
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
writing_mode: self.style.writing_mode,
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = non_replaced
|
||||||
|
.inline_content_sizes(self.layout_context, &constraint_space);
|
||||||
|
let adjusted_available_space = inputs
|
||||||
|
.available_space
|
||||||
|
.width
|
||||||
|
.map_definite_value(|width| width - content_box_inset.inline);
|
||||||
|
|
||||||
|
resolve_content_size(adjusted_available_space, result.sizes)
|
||||||
|
});
|
||||||
|
|
||||||
|
let maybe_block_size =
|
||||||
|
option_f32_to_lpa(content_box_known_dimensions.height);
|
||||||
|
let content_box_size_override = ContainingBlock {
|
||||||
|
inline_size: Au::from_f32_px(inline_size),
|
||||||
|
block_size: maybe_block_size,
|
||||||
|
style: &non_replaced.style,
|
||||||
|
};
|
||||||
|
|
||||||
|
let layout = {
|
||||||
|
let mut child_positioning_context = PositioningContext::new_for_subtree(
|
||||||
|
self.positioning_context
|
||||||
|
.collects_for_nearest_positioned_ancestor(),
|
||||||
|
);
|
||||||
|
let layout = non_replaced.layout(
|
||||||
|
self.layout_context,
|
||||||
|
&mut child_positioning_context,
|
||||||
|
&content_box_size_override,
|
||||||
|
containing_block,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Store layout data on child for later access
|
||||||
|
child.positioning_context = child_positioning_context;
|
||||||
|
|
||||||
|
layout
|
||||||
|
};
|
||||||
|
|
||||||
|
child.child_fragments = layout.fragments;
|
||||||
|
|
||||||
|
let block_size = layout.content_block_size.to_f32_px();
|
||||||
|
|
||||||
|
let computed_size = taffy::Size {
|
||||||
|
width: inline_size + pbm.padding_border_sums.inline.to_f32_px(),
|
||||||
|
height: block_size + pbm.padding_border_sums.block.to_f32_px(),
|
||||||
|
};
|
||||||
|
let size = inputs.known_dimensions.unwrap_or(computed_size);
|
||||||
|
|
||||||
|
taffy::LayoutOutput {
|
||||||
|
size,
|
||||||
|
first_baselines: taffy::Point {
|
||||||
|
x: None,
|
||||||
|
y: layout.baselines.first.map(|au| au.to_f32_px()),
|
||||||
|
},
|
||||||
|
..taffy::LayoutOutput::DEFAULT
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl taffy::LayoutGridContainer for TaffyContainerContext<'_> {
|
||||||
|
type GridContainerStyle<'a> = TaffyStyloStyle<&'a ComputedValues>
|
||||||
|
where
|
||||||
|
Self: 'a;
|
||||||
|
|
||||||
|
type GridItemStyle<'a> = TaffyStyloStyle<AtomicRef<'a, ComputedValues>>
|
||||||
|
where
|
||||||
|
Self: 'a;
|
||||||
|
|
||||||
|
fn get_grid_container_style(
|
||||||
|
&self,
|
||||||
|
_node_id: taffy::prelude::NodeId,
|
||||||
|
) -> Self::GridContainerStyle<'_> {
|
||||||
|
TaffyStyloStyle(self.style)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_grid_child_style(
|
||||||
|
&self,
|
||||||
|
child_node_id: taffy::prelude::NodeId,
|
||||||
|
) -> Self::GridItemStyle<'_> {
|
||||||
|
let id = usize::from(child_node_id);
|
||||||
|
let child = (*self.source_child_nodes[id]).borrow();
|
||||||
|
TaffyStyloStyle(AtomicRef::map(child, |c| &*c.style))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TaffyContainer {
|
||||||
|
pub fn inline_content_sizes(
|
||||||
|
&self,
|
||||||
|
layout_context: &LayoutContext,
|
||||||
|
_constraint_space: &ConstraintSpace,
|
||||||
|
) -> InlineContentSizesResult {
|
||||||
|
let style = &self.style;
|
||||||
|
|
||||||
|
let max_content_inputs = taffy::LayoutInput {
|
||||||
|
run_mode: taffy::RunMode::ComputeSize,
|
||||||
|
sizing_mode: taffy::SizingMode::InherentSize,
|
||||||
|
axis: taffy::RequestedAxis::Horizontal,
|
||||||
|
vertical_margins_are_collapsible: taffy::Line::FALSE,
|
||||||
|
|
||||||
|
known_dimensions: taffy::Size::NONE,
|
||||||
|
parent_size: taffy::Size::NONE,
|
||||||
|
available_space: taffy::Size::MAX_CONTENT,
|
||||||
|
};
|
||||||
|
|
||||||
|
let min_content_inputs = taffy::LayoutInput {
|
||||||
|
available_space: taffy::Size::MIN_CONTENT,
|
||||||
|
..max_content_inputs
|
||||||
|
};
|
||||||
|
|
||||||
|
let containing_block = &ContainingBlock {
|
||||||
|
inline_size: Au::zero(),
|
||||||
|
block_size: GenericLengthPercentageOrAuto::Auto,
|
||||||
|
style,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut grid_context = TaffyContainerContext {
|
||||||
|
layout_context,
|
||||||
|
positioning_context:
|
||||||
|
&mut PositioningContext::new_for_containing_block_for_all_descendants(),
|
||||||
|
content_box_size_override: containing_block,
|
||||||
|
style,
|
||||||
|
source_child_nodes: &self.children,
|
||||||
|
};
|
||||||
|
|
||||||
|
let (max_content_output, min_content_output) = match style.clone_display().inside() {
|
||||||
|
DisplayInside::Grid => {
|
||||||
|
let max_content_output = taffy::compute_grid_layout(
|
||||||
|
&mut grid_context,
|
||||||
|
DUMMY_NODE_ID,
|
||||||
|
max_content_inputs,
|
||||||
|
);
|
||||||
|
let min_content_output = taffy::compute_grid_layout(
|
||||||
|
&mut grid_context,
|
||||||
|
DUMMY_NODE_ID,
|
||||||
|
min_content_inputs,
|
||||||
|
);
|
||||||
|
(max_content_output, min_content_output)
|
||||||
|
},
|
||||||
|
_ => panic!("Servo is only configured to use Taffy for CSS Grid layout"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let pb_sums = style
|
||||||
|
.padding_border_margin(containing_block)
|
||||||
|
.padding_border_sums;
|
||||||
|
|
||||||
|
InlineContentSizesResult {
|
||||||
|
sizes: ContentSizes {
|
||||||
|
max_content: Au::from_f32_px(max_content_output.size.width) - pb_sums.inline,
|
||||||
|
min_content: Au::from_f32_px(min_content_output.size.width) - pb_sums.inline,
|
||||||
|
},
|
||||||
|
|
||||||
|
// TODO: determine this accurately
|
||||||
|
//
|
||||||
|
// "true" is a safe default as it will prevent Servo from performing optimizations based
|
||||||
|
// on the assumption that the node's size does not depend on block constraints.
|
||||||
|
depends_on_block_constraints: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <https://drafts.csswg.org/css-grid/#layout-algorithm>
|
||||||
|
pub(crate) fn layout(
|
||||||
|
&self,
|
||||||
|
layout_context: &LayoutContext,
|
||||||
|
positioning_context: &mut PositioningContext,
|
||||||
|
content_box_size_override: &ContainingBlock,
|
||||||
|
containing_block: &ContainingBlock,
|
||||||
|
) -> IndependentLayout {
|
||||||
|
let mut container_ctx = TaffyContainerContext {
|
||||||
|
layout_context,
|
||||||
|
positioning_context,
|
||||||
|
content_box_size_override,
|
||||||
|
style: content_box_size_override.style,
|
||||||
|
source_child_nodes: &self.children,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn auto_or_to_option<T>(input: GenericLengthPercentageOrAuto<T>) -> Option<T> {
|
||||||
|
match input {
|
||||||
|
LengthPercentageOrAuto::LengthPercentage(val) => Some(val),
|
||||||
|
LengthPercentageOrAuto::Auto => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let container_style = &content_box_size_override.style;
|
||||||
|
let align_items = container_style.clone_align_items();
|
||||||
|
let justify_items = container_style.clone_justify_items();
|
||||||
|
let pbm = container_style.padding_border_margin(containing_block);
|
||||||
|
|
||||||
|
let known_dimensions = taffy::Size {
|
||||||
|
width: Some(
|
||||||
|
(content_box_size_override.inline_size + pbm.padding_border_sums.inline)
|
||||||
|
.to_f32_px(),
|
||||||
|
),
|
||||||
|
height: auto_or_to_option(content_box_size_override.block_size)
|
||||||
|
.map(Au::to_f32_px)
|
||||||
|
.maybe_add(pbm.padding_border_sums.block.to_f32_px()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let taffy_containing_block = taffy::Size {
|
||||||
|
width: Some(containing_block.inline_size.to_f32_px()),
|
||||||
|
height: auto_or_to_option(containing_block.block_size).map(Au::to_f32_px),
|
||||||
|
};
|
||||||
|
|
||||||
|
let layout_input = taffy::LayoutInput {
|
||||||
|
run_mode: taffy::RunMode::PerformLayout,
|
||||||
|
sizing_mode: taffy::SizingMode::InherentSize,
|
||||||
|
axis: taffy::RequestedAxis::Vertical,
|
||||||
|
vertical_margins_are_collapsible: taffy::Line::FALSE,
|
||||||
|
|
||||||
|
known_dimensions,
|
||||||
|
parent_size: taffy_containing_block,
|
||||||
|
available_space: taffy_containing_block.map(AvailableSpace::from),
|
||||||
|
};
|
||||||
|
|
||||||
|
let output = match container_ctx.style.clone_display().inside() {
|
||||||
|
DisplayInside::Grid => {
|
||||||
|
taffy::compute_grid_layout(&mut container_ctx, DUMMY_NODE_ID, layout_input)
|
||||||
|
},
|
||||||
|
_ => panic!("Servo is only configured to use Taffy for CSS Grid layout"),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Convert `taffy::Layout` into Servo `Fragment`s
|
||||||
|
let fragments: Vec<Fragment> = self
|
||||||
|
.children
|
||||||
|
.iter()
|
||||||
|
.map(|child| (**child).borrow_mut())
|
||||||
|
.map(|mut child| {
|
||||||
|
fn rect_to_logical_sides<T>(rect: taffy::Rect<T>) -> LogicalSides<T> {
|
||||||
|
LogicalSides {
|
||||||
|
inline_start: rect.left,
|
||||||
|
inline_end: rect.right,
|
||||||
|
block_start: rect.top,
|
||||||
|
block_end: rect.bottom,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rect_to_physical_sides<T>(rect: taffy::Rect<T>) -> PhysicalSides<T> {
|
||||||
|
PhysicalSides::new(rect.top, rect.right, rect.bottom, rect.left)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_and_pos_to_logical_rect<T: Default>(
|
||||||
|
position: taffy::Point<T>,
|
||||||
|
size: taffy::Size<T>,
|
||||||
|
) -> PhysicalRect<T> {
|
||||||
|
PhysicalRect::new(
|
||||||
|
PhysicalPoint::new(position.x, position.y),
|
||||||
|
PhysicalSize::new(size.width, size.height),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
let layout = &child.taffy_layout;
|
||||||
|
|
||||||
|
let padding = rect_to_physical_sides(layout.padding.map(Au::from_f32_px));
|
||||||
|
let border = rect_to_physical_sides(layout.border.map(Au::from_f32_px));
|
||||||
|
let margin = rect_to_physical_sides(layout.margin.map(Au::from_f32_px));
|
||||||
|
let logical_margin = rect_to_logical_sides(layout.margin.map(Au::from_f32_px));
|
||||||
|
let collapsed_margin = CollapsedBlockMargins::from_margin(&logical_margin);
|
||||||
|
|
||||||
|
// Compute content box size and position.
|
||||||
|
//
|
||||||
|
// For the x/y position we have to correct for the difference between the
|
||||||
|
// content box and the border box for both the parent and the child.
|
||||||
|
let content_size = size_and_pos_to_logical_rect(
|
||||||
|
taffy::Point {
|
||||||
|
x: Au::from_f32_px(
|
||||||
|
layout.location.x + layout.padding.left + layout.border.left,
|
||||||
|
) - pbm.padding.inline_start -
|
||||||
|
pbm.border.inline_start,
|
||||||
|
y: Au::from_f32_px(
|
||||||
|
layout.location.y + layout.padding.top + layout.border.top,
|
||||||
|
) - pbm.padding.block_start -
|
||||||
|
pbm.border.block_start,
|
||||||
|
},
|
||||||
|
taffy::Size {
|
||||||
|
width: layout.size.width -
|
||||||
|
layout.padding.left -
|
||||||
|
layout.padding.right -
|
||||||
|
layout.border.left -
|
||||||
|
layout.border.right,
|
||||||
|
height: layout.size.height -
|
||||||
|
layout.padding.top -
|
||||||
|
layout.padding.bottom -
|
||||||
|
layout.border.top -
|
||||||
|
layout.border.bottom,
|
||||||
|
}
|
||||||
|
.map(Au::from_f32_px),
|
||||||
|
);
|
||||||
|
|
||||||
|
match &mut child.taffy_level_box {
|
||||||
|
TaffyItemBoxInner::InFlowBox(independent_box) => {
|
||||||
|
let fragment = Fragment::Box(
|
||||||
|
BoxFragment::new(
|
||||||
|
independent_box.base_fragment_info(),
|
||||||
|
independent_box.style().clone(),
|
||||||
|
std::mem::take(&mut child.child_fragments),
|
||||||
|
content_size,
|
||||||
|
padding,
|
||||||
|
border,
|
||||||
|
margin,
|
||||||
|
None, /* clearance */
|
||||||
|
collapsed_margin,
|
||||||
|
)
|
||||||
|
.with_baselines(Baselines {
|
||||||
|
first: output.first_baselines.y.map(Au::from_f32_px),
|
||||||
|
last: None,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
child
|
||||||
|
.positioning_context
|
||||||
|
.adjust_static_position_of_hoisted_fragments(
|
||||||
|
&fragment,
|
||||||
|
PositioningContextLength::zero(),
|
||||||
|
);
|
||||||
|
let child_positioning_context = std::mem::replace(
|
||||||
|
&mut child.positioning_context,
|
||||||
|
PositioningContext::new_for_containing_block_for_all_descendants(),
|
||||||
|
);
|
||||||
|
container_ctx
|
||||||
|
.positioning_context
|
||||||
|
.append(child_positioning_context);
|
||||||
|
|
||||||
|
fragment
|
||||||
|
},
|
||||||
|
TaffyItemBoxInner::OutOfFlowAbsolutelyPositionedBox(abs_pos_box) => {
|
||||||
|
fn resolve_alignment(value: AlignFlags, auto: AlignFlags) -> AlignFlags {
|
||||||
|
match value {
|
||||||
|
AlignFlags::AUTO => auto,
|
||||||
|
AlignFlags::NORMAL => AlignFlags::STRETCH,
|
||||||
|
value => value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let hoisted_box = AbsolutelyPositionedBox::to_hoisted(
|
||||||
|
abs_pos_box.clone(),
|
||||||
|
PhysicalRect::from_size(PhysicalSize::new(
|
||||||
|
Au::from_f32_px(output.size.width),
|
||||||
|
Au::from_f32_px(output.size.height),
|
||||||
|
)),
|
||||||
|
LogicalVec2 {
|
||||||
|
inline: resolve_alignment(
|
||||||
|
child.style.clone_align_self().0 .0,
|
||||||
|
align_items.0,
|
||||||
|
),
|
||||||
|
block: resolve_alignment(
|
||||||
|
child.style.clone_justify_self().0 .0,
|
||||||
|
justify_items.computed.0,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
container_ctx.style.writing_mode,
|
||||||
|
);
|
||||||
|
let hoisted_fragment = hoisted_box.fragment.clone();
|
||||||
|
container_ctx.positioning_context.push(hoisted_box);
|
||||||
|
Fragment::AbsoluteOrFixedPositioned(hoisted_fragment)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
IndependentLayout {
|
||||||
|
fragments,
|
||||||
|
content_block_size: Au::from_f32_px(output.size.height) - pbm.padding_border_sums.block,
|
||||||
|
content_inline_size_for_table: Some(
|
||||||
|
Au::from_f32_px(output.size.width) - pbm.padding_border_sums.inline,
|
||||||
|
),
|
||||||
|
baselines: Baselines::default(),
|
||||||
|
|
||||||
|
// TODO: determine this accurately
|
||||||
|
//
|
||||||
|
// "true" is a safe default as it will prevent Servo from performing optimizations based
|
||||||
|
// on the assumption that the node's size does not depend on block constraints.
|
||||||
|
depends_on_block_constraints: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
122
components/layout_2020/taffy/mod.rs
Normal file
122
components/layout_2020/taffy/mod.rs
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
mod layout;
|
||||||
|
mod stylo_taffy;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
use serde::Serialize;
|
||||||
|
use servo_arc::Arc;
|
||||||
|
use style::properties::ComputedValues;
|
||||||
|
use style::values::computed::TextDecorationLine;
|
||||||
|
use stylo_taffy::TaffyStyloStyle;
|
||||||
|
|
||||||
|
use crate::cell::ArcRefCell;
|
||||||
|
use crate::construct_modern::{ModernContainerBuilder, ModernItemKind};
|
||||||
|
use crate::context::LayoutContext;
|
||||||
|
use crate::dom::{LayoutBox, NodeExt};
|
||||||
|
use crate::dom_traversal::{NodeAndStyleInfo, NonReplacedContents};
|
||||||
|
use crate::formatting_contexts::IndependentFormattingContext;
|
||||||
|
use crate::fragment_tree::Fragment;
|
||||||
|
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub(crate) struct TaffyContainer {
|
||||||
|
children: Vec<ArcRefCell<TaffyItemBox>>,
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
style: Arc<ComputedValues>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TaffyContainer {
|
||||||
|
pub fn construct<'dom>(
|
||||||
|
context: &LayoutContext,
|
||||||
|
info: &NodeAndStyleInfo<impl NodeExt<'dom>>,
|
||||||
|
contents: NonReplacedContents,
|
||||||
|
propagated_text_decoration_line: TextDecorationLine,
|
||||||
|
) -> Self {
|
||||||
|
let text_decoration_line =
|
||||||
|
propagated_text_decoration_line | info.style.clone_text_decoration_line();
|
||||||
|
let mut builder = ModernContainerBuilder::new(context, info, text_decoration_line);
|
||||||
|
contents.traverse(context, info, &mut builder);
|
||||||
|
let items = builder.finish();
|
||||||
|
|
||||||
|
let children = items
|
||||||
|
.into_iter()
|
||||||
|
.map(|item| {
|
||||||
|
let box_ = match item.kind {
|
||||||
|
ModernItemKind::InFlow => ArcRefCell::new(TaffyItemBox::new(
|
||||||
|
TaffyItemBoxInner::InFlowBox(item.formatting_context),
|
||||||
|
)),
|
||||||
|
ModernItemKind::OutOfFlow => {
|
||||||
|
let abs_pos_box =
|
||||||
|
ArcRefCell::new(AbsolutelyPositionedBox::new(item.formatting_context));
|
||||||
|
ArcRefCell::new(TaffyItemBox::new(
|
||||||
|
TaffyItemBoxInner::OutOfFlowAbsolutelyPositionedBox(abs_pos_box),
|
||||||
|
))
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(box_slot) = item.box_slot {
|
||||||
|
box_slot.set(LayoutBox::TaffyItemBox(box_.clone()));
|
||||||
|
}
|
||||||
|
|
||||||
|
box_
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Self {
|
||||||
|
children,
|
||||||
|
style: info.style.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub(crate) struct TaffyItemBox {
|
||||||
|
pub(crate) taffy_layout_cache: taffy::Cache,
|
||||||
|
pub(crate) taffy_layout: taffy::Layout,
|
||||||
|
pub(crate) child_fragments: Vec<Fragment>,
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
pub(crate) positioning_context: PositioningContext,
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
pub(crate) style: Arc<ComputedValues>,
|
||||||
|
pub(crate) taffy_level_box: TaffyItemBoxInner,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub(crate) enum TaffyItemBoxInner {
|
||||||
|
InFlowBox(IndependentFormattingContext),
|
||||||
|
OutOfFlowAbsolutelyPositionedBox(ArcRefCell<AbsolutelyPositionedBox>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for TaffyItemBox {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
f.debug_struct("TaffyItemBox")
|
||||||
|
.field("taffy_layout_cache", &self.taffy_layout_cache)
|
||||||
|
.field("taffy_layout", &self.taffy_layout)
|
||||||
|
.field("child_fragments", &self.child_fragments.len())
|
||||||
|
.field("style", &self.style)
|
||||||
|
.field("taffy_level_box", &self.taffy_level_box)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TaffyItemBox {
|
||||||
|
fn new(inner: TaffyItemBoxInner) -> Self {
|
||||||
|
let style: Arc<ComputedValues> = match &inner {
|
||||||
|
TaffyItemBoxInner::InFlowBox(item) => item.style().clone(),
|
||||||
|
TaffyItemBoxInner::OutOfFlowAbsolutelyPositionedBox(absbox) => {
|
||||||
|
(*absbox).borrow().context.style().clone()
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Self {
|
||||||
|
taffy_layout_cache: Default::default(),
|
||||||
|
taffy_layout: Default::default(),
|
||||||
|
child_fragments: Vec::new(),
|
||||||
|
positioning_context: PositioningContext::new_for_containing_block_for_all_descendants(),
|
||||||
|
style,
|
||||||
|
taffy_level_box: inner,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
338
components/layout_2020/taffy/stylo_taffy/convert.rs
Normal file
338
components/layout_2020/taffy/stylo_taffy/convert.rs
Normal file
|
@ -0,0 +1,338 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
/// Private module of type aliases so we can refer to stylo types with nicer names
|
||||||
|
mod stylo {
|
||||||
|
pub(crate) use style::properties::generated::longhands::box_sizing::computed_value::T as BoxSizing;
|
||||||
|
pub(crate) use style::properties::longhands::aspect_ratio::computed_value::T as AspectRatio;
|
||||||
|
pub(crate) use style::properties::longhands::position::computed_value::T as Position;
|
||||||
|
pub(crate) use style::values::computed::{LengthPercentage, Percentage};
|
||||||
|
pub(crate) use style::values::generics::length::{
|
||||||
|
GenericLengthPercentageOrNormal, GenericMargin, GenericMaxSize, GenericSize,
|
||||||
|
};
|
||||||
|
pub(crate) use style::values::generics::position::{Inset as GenericInset, PreferredRatio};
|
||||||
|
pub(crate) use style::values::generics::NonNegative;
|
||||||
|
pub(crate) use style::values::specified::align::{AlignFlags, ContentDistribution};
|
||||||
|
pub(crate) use style::values::specified::box_::{
|
||||||
|
Display, DisplayInside, DisplayOutside, Overflow,
|
||||||
|
};
|
||||||
|
pub(crate) type MarginVal = GenericMargin<LengthPercentage>;
|
||||||
|
pub(crate) type InsetVal = GenericInset<Percentage, LengthPercentage>;
|
||||||
|
pub(crate) type Size = GenericSize<NonNegative<LengthPercentage>>;
|
||||||
|
pub(crate) type MaxSize = GenericMaxSize<NonNegative<LengthPercentage>>;
|
||||||
|
|
||||||
|
pub(crate) type Gap = GenericLengthPercentageOrNormal<NonNegative<LengthPercentage>>;
|
||||||
|
|
||||||
|
pub(crate) use style::computed_values::grid_auto_flow::T as GridAutoFlow;
|
||||||
|
pub(crate) use style::values::computed::{GridLine, GridTemplateComponent, ImplicitGridTracks};
|
||||||
|
pub(crate) use style::values::generics::grid::{
|
||||||
|
RepeatCount, TrackBreadth, TrackListValue, TrackSize,
|
||||||
|
};
|
||||||
|
pub(crate) use style::values::specified::GenericGridTemplateComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn length_percentage(val: &stylo::LengthPercentage) -> taffy::LengthPercentage {
|
||||||
|
if let Some(length) = val.to_length() {
|
||||||
|
taffy::LengthPercentage::Length(length.px())
|
||||||
|
} else if let Some(val) = val.to_percentage() {
|
||||||
|
taffy::LengthPercentage::Percent(val.0)
|
||||||
|
} else {
|
||||||
|
// TODO: Support calc
|
||||||
|
taffy::LengthPercentage::Percent(0.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn dimension(val: &stylo::Size) -> taffy::Dimension {
|
||||||
|
match val {
|
||||||
|
stylo::Size::LengthPercentage(val) => length_percentage(&val.0).into(),
|
||||||
|
stylo::Size::Auto => taffy::Dimension::Auto,
|
||||||
|
|
||||||
|
// TODO: implement other values in Taffy
|
||||||
|
stylo::Size::MaxContent => taffy::Dimension::Auto,
|
||||||
|
stylo::Size::MinContent => taffy::Dimension::Auto,
|
||||||
|
stylo::Size::FitContent => taffy::Dimension::Auto,
|
||||||
|
stylo::Size::Stretch => taffy::Dimension::Auto,
|
||||||
|
|
||||||
|
// Anchor positioning will be flagged off for time being
|
||||||
|
stylo::Size::AnchorSizeFunction(_) => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn max_size_dimension(val: &stylo::MaxSize) -> taffy::Dimension {
|
||||||
|
match val {
|
||||||
|
stylo::MaxSize::LengthPercentage(val) => length_percentage(&val.0).into(),
|
||||||
|
stylo::MaxSize::None => taffy::Dimension::Auto,
|
||||||
|
|
||||||
|
// TODO: implement other values in Taffy
|
||||||
|
stylo::MaxSize::MaxContent => taffy::Dimension::Auto,
|
||||||
|
stylo::MaxSize::MinContent => taffy::Dimension::Auto,
|
||||||
|
stylo::MaxSize::FitContent => taffy::Dimension::Auto,
|
||||||
|
stylo::MaxSize::Stretch => taffy::Dimension::Auto,
|
||||||
|
|
||||||
|
// Anchor positioning will be flagged off for time being
|
||||||
|
stylo::MaxSize::AnchorSizeFunction(_) => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn margin(val: &stylo::MarginVal) -> taffy::LengthPercentageAuto {
|
||||||
|
match val {
|
||||||
|
stylo::MarginVal::Auto => taffy::LengthPercentageAuto::Auto,
|
||||||
|
stylo::MarginVal::LengthPercentage(val) => length_percentage(val).into(),
|
||||||
|
|
||||||
|
// Anchor positioning will be flagged off for time being
|
||||||
|
stylo::MarginVal::AnchorSizeFunction(_) => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn inset(val: &stylo::InsetVal) -> taffy::LengthPercentageAuto {
|
||||||
|
match val {
|
||||||
|
stylo::InsetVal::Auto => taffy::LengthPercentageAuto::Auto,
|
||||||
|
stylo::InsetVal::LengthPercentage(val) => length_percentage(val).into(),
|
||||||
|
|
||||||
|
// Anchor positioning will be flagged off for time being
|
||||||
|
stylo::InsetVal::AnchorSizeFunction(_) => unreachable!(),
|
||||||
|
stylo::InsetVal::AnchorFunction(_) => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_block(input: stylo::Display) -> bool {
|
||||||
|
matches!(input.outside(), stylo::DisplayOutside::Block) &&
|
||||||
|
matches!(
|
||||||
|
input.inside(),
|
||||||
|
stylo::DisplayInside::Flow | stylo::DisplayInside::FlowRoot
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn box_generation_mode(input: stylo::Display) -> taffy::BoxGenerationMode {
|
||||||
|
match input.inside() {
|
||||||
|
stylo::DisplayInside::None => taffy::BoxGenerationMode::None,
|
||||||
|
_ => taffy::BoxGenerationMode::Normal,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn box_sizing(input: stylo::BoxSizing) -> taffy::BoxSizing {
|
||||||
|
match input {
|
||||||
|
stylo::BoxSizing::BorderBox => taffy::BoxSizing::BorderBox,
|
||||||
|
stylo::BoxSizing::ContentBox => taffy::BoxSizing::ContentBox,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn position(input: stylo::Position) -> taffy::Position {
|
||||||
|
match input {
|
||||||
|
// TODO: support position:static
|
||||||
|
stylo::Position::Relative => taffy::Position::Relative,
|
||||||
|
stylo::Position::Static => taffy::Position::Relative,
|
||||||
|
|
||||||
|
// TODO: support position:fixed and sticky
|
||||||
|
stylo::Position::Absolute => taffy::Position::Absolute,
|
||||||
|
stylo::Position::Fixed => taffy::Position::Absolute,
|
||||||
|
stylo::Position::Sticky => taffy::Position::Absolute,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn overflow(input: stylo::Overflow) -> taffy::Overflow {
|
||||||
|
// TODO: Enable Overflow::Clip in servo configuration of stylo
|
||||||
|
match input {
|
||||||
|
stylo::Overflow::Visible => taffy::Overflow::Visible,
|
||||||
|
stylo::Overflow::Hidden => taffy::Overflow::Hidden,
|
||||||
|
stylo::Overflow::Scroll => taffy::Overflow::Scroll,
|
||||||
|
// TODO: Support Overflow::Auto in Taffy
|
||||||
|
stylo::Overflow::Auto => taffy::Overflow::Scroll,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn aspect_ratio(input: stylo::AspectRatio) -> Option<f32> {
|
||||||
|
match input.ratio {
|
||||||
|
stylo::PreferredRatio::None => None,
|
||||||
|
stylo::PreferredRatio::Ratio(val) => Some(val.0 .0 / val.1 .0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn content_alignment(input: stylo::ContentDistribution) -> Option<taffy::AlignContent> {
|
||||||
|
match input.primary().value() {
|
||||||
|
stylo::AlignFlags::NORMAL => None,
|
||||||
|
stylo::AlignFlags::AUTO => None,
|
||||||
|
stylo::AlignFlags::START => Some(taffy::AlignContent::Start),
|
||||||
|
stylo::AlignFlags::END => Some(taffy::AlignContent::End),
|
||||||
|
stylo::AlignFlags::FLEX_START => Some(taffy::AlignContent::FlexStart),
|
||||||
|
stylo::AlignFlags::STRETCH => Some(taffy::AlignContent::Stretch),
|
||||||
|
stylo::AlignFlags::FLEX_END => Some(taffy::AlignContent::FlexEnd),
|
||||||
|
stylo::AlignFlags::CENTER => Some(taffy::AlignContent::Center),
|
||||||
|
stylo::AlignFlags::SPACE_BETWEEN => Some(taffy::AlignContent::SpaceBetween),
|
||||||
|
stylo::AlignFlags::SPACE_AROUND => Some(taffy::AlignContent::SpaceAround),
|
||||||
|
stylo::AlignFlags::SPACE_EVENLY => Some(taffy::AlignContent::SpaceEvenly),
|
||||||
|
// Should never be hit. But no real reason to panic here.
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn item_alignment(input: stylo::AlignFlags) -> Option<taffy::AlignItems> {
|
||||||
|
match input.value() {
|
||||||
|
stylo::AlignFlags::NORMAL => None,
|
||||||
|
stylo::AlignFlags::AUTO => None,
|
||||||
|
stylo::AlignFlags::STRETCH => Some(taffy::AlignItems::Stretch),
|
||||||
|
stylo::AlignFlags::FLEX_START => Some(taffy::AlignItems::FlexStart),
|
||||||
|
stylo::AlignFlags::FLEX_END => Some(taffy::AlignItems::FlexEnd),
|
||||||
|
stylo::AlignFlags::START => Some(taffy::AlignItems::Start),
|
||||||
|
stylo::AlignFlags::END => Some(taffy::AlignItems::End),
|
||||||
|
stylo::AlignFlags::CENTER => Some(taffy::AlignItems::Center),
|
||||||
|
stylo::AlignFlags::BASELINE => Some(taffy::AlignItems::Baseline),
|
||||||
|
// Should never be hit. But no real reason to panic here.
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn gap(input: &stylo::Gap) -> taffy::LengthPercentage {
|
||||||
|
match input {
|
||||||
|
// For Flexbox and CSS Grid the "normal" value is 0px. This may need to be updated
|
||||||
|
// if we ever implement multi-column layout.
|
||||||
|
stylo::Gap::Normal => taffy::LengthPercentage::Length(0.0),
|
||||||
|
stylo::Gap::LengthPercentage(val) => length_percentage(&val.0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CSS Grid styles
|
||||||
|
// ===============
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn grid_auto_flow(input: stylo::GridAutoFlow) -> taffy::GridAutoFlow {
|
||||||
|
let is_row = input.contains(stylo::GridAutoFlow::ROW);
|
||||||
|
let is_dense = input.contains(stylo::GridAutoFlow::DENSE);
|
||||||
|
|
||||||
|
match (is_row, is_dense) {
|
||||||
|
(true, false) => taffy::GridAutoFlow::Row,
|
||||||
|
(true, true) => taffy::GridAutoFlow::RowDense,
|
||||||
|
(false, false) => taffy::GridAutoFlow::Column,
|
||||||
|
(false, true) => taffy::GridAutoFlow::ColumnDense,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn grid_line(input: &stylo::GridLine) -> taffy::GridPlacement {
|
||||||
|
if input.is_auto() {
|
||||||
|
taffy::GridPlacement::Auto
|
||||||
|
} else if input.is_span {
|
||||||
|
taffy::style_helpers::span(input.line_num.try_into().unwrap())
|
||||||
|
} else if input.line_num == 0 {
|
||||||
|
taffy::GridPlacement::Auto
|
||||||
|
} else {
|
||||||
|
taffy::style_helpers::line(input.line_num.try_into().unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn grid_template_tracks(
|
||||||
|
input: &stylo::GridTemplateComponent,
|
||||||
|
) -> Vec<taffy::TrackSizingFunction> {
|
||||||
|
match input {
|
||||||
|
stylo::GenericGridTemplateComponent::None => Vec::new(),
|
||||||
|
stylo::GenericGridTemplateComponent::TrackList(list) => list
|
||||||
|
.values
|
||||||
|
.iter()
|
||||||
|
.map(|track| match track {
|
||||||
|
stylo::TrackListValue::TrackSize(size) => {
|
||||||
|
taffy::TrackSizingFunction::Single(track_size(size))
|
||||||
|
},
|
||||||
|
stylo::TrackListValue::TrackRepeat(repeat) => taffy::TrackSizingFunction::Repeat(
|
||||||
|
track_repeat(repeat.count),
|
||||||
|
repeat.track_sizes.iter().map(track_size).collect(),
|
||||||
|
),
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
|
||||||
|
// TODO: Implement subgrid and masonry
|
||||||
|
stylo::GenericGridTemplateComponent::Subgrid(_) => Vec::new(),
|
||||||
|
stylo::GenericGridTemplateComponent::Masonry => Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn grid_auto_tracks(
|
||||||
|
input: &stylo::ImplicitGridTracks,
|
||||||
|
) -> Vec<taffy::NonRepeatedTrackSizingFunction> {
|
||||||
|
input.0.iter().map(track_size).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn track_repeat(input: stylo::RepeatCount<i32>) -> taffy::GridTrackRepetition {
|
||||||
|
match input {
|
||||||
|
stylo::RepeatCount::Number(val) => {
|
||||||
|
taffy::GridTrackRepetition::Count(val.try_into().unwrap())
|
||||||
|
},
|
||||||
|
stylo::RepeatCount::AutoFill => taffy::GridTrackRepetition::AutoFill,
|
||||||
|
stylo::RepeatCount::AutoFit => taffy::GridTrackRepetition::AutoFit,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn track_size(
|
||||||
|
input: &stylo::TrackSize<stylo::LengthPercentage>,
|
||||||
|
) -> taffy::NonRepeatedTrackSizingFunction {
|
||||||
|
match input {
|
||||||
|
stylo::TrackSize::Breadth(breadth) => taffy::MinMax {
|
||||||
|
min: min_track(breadth),
|
||||||
|
max: max_track(breadth),
|
||||||
|
},
|
||||||
|
stylo::TrackSize::Minmax(min, max) => taffy::MinMax {
|
||||||
|
min: min_track(min),
|
||||||
|
max: max_track(max),
|
||||||
|
},
|
||||||
|
stylo::TrackSize::FitContent(limit) => taffy::MinMax {
|
||||||
|
min: taffy::MinTrackSizingFunction::Auto,
|
||||||
|
max: taffy::MaxTrackSizingFunction::FitContent(match limit {
|
||||||
|
stylo::TrackBreadth::Breadth(lp) => length_percentage(lp),
|
||||||
|
|
||||||
|
// Are these valid? Taffy doesn't support this in any case
|
||||||
|
stylo::TrackBreadth::Fr(_) => unreachable!(),
|
||||||
|
stylo::TrackBreadth::Auto => unreachable!(),
|
||||||
|
stylo::TrackBreadth::MinContent => unreachable!(),
|
||||||
|
stylo::TrackBreadth::MaxContent => unreachable!(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn min_track(
|
||||||
|
input: &stylo::TrackBreadth<stylo::LengthPercentage>,
|
||||||
|
) -> taffy::MinTrackSizingFunction {
|
||||||
|
match input {
|
||||||
|
stylo::TrackBreadth::Breadth(lp) => {
|
||||||
|
taffy::MinTrackSizingFunction::Fixed(length_percentage(lp))
|
||||||
|
},
|
||||||
|
stylo::TrackBreadth::Fr(_) => taffy::MinTrackSizingFunction::Auto,
|
||||||
|
stylo::TrackBreadth::Auto => taffy::MinTrackSizingFunction::Auto,
|
||||||
|
stylo::TrackBreadth::MinContent => taffy::MinTrackSizingFunction::MinContent,
|
||||||
|
stylo::TrackBreadth::MaxContent => taffy::MinTrackSizingFunction::MaxContent,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn max_track(
|
||||||
|
input: &stylo::TrackBreadth<stylo::LengthPercentage>,
|
||||||
|
) -> taffy::MaxTrackSizingFunction {
|
||||||
|
match input {
|
||||||
|
stylo::TrackBreadth::Breadth(lp) => {
|
||||||
|
taffy::MaxTrackSizingFunction::Fixed(length_percentage(lp))
|
||||||
|
},
|
||||||
|
stylo::TrackBreadth::Fr(val) => taffy::MaxTrackSizingFunction::Fraction(*val),
|
||||||
|
stylo::TrackBreadth::Auto => taffy::MaxTrackSizingFunction::Auto,
|
||||||
|
stylo::TrackBreadth::MinContent => taffy::MaxTrackSizingFunction::MinContent,
|
||||||
|
stylo::TrackBreadth::MaxContent => taffy::MaxTrackSizingFunction::MaxContent,
|
||||||
|
}
|
||||||
|
}
|
9
components/layout_2020/taffy/stylo_taffy/mod.rs
Normal file
9
components/layout_2020/taffy/stylo_taffy/mod.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
//! Conversion functions from Stylo types to Taffy types
|
||||||
|
|
||||||
|
mod convert;
|
||||||
|
mod wrapper;
|
||||||
|
pub use wrapper::TaffyStyloStyle;
|
226
components/layout_2020/taffy/stylo_taffy/wrapper.rs
Normal file
226
components/layout_2020/taffy/stylo_taffy/wrapper.rs
Normal file
|
@ -0,0 +1,226 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
use style::properties::ComputedValues;
|
||||||
|
|
||||||
|
use super::convert;
|
||||||
|
|
||||||
|
/// A wrapper struct for anything that Deref's to a [`stylo::ComputedValues`], which
|
||||||
|
/// implements Taffy's layout traits and can used with Taffy's layout algorithms.
|
||||||
|
pub struct TaffyStyloStyle<T: Deref<Target = ComputedValues>>(pub T);
|
||||||
|
|
||||||
|
impl<T: Deref<Target = ComputedValues>> From<T> for TaffyStyloStyle<T> {
|
||||||
|
fn from(value: T) -> Self {
|
||||||
|
Self(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Deref<Target = ComputedValues>> taffy::CoreStyle for TaffyStyloStyle<T> {
|
||||||
|
#[inline]
|
||||||
|
fn box_generation_mode(&self) -> taffy::BoxGenerationMode {
|
||||||
|
convert::box_generation_mode(self.0.get_box().display)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_block(&self) -> bool {
|
||||||
|
convert::is_block(self.0.get_box().display)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn box_sizing(&self) -> taffy::BoxSizing {
|
||||||
|
convert::box_sizing(self.0.get_position().box_sizing)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn overflow(&self) -> taffy::Point<taffy::Overflow> {
|
||||||
|
let box_styles = self.0.get_box();
|
||||||
|
taffy::Point {
|
||||||
|
x: convert::overflow(box_styles.overflow_x),
|
||||||
|
y: convert::overflow(box_styles.overflow_y),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn scrollbar_width(&self) -> f32 {
|
||||||
|
0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn position(&self) -> taffy::Position {
|
||||||
|
convert::position(self.0.get_box().position)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn inset(&self) -> taffy::Rect<taffy::LengthPercentageAuto> {
|
||||||
|
let position_styles = self.0.get_position();
|
||||||
|
taffy::Rect {
|
||||||
|
left: convert::inset(&position_styles.left),
|
||||||
|
right: convert::inset(&position_styles.right),
|
||||||
|
top: convert::inset(&position_styles.top),
|
||||||
|
bottom: convert::inset(&position_styles.bottom),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn size(&self) -> taffy::Size<taffy::Dimension> {
|
||||||
|
let position_styles = self.0.get_position();
|
||||||
|
taffy::Size {
|
||||||
|
width: convert::dimension(&position_styles.width),
|
||||||
|
height: convert::dimension(&position_styles.height),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn min_size(&self) -> taffy::Size<taffy::Dimension> {
|
||||||
|
let position_styles = self.0.get_position();
|
||||||
|
taffy::Size {
|
||||||
|
width: convert::dimension(&position_styles.min_width),
|
||||||
|
height: convert::dimension(&position_styles.min_height),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn max_size(&self) -> taffy::Size<taffy::Dimension> {
|
||||||
|
let position_styles = self.0.get_position();
|
||||||
|
taffy::Size {
|
||||||
|
width: convert::max_size_dimension(&position_styles.max_width),
|
||||||
|
height: convert::max_size_dimension(&position_styles.max_height),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn aspect_ratio(&self) -> Option<f32> {
|
||||||
|
convert::aspect_ratio(self.0.get_position().aspect_ratio)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn margin(&self) -> taffy::Rect<taffy::LengthPercentageAuto> {
|
||||||
|
let margin_styles = self.0.get_margin();
|
||||||
|
taffy::Rect {
|
||||||
|
left: convert::margin(&margin_styles.margin_left),
|
||||||
|
right: convert::margin(&margin_styles.margin_right),
|
||||||
|
top: convert::margin(&margin_styles.margin_top),
|
||||||
|
bottom: convert::margin(&margin_styles.margin_bottom),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn padding(&self) -> taffy::Rect<taffy::LengthPercentage> {
|
||||||
|
let padding_styles = self.0.get_padding();
|
||||||
|
taffy::Rect {
|
||||||
|
left: convert::length_percentage(&padding_styles.padding_left.0),
|
||||||
|
right: convert::length_percentage(&padding_styles.padding_right.0),
|
||||||
|
top: convert::length_percentage(&padding_styles.padding_top.0),
|
||||||
|
bottom: convert::length_percentage(&padding_styles.padding_bottom.0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn border(&self) -> taffy::Rect<taffy::LengthPercentage> {
|
||||||
|
let border_styles = self.0.get_border();
|
||||||
|
taffy::Rect {
|
||||||
|
left: taffy::LengthPercentage::Length(border_styles.border_left_width.to_f32_px()),
|
||||||
|
right: taffy::LengthPercentage::Length(border_styles.border_right_width.to_f32_px()),
|
||||||
|
top: taffy::LengthPercentage::Length(border_styles.border_top_width.to_f32_px()),
|
||||||
|
bottom: taffy::LengthPercentage::Length(border_styles.border_bottom_width.to_f32_px()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Deref<Target = ComputedValues>> taffy::GridContainerStyle for TaffyStyloStyle<T> {
|
||||||
|
type TemplateTrackList<'a>
|
||||||
|
= Vec<taffy::TrackSizingFunction>
|
||||||
|
where
|
||||||
|
Self: 'a;
|
||||||
|
type AutoTrackList<'a>
|
||||||
|
= Vec<taffy::NonRepeatedTrackSizingFunction>
|
||||||
|
where
|
||||||
|
Self: 'a;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn grid_template_rows(&self) -> Self::TemplateTrackList<'_> {
|
||||||
|
convert::grid_template_tracks(&self.0.get_position().grid_template_rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn grid_template_columns(&self) -> Self::TemplateTrackList<'_> {
|
||||||
|
convert::grid_template_tracks(&self.0.get_position().grid_template_columns)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn grid_auto_rows(&self) -> Self::AutoTrackList<'_> {
|
||||||
|
convert::grid_auto_tracks(&self.0.get_position().grid_auto_rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn grid_auto_columns(&self) -> Self::AutoTrackList<'_> {
|
||||||
|
convert::grid_auto_tracks(&self.0.get_position().grid_auto_columns)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn grid_auto_flow(&self) -> taffy::GridAutoFlow {
|
||||||
|
convert::grid_auto_flow(self.0.get_position().grid_auto_flow)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn gap(&self) -> taffy::Size<taffy::LengthPercentage> {
|
||||||
|
let position_styles = self.0.get_position();
|
||||||
|
taffy::Size {
|
||||||
|
width: convert::gap(&position_styles.column_gap),
|
||||||
|
height: convert::gap(&position_styles.row_gap),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn align_content(&self) -> Option<taffy::AlignContent> {
|
||||||
|
convert::content_alignment(self.0.get_position().align_content.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn justify_content(&self) -> Option<taffy::JustifyContent> {
|
||||||
|
convert::content_alignment(self.0.get_position().justify_content.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn align_items(&self) -> Option<taffy::AlignItems> {
|
||||||
|
convert::item_alignment(self.0.get_position().align_items.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn justify_items(&self) -> Option<taffy::AlignItems> {
|
||||||
|
convert::item_alignment(self.0.get_position().justify_items.computed.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Deref<Target = ComputedValues>> taffy::GridItemStyle for TaffyStyloStyle<T> {
|
||||||
|
#[inline]
|
||||||
|
fn grid_row(&self) -> taffy::Line<taffy::GridPlacement> {
|
||||||
|
let position_styles = self.0.get_position();
|
||||||
|
taffy::Line {
|
||||||
|
start: convert::grid_line(&position_styles.grid_row_start),
|
||||||
|
end: convert::grid_line(&position_styles.grid_row_end),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn grid_column(&self) -> taffy::Line<taffy::GridPlacement> {
|
||||||
|
let position_styles = self.0.get_position();
|
||||||
|
taffy::Line {
|
||||||
|
start: convert::grid_line(&position_styles.grid_column_start),
|
||||||
|
end: convert::grid_line(&position_styles.grid_column_end),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn align_self(&self) -> Option<taffy::AlignSelf> {
|
||||||
|
convert::item_alignment(self.0.get_position().align_self.0 .0)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn justify_self(&self) -> Option<taffy::AlignSelf> {
|
||||||
|
convert::item_alignment(self.0.get_position().justify_self.0 .0)
|
||||||
|
}
|
||||||
|
}
|
|
@ -103,6 +103,7 @@
|
||||||
"layout.columns.enabled": false,
|
"layout.columns.enabled": false,
|
||||||
"layout.css.transition-behavior.enabled": true,
|
"layout.css.transition-behavior.enabled": true,
|
||||||
"layout.flexbox.enabled": true,
|
"layout.flexbox.enabled": true,
|
||||||
|
"layout.grid.enabled": false,
|
||||||
"layout.legacy_layout": false,
|
"layout.legacy_layout": false,
|
||||||
"layout.threads": 3,
|
"layout.threads": 3,
|
||||||
"layout.writing-mode.enabled": false,
|
"layout.writing-mode.enabled": false,
|
||||||
|
|
1
tests/wpt/meta/css/css-grid/__dir__.ini
vendored
Normal file
1
tests/wpt/meta/css/css-grid/__dir__.ini
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
prefs: ["layout.columns.enabled:true", "layout.flexbox.enabled:true", "layout.grid.enabled:true"]
|
|
@ -1,3 +0,0 @@
|
||||||
[absolute-positioning-definite-sizes-001.html]
|
|
||||||
[.grid 1]
|
|
||||||
expected: FAIL
|
|
|
@ -13,3 +13,12 @@
|
||||||
|
|
||||||
[.container 12]
|
[.container 12]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[.container 7]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.container 8]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.container 9]
|
||||||
|
expected: FAIL
|
||||||
|
|
2
tests/wpt/meta/css/css-grid/abspos/grid-abspos-staticpos-align-self-safe-001.html.ini
vendored
Normal file
2
tests/wpt/meta/css/css-grid/abspos/grid-abspos-staticpos-align-self-safe-001.html.ini
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[grid-abspos-staticpos-align-self-safe-001.html]
|
||||||
|
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
||||||
[positioned-grid-items-018.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[positioned-grid-items-024.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,22 +1,4 @@
|
||||||
[positioned-grid-items-should-not-take-up-space-001.html]
|
[positioned-grid-items-should-not-take-up-space-001.html]
|
||||||
[.grid 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 3]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 4]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 5]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 6]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 7]
|
[.grid 7]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -13,3 +13,6 @@
|
||||||
|
|
||||||
[#target > div 6]
|
[#target > div 6]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[#target > div 4]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -13,3 +13,6 @@
|
||||||
|
|
||||||
[#target > div 6]
|
[#target > div 6]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[#target > div 4]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
[grid-align-baseline-004.html]
|
[grid-align-baseline-004.html]
|
||||||
[#target > div 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[#target > div 2]
|
[#target > div 2]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
|
@ -7,6 +7,3 @@
|
||||||
|
|
||||||
[.target > * 3]
|
[.target > * 3]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 4]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -4,3 +4,9 @@
|
||||||
|
|
||||||
[.target > * 3]
|
[.target > * 3]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 2]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 4]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -4,3 +4,9 @@
|
||||||
|
|
||||||
[.target > * 3]
|
[.target > * 3]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 2]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 4]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -2,143 +2,68 @@
|
||||||
[.target > * 1]
|
[.target > * 1]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 3]
|
[.target > * 3]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 4]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 5]
|
[.target > * 5]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 6]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 7]
|
[.target > * 7]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 8]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 9]
|
[.target > * 9]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 10]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 11]
|
[.target > * 11]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 12]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 13]
|
[.target > * 13]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 14]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 15]
|
[.target > * 15]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 16]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 17]
|
[.target > * 17]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 18]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 19]
|
[.target > * 19]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 20]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 21]
|
[.target > * 21]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 22]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 23]
|
[.target > * 23]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 24]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 25]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 26]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 27]
|
[.target > * 27]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 28]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 29]
|
[.target > * 29]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 30]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 31]
|
[.target > * 31]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 32]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 33]
|
[.target > * 33]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 34]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 35]
|
[.target > * 35]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 36]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 37]
|
[.target > * 37]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 38]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 39]
|
[.target > * 39]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 40]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 41]
|
[.target > * 41]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 42]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 43]
|
[.target > * 43]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 44]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 45]
|
[.target > * 45]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 46]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 47]
|
[.target > * 47]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 48]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -70,3 +70,75 @@
|
||||||
|
|
||||||
[.target > * 47]
|
[.target > * 47]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 2]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 4]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 6]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 8]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 10]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 12]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 14]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 16]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 18]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 20]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 22]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 24]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 26]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 28]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 30]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 32]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 34]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 36]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 38]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 40]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 42]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 44]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 46]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 48]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -2,47 +2,23 @@
|
||||||
[.target > * 1]
|
[.target > * 1]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 3]
|
[.target > * 3]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 4]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 5]
|
[.target > * 5]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 6]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 7]
|
[.target > * 7]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 8]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 9]
|
[.target > * 9]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 10]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 11]
|
[.target > * 11]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 12]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 13]
|
[.target > * 13]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 14]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 15]
|
[.target > * 15]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 16]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -22,3 +22,27 @@
|
||||||
|
|
||||||
[.target > * 15]
|
[.target > * 15]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 2]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 4]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 6]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 8]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 10]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 12]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 14]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 16]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -2,35 +2,17 @@
|
||||||
[.target > * 1]
|
[.target > * 1]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 3]
|
[.target > * 3]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 4]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 5]
|
[.target > * 5]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 6]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 7]
|
[.target > * 7]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 8]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 9]
|
[.target > * 9]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 10]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 11]
|
[.target > * 11]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 12]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -16,3 +16,21 @@
|
||||||
|
|
||||||
[.target > * 11]
|
[.target > * 11]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 2]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 4]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 6]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 8]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 10]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 12]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -16,3 +16,21 @@
|
||||||
|
|
||||||
[.target > * 11]
|
[.target > * 11]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 2]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 4]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 6]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 8]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 10]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 12]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -2,71 +2,35 @@
|
||||||
[.target > * 1]
|
[.target > * 1]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 3]
|
[.target > * 3]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 4]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 5]
|
[.target > * 5]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 6]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 7]
|
[.target > * 7]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 8]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 9]
|
[.target > * 9]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 10]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 11]
|
[.target > * 11]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 12]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 13]
|
[.target > * 13]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 14]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 15]
|
[.target > * 15]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 16]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 17]
|
[.target > * 17]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 18]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 19]
|
[.target > * 19]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 20]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 21]
|
[.target > * 21]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 22]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 23]
|
[.target > * 23]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 24]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -34,3 +34,39 @@
|
||||||
|
|
||||||
[.target > * 23]
|
[.target > * 23]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 2]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 4]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 6]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 8]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 10]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 12]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 14]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 16]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 18]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 20]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 22]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 24]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -34,3 +34,39 @@
|
||||||
|
|
||||||
[.target > * 23]
|
[.target > * 23]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 2]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 4]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 6]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 8]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 10]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 12]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 14]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 16]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 18]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 20]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 22]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 24]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -8,21 +8,12 @@
|
||||||
[.target > * 3]
|
[.target > * 3]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 4]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 5]
|
[.target > * 5]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 6]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 7]
|
[.target > * 7]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 8]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 9]
|
[.target > * 9]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -31,6 +22,3 @@
|
||||||
|
|
||||||
[.target > * 11]
|
[.target > * 11]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 12]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -16,3 +16,21 @@
|
||||||
|
|
||||||
[.target > * 11]
|
[.target > * 11]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 2]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 4]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 6]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 8]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 10]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 12]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -16,3 +16,21 @@
|
||||||
|
|
||||||
[.target > * 11]
|
[.target > * 11]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 2]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 4]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 6]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 8]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 10]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 12]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -2,15 +2,9 @@
|
||||||
[.target > * 1]
|
[.target > * 1]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 3]
|
[.target > * 3]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 4]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 6]
|
[.target > * 6]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -20,11 +14,5 @@
|
||||||
[.target > * 9]
|
[.target > * 9]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 10]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 11]
|
[.target > * 11]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 12]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -13,3 +13,18 @@
|
||||||
|
|
||||||
[.target > * 10]
|
[.target > * 10]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 2]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 4]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 6]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 8]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 12]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -13,3 +13,18 @@
|
||||||
|
|
||||||
[.target > * 11]
|
[.target > * 11]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 2]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 4]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 6]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 10]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 12]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -1,24 +1,9 @@
|
||||||
[grid-align-baseline-table-001.html]
|
[grid-align-baseline-table-001.html]
|
||||||
[.target > * 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 3]
|
[.target > * 3]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 4]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 5]
|
[.target > * 5]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 6]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.target > * 7]
|
[.target > * 7]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.target > * 8]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -4,3 +4,9 @@
|
||||||
|
|
||||||
[.target > * 3]
|
[.target > * 3]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 2]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 4]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -4,3 +4,9 @@
|
||||||
|
|
||||||
[.target > * 3]
|
[.target > * 3]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 2]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.target > * 4]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -16,3 +16,15 @@
|
||||||
|
|
||||||
[Additional Check 4]
|
[Additional Check 4]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[Additional Check 1]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Additional Check 3]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Additional Check 5]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Additional Check 6]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
[grid-align-baseline.html]
|
[grid-align-baseline.html]
|
||||||
[.grid 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 2]
|
[.grid 2]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -13,15 +10,3 @@
|
||||||
|
|
||||||
[.grid 5]
|
[.grid 5]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Additional Check 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Additional Check 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Additional Check 3]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Additional Check 4]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,40 +1,4 @@
|
||||||
[grid-align-content-distribution.html]
|
[grid-align-content-distribution.html]
|
||||||
[.grid 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 3]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 4]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 5]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 6]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 7]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 8]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 9]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 10]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 11]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 12]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 13]
|
[.grid 13]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,28 +1,4 @@
|
||||||
[grid-align-content.html]
|
[grid-align-content.html]
|
||||||
[.grid 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 3]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 4]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 5]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 6]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 7]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 8]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 9]
|
[.grid 9]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
[grid-align-stretching-replaced-items.html]
|
[grid-align-stretching-replaced-items.html]
|
||||||
[.grid 3]
|
[.grid 1]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.grid 2]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-alignment-implies-size-change-001.html]
|
|
||||||
[.before 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-alignment-implies-size-change-002.html]
|
|
||||||
[.before 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-alignment-implies-size-change-003.html]
|
|
||||||
[.before 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-alignment-implies-size-change-004.html]
|
|
||||||
[.before 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-alignment-implies-size-change-005.html]
|
|
||||||
[.before 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-alignment-implies-size-change-006.html]
|
|
||||||
[.before 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-alignment-implies-size-change-007.html]
|
|
||||||
[.before 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-alignment-implies-size-change-008.html]
|
|
||||||
[.before 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-alignment-implies-size-change-009.html]
|
|
||||||
[.before 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-alignment-implies-size-change-010.html]
|
|
||||||
[.before 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +1,6 @@
|
||||||
[grid-alignment-implies-size-change-013.html]
|
[grid-alignment-implies-size-change-013.html]
|
||||||
[.before 1]
|
[.before 1]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[.after 2]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
[grid-alignment-implies-size-change-014.html]
|
[grid-alignment-implies-size-change-014.html]
|
||||||
[.after 2]
|
[.after 2]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[.before 1]
|
||||||
|
expected: FAIL
|
||||||
|
|
3
tests/wpt/meta/css/css-grid/alignment/grid-alignment-implies-size-change-015.html.ini
vendored
Normal file
3
tests/wpt/meta/css/css-grid/alignment/grid-alignment-implies-size-change-015.html.ini
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[grid-alignment-implies-size-change-015.html]
|
||||||
|
[.after 2]
|
||||||
|
expected: FAIL
|
3
tests/wpt/meta/css/css-grid/alignment/grid-alignment-implies-size-change-016.html.ini
vendored
Normal file
3
tests/wpt/meta/css/css-grid/alignment/grid-alignment-implies-size-change-016.html.ini
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[grid-alignment-implies-size-change-016.html]
|
||||||
|
[.before 1]
|
||||||
|
expected: FAIL
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-alignment-implies-size-change-019.html]
|
|
||||||
[.before 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-alignment-implies-size-change-020.html]
|
|
||||||
[.before 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-alignment-implies-size-change-021.html]
|
|
||||||
[.before 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-alignment-implies-size-change-022.html]
|
|
||||||
[.before 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-alignment-implies-size-change-023.html]
|
|
||||||
[.before 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-alignment-implies-size-change-024.html]
|
|
||||||
[.before 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-alignment-implies-size-change-025.html]
|
|
||||||
[.before 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-alignment-implies-size-change-026.html]
|
|
||||||
[.before 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-alignment-implies-size-change-027.html]
|
|
||||||
[.before 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-alignment-implies-size-change-028.html]
|
|
||||||
[.before 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +1,6 @@
|
||||||
[grid-alignment-implies-size-change-031.html]
|
[grid-alignment-implies-size-change-031.html]
|
||||||
[.before 1]
|
[.before 1]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[.after 2]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
[grid-alignment-implies-size-change-032.html]
|
[grid-alignment-implies-size-change-032.html]
|
||||||
[.after 2]
|
[.before 1]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
3
tests/wpt/meta/css/css-grid/alignment/grid-alignment-implies-size-change-033.html.ini
vendored
Normal file
3
tests/wpt/meta/css/css-grid/alignment/grid-alignment-implies-size-change-033.html.ini
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[grid-alignment-implies-size-change-033.html]
|
||||||
|
[.after 2]
|
||||||
|
expected: FAIL
|
3
tests/wpt/meta/css/css-grid/alignment/grid-alignment-implies-size-change-034.html.ini
vendored
Normal file
3
tests/wpt/meta/css/css-grid/alignment/grid-alignment-implies-size-change-034.html.ini
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[grid-alignment-implies-size-change-034.html]
|
||||||
|
[.before 1]
|
||||||
|
expected: FAIL
|
|
@ -2,17 +2,8 @@
|
||||||
[.before 1]
|
[.before 1]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.before 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.before 3]
|
[.before 3]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.after 4]
|
[.after 4]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.after 5]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 6]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -2,17 +2,8 @@
|
||||||
[.before 1]
|
[.before 1]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.before 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.before 3]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 4]
|
[.after 4]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.after 5]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 6]
|
[.after 6]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
|
@ -11,8 +11,5 @@
|
||||||
[.after 4]
|
[.after 4]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.after 5]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 6]
|
[.after 6]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
|
@ -2,9 +2,6 @@
|
||||||
[.before 1]
|
[.before 1]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.before 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.before 3]
|
[.before 3]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,6 @@
|
||||||
[grid-alignment-style-changes-005.html]
|
[grid-alignment-style-changes-005.html]
|
||||||
[.before 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.before 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.before 3]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 4]
|
[.after 4]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.after 5]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 6]
|
[.after 6]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
|
@ -2,17 +2,5 @@
|
||||||
[.before 1]
|
[.before 1]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.before 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.before 3]
|
[.before 3]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.after 4]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 5]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 6]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -2,17 +2,8 @@
|
||||||
[.before 1]
|
[.before 1]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.before 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.before 3]
|
[.before 3]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.after 4]
|
[.after 4]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.after 5]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 6]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -2,17 +2,8 @@
|
||||||
[.before 1]
|
[.before 1]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.before 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.before 3]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 4]
|
[.after 4]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.after 5]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.after 6]
|
[.after 6]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-block-axis-alignment-auto-margins-001.html]
|
|
||||||
[#grid 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[#grid 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-block-axis-alignment-auto-margins-002.html]
|
|
||||||
[#grid 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[#grid 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-block-axis-alignment-auto-margins-003.html]
|
|
||||||
[#grid 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[#grid 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-block-axis-alignment-auto-margins-004.html]
|
|
||||||
[#grid 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[#grid 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-block-axis-alignment-auto-margins-005.html]
|
|
||||||
[#grid 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[#grid 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-block-axis-alignment-auto-margins-006.html]
|
|
||||||
[#grid 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[#grid 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[grid-block-axis-alignment-auto-margins-007.html]
|
|
||||||
[#grid 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[#grid 2]
|
|
||||||
expected: FAIL
|
|
|
@ -19,3 +19,15 @@
|
||||||
|
|
||||||
[.wrapper 11]
|
[.wrapper 11]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[.wrapper 4]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.wrapper 5]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.wrapper 6]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.wrapper 7]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -1,40 +1,4 @@
|
||||||
[grid-content-alignment-and-self-alignment-001.html]
|
[grid-content-alignment-and-self-alignment-001.html]
|
||||||
[.grid 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 3]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 4]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 5]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 6]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 7]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 8]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 9]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 10]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 11]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 12]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.grid 13]
|
[.grid 13]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue