mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Auto merge of #24528 - servo:background-color, r=nox
Layout 2020: run layout and paint background-color
This commit is contained in:
commit
4cdfe23cc8
22 changed files with 258 additions and 62 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2477,6 +2477,7 @@ version = "0.0.1"
|
|||
dependencies = [
|
||||
"app_units",
|
||||
"atomic_refcell",
|
||||
"cssparser",
|
||||
"euclid",
|
||||
"gfx",
|
||||
"ipc-channel",
|
||||
|
|
|
@ -15,6 +15,7 @@ doctest = false
|
|||
[dependencies]
|
||||
app_units = "0.7"
|
||||
atomic_refcell = "0.1"
|
||||
cssparser = "0.27"
|
||||
euclid = "0.20"
|
||||
gfx = {path = "../gfx"}
|
||||
ipc-channel = "0.12"
|
||||
|
|
106
components/layout_2020/display_list.rs
Normal file
106
components/layout_2020/display_list.rs
Normal file
|
@ -0,0 +1,106 @@
|
|||
/* 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 crate::fragments::{BoxFragment, Fragment};
|
||||
use crate::geom::physical::{Rect, Vec2};
|
||||
use crate::style_ext::ComputedValuesExt;
|
||||
use app_units::Au;
|
||||
use style::values::computed::Length;
|
||||
use webrender_api::CommonItemProperties;
|
||||
|
||||
pub struct DisplayListBuilder {
|
||||
pipeline_id: webrender_api::PipelineId,
|
||||
pub wr: webrender_api::DisplayListBuilder,
|
||||
pub is_contentful: bool,
|
||||
}
|
||||
|
||||
impl DisplayListBuilder {
|
||||
pub fn new(
|
||||
pipeline_id: webrender_api::PipelineId,
|
||||
viewport_size: webrender_api::units::LayoutSize,
|
||||
) -> Self {
|
||||
Self {
|
||||
pipeline_id,
|
||||
is_contentful: false,
|
||||
wr: webrender_api::DisplayListBuilder::new(pipeline_id, viewport_size),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Contentful paint, for the purpose of
|
||||
/// https://w3c.github.io/paint-timing/#first-contentful-paint
|
||||
/// (i.e. the display list contains items of type text,
|
||||
/// image, non-white canvas or SVG). Used by metrics.
|
||||
pub struct IsContentful(pub bool);
|
||||
|
||||
impl Fragment {
|
||||
pub(crate) fn build_display_list(
|
||||
&self,
|
||||
builder: &mut DisplayListBuilder,
|
||||
is_contentful: &mut IsContentful,
|
||||
containing_block: &Rect<Length>,
|
||||
) {
|
||||
match self {
|
||||
Fragment::Box(b) => b.build_display_list(builder, is_contentful, containing_block),
|
||||
Fragment::Anonymous(a) => {
|
||||
let rect = a
|
||||
.rect
|
||||
.to_physical(a.mode, containing_block)
|
||||
.translate(&containing_block.top_left);
|
||||
for child in &a.children {
|
||||
child.build_display_list(builder, is_contentful, &rect)
|
||||
}
|
||||
},
|
||||
Fragment::Text(_) => {
|
||||
is_contentful.0 = true;
|
||||
// FIXME
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BoxFragment {
|
||||
fn build_display_list(
|
||||
&self,
|
||||
builder: &mut DisplayListBuilder,
|
||||
is_contentful: &mut IsContentful,
|
||||
containing_block: &Rect<Length>,
|
||||
) {
|
||||
let background_color = self
|
||||
.style
|
||||
.resolve_color(self.style.clone_background_color());
|
||||
if background_color.alpha > 0 {
|
||||
let clip_rect = self
|
||||
.border_rect()
|
||||
.to_physical(self.style.writing_mode(), containing_block)
|
||||
.translate(&containing_block.top_left)
|
||||
.into();
|
||||
let common = CommonItemProperties {
|
||||
clip_rect,
|
||||
clip_id: webrender_api::ClipId::root(builder.pipeline_id),
|
||||
spatial_id: webrender_api::SpatialId::root_scroll_node(builder.pipeline_id),
|
||||
hit_info: None,
|
||||
// TODO(gw): Make use of the WR backface visibility functionality.
|
||||
is_backface_visible: true,
|
||||
};
|
||||
builder.wr.push_rect(&common, rgba(background_color))
|
||||
}
|
||||
let content_rect = self
|
||||
.content_rect
|
||||
.to_physical(self.style.writing_mode(), containing_block)
|
||||
.translate(&containing_block.top_left);
|
||||
for child in &self.children {
|
||||
child.build_display_list(builder, is_contentful, &content_rect)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn rgba(rgba: cssparser::RGBA) -> webrender_api::ColorF {
|
||||
webrender_api::ColorF::new(
|
||||
rgba.red_f32(),
|
||||
rgba.green_f32(),
|
||||
rgba.blue_f32(),
|
||||
rgba.alpha_f32(),
|
||||
)
|
||||
}
|
|
@ -210,7 +210,6 @@ where
|
|||
self.handle_block_level_element(style.clone(), inside, contents, box_slot)
|
||||
}
|
||||
},
|
||||
DisplayOutside::None => panic!(":("),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -352,7 +351,6 @@ where
|
|||
inline_box.last_fragment = true;
|
||||
Arc::new(InlineLevelBox::InlineBox(inline_box))
|
||||
},
|
||||
DisplayInside::None | DisplayInside::Contents => panic!(":("),
|
||||
},
|
||||
};
|
||||
self.current_inline_level_boxes().push(box_.clone());
|
||||
|
|
|
@ -122,7 +122,6 @@ impl InlineFormattingContext {
|
|||
inline: match outside {
|
||||
DisplayOutside::Inline => ifc.inline_position,
|
||||
DisplayOutside::Block => Length::zero(),
|
||||
DisplayOutside::None => unreachable!(":("),
|
||||
},
|
||||
block: ifc.line_boxes.next_line_block_position,
|
||||
},
|
||||
|
|
|
@ -27,7 +27,7 @@ mod float;
|
|||
pub mod inline;
|
||||
mod root;
|
||||
|
||||
pub use root::BoxTreeRoot;
|
||||
pub use root::{BoxTreeRoot, FragmentTreeRoot};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct BlockFormattingContext {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* 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 crate::display_list::IsContentful;
|
||||
use crate::dom_traversal::{Contents, NodeExt};
|
||||
use crate::flow::construct::ContainsFloats;
|
||||
use crate::flow::float::FloatBox;
|
||||
|
@ -20,9 +21,11 @@ use servo_arc::Arc;
|
|||
use style::context::SharedStyleContext;
|
||||
use style::properties::ComputedValues;
|
||||
use style::values::computed::{Length, LengthOrAuto};
|
||||
use style::Zero;
|
||||
use style_traits::CSSPixel;
|
||||
|
||||
pub struct BoxTreeRoot(BlockFormattingContext);
|
||||
pub struct FragmentTreeRoot(Vec<Fragment>);
|
||||
|
||||
impl BoxTreeRoot {
|
||||
pub fn construct<'dom>(
|
||||
|
@ -95,7 +98,7 @@ fn construct_for_root_element<'dom>(
|
|||
}
|
||||
|
||||
impl BoxTreeRoot {
|
||||
fn layout(&self, viewport: geom::Size<CSSPixel>) -> Vec<Fragment> {
|
||||
pub fn layout(&self, viewport: geom::Size<CSSPixel>) -> FragmentTreeRoot {
|
||||
let initial_containing_block_size = Vec2 {
|
||||
inline: Length::new(viewport.width),
|
||||
block: Length::new(viewport.height),
|
||||
|
@ -125,6 +128,31 @@ impl BoxTreeRoot {
|
|||
.par_iter()
|
||||
.map(|a| a.layout(&initial_containing_block)),
|
||||
);
|
||||
flow_children.fragments
|
||||
FragmentTreeRoot(flow_children.fragments)
|
||||
}
|
||||
}
|
||||
|
||||
impl FragmentTreeRoot {
|
||||
pub fn build_display_list(
|
||||
&self,
|
||||
builder: &mut crate::display_list::DisplayListBuilder,
|
||||
pipeline_id: msg::constellation_msg::PipelineId,
|
||||
viewport_size: webrender_api::units::LayoutSize,
|
||||
) -> IsContentful {
|
||||
let containing_block = geom::physical::Rect {
|
||||
top_left: geom::physical::Vec2 {
|
||||
x: Length::zero(),
|
||||
y: Length::zero(),
|
||||
},
|
||||
size: geom::physical::Vec2 {
|
||||
x: Length::new(viewport_size.width),
|
||||
y: Length::new(viewport_size.height),
|
||||
},
|
||||
};
|
||||
let mut is_contentful = IsContentful(false);
|
||||
for fragment in &self.0 {
|
||||
fragment.build_display_list(builder, &mut is_contentful, &containing_block)
|
||||
}
|
||||
is_contentful
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use crate::style_ext::{Direction, WritingMode};
|
||||
use std::fmt;
|
||||
use std::ops::{Add, AddAssign, Sub};
|
||||
use style::values::computed::{Length, LengthOrAuto, LengthPercentage, LengthPercentageOrAuto};
|
||||
use style::Zero;
|
||||
|
@ -13,7 +14,7 @@ pub type Size<U> = euclid::Size2D<f32, U>;
|
|||
pub type Rect<U> = euclid::Rect<f32, U>;
|
||||
|
||||
pub(crate) mod physical {
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct Vec2<T> {
|
||||
pub x: T,
|
||||
pub y: T,
|
||||
|
@ -35,7 +36,7 @@ pub(crate) mod physical {
|
|||
}
|
||||
|
||||
pub(crate) mod flow_relative {
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct Vec2<T> {
|
||||
pub inline: T,
|
||||
pub block: T,
|
||||
|
@ -56,6 +57,28 @@ pub(crate) mod flow_relative {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: fmt::Debug> fmt::Debug for physical::Vec2<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
// Not using f.debug_struct on purpose here, to keep {:?} output somewhat compact
|
||||
f.write_str("Vec2 { x: ")?;
|
||||
self.x.fmt(f)?;
|
||||
f.write_str(", y: ")?;
|
||||
self.y.fmt(f)?;
|
||||
f.write_str(" }")
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: fmt::Debug> fmt::Debug for flow_relative::Vec2<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
// Not using f.debug_struct on purpose here, to keep {:?} output somewhat compact
|
||||
f.write_str("Vec2 { i: ")?;
|
||||
self.inline.fmt(f)?;
|
||||
f.write_str(", b: ")?;
|
||||
self.block.fmt(f)?;
|
||||
f.write_str(" }")
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Add<&'_ physical::Vec2<T>> for &'_ physical::Vec2<T>
|
||||
where
|
||||
T: Add<Output = T> + Copy,
|
||||
|
@ -332,3 +355,12 @@ impl From<physical::Rect<Length>> for Rect<CSSPixel> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<physical::Rect<Length>> for webrender_api::units::LayoutRect {
|
||||
fn from(r: physical::Rect<Length>) -> Self {
|
||||
Rect {
|
||||
origin: Point::new(r.top_left.x.px(), r.top_left.y.px()),
|
||||
size: Size::new(r.size.x.px(), r.size.y.px()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ use style::Zero;
|
|||
|
||||
pub mod context;
|
||||
pub mod data;
|
||||
pub mod display_list;
|
||||
mod dom_traversal;
|
||||
mod element_data;
|
||||
mod flow;
|
||||
|
@ -30,18 +31,17 @@ mod style_ext;
|
|||
pub mod traversal;
|
||||
pub mod wrapper;
|
||||
|
||||
pub use flow::BoxTreeRoot;
|
||||
pub use flow::{BoxTreeRoot, FragmentTreeRoot};
|
||||
|
||||
use crate::dom_traversal::{Contents, NodeExt};
|
||||
use crate::flow::{BlockFormattingContext, FlowChildren};
|
||||
use crate::geom::flow_relative::Vec2;
|
||||
use crate::positioned::AbsolutelyPositionedFragment;
|
||||
use crate::replaced::ReplacedContent;
|
||||
use crate::style_ext::{ComputedValuesExt, Direction, Position, WritingMode};
|
||||
use crate::style_ext::{ComputedValuesExt, Direction, DisplayInside, Position, WritingMode};
|
||||
use servo_arc::Arc;
|
||||
use std::convert::TryInto;
|
||||
use style::context::SharedStyleContext;
|
||||
use style::values::specified::box_::DisplayInside;
|
||||
|
||||
/// https://drafts.csswg.org/css-display/#independent-formatting-context
|
||||
#[derive(Debug)]
|
||||
|
@ -73,7 +73,6 @@ impl IndependentFormattingContext {
|
|||
non_replaced,
|
||||
))
|
||||
},
|
||||
DisplayInside::None | DisplayInside::Contents => panic!(":("),
|
||||
},
|
||||
Err(replaced) => IndependentFormattingContext::Replaced(replaced),
|
||||
}
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
|
||||
use crate::geom::{flow_relative, physical};
|
||||
use style::properties::ComputedValues;
|
||||
use style::values::computed::{
|
||||
Display as PackedDisplay, Length, LengthPercentage, LengthPercentageOrAuto, Size,
|
||||
};
|
||||
use style::values::computed::{Length, LengthPercentage, LengthPercentageOrAuto, Size};
|
||||
use style::values::specified::box_ as stylo;
|
||||
|
||||
pub use style::computed_values::direction::T as Direction;
|
||||
pub use style::computed_values::position::T as Position;
|
||||
pub use style::computed_values::writing_mode::T as WritingMode;
|
||||
pub use style::values::specified::box_::{DisplayInside, DisplayOutside};
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||
pub(crate) enum Display {
|
||||
|
@ -31,6 +29,18 @@ pub(crate) enum DisplayGeneratingBox {
|
|||
// https://drafts.csswg.org/css-display-3/#layout-specific-display
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||
pub(crate) enum DisplayOutside {
|
||||
Block,
|
||||
Inline,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||
pub(crate) enum DisplayInside {
|
||||
Flow,
|
||||
FlowRoot,
|
||||
}
|
||||
|
||||
pub(crate) trait ComputedValuesExt {
|
||||
fn writing_mode(&self) -> (WritingMode, Direction);
|
||||
fn box_offsets(&self) -> flow_relative::Sides<LengthPercentageOrAuto>;
|
||||
|
@ -105,18 +115,27 @@ impl ComputedValuesExt for ComputedValues {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<PackedDisplay> for Display {
|
||||
fn from(packed_display: PackedDisplay) -> Self {
|
||||
if packed_display == PackedDisplay::None {
|
||||
return Self::None;
|
||||
}
|
||||
if packed_display == PackedDisplay::Contents {
|
||||
return Self::Contents;
|
||||
}
|
||||
Self::GeneratingBox(DisplayGeneratingBox::OutsideInside {
|
||||
outside: packed_display.outside(),
|
||||
inside: packed_display.inside(),
|
||||
// list_item: packed_display.is_list_item(),
|
||||
impl From<stylo::Display> for Display {
|
||||
fn from(packed: stylo::Display) -> Self {
|
||||
let inside = match packed.inside() {
|
||||
stylo::DisplayInside::Flow => DisplayInside::Flow,
|
||||
stylo::DisplayInside::FlowRoot => DisplayInside::FlowRoot,
|
||||
|
||||
// These should not be values of DisplayInside, but oh well
|
||||
stylo::DisplayInside::None => return Display::None,
|
||||
stylo::DisplayInside::Contents => return Display::Contents,
|
||||
};
|
||||
let outside = match packed.outside() {
|
||||
stylo::DisplayOutside::Block => DisplayOutside::Block,
|
||||
stylo::DisplayOutside::Inline => DisplayOutside::Inline,
|
||||
|
||||
// This should not be a value of DisplayInside, but oh well
|
||||
stylo::DisplayOutside::None => return Display::None,
|
||||
};
|
||||
Display::GeneratingBox(DisplayGeneratingBox::OutsideInside {
|
||||
outside,
|
||||
inside,
|
||||
// list_item: packed.is_list_item(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ use gfx_traits::{node_id_from_scroll_id, Epoch};
|
|||
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||
use ipc_channel::router::ROUTER;
|
||||
use layout::context::LayoutContext;
|
||||
use layout::display_list::DisplayListBuilder;
|
||||
use layout::query::{
|
||||
process_content_box_request, process_content_boxes_request, LayoutRPCImpl, LayoutThreadData,
|
||||
};
|
||||
|
@ -167,8 +168,11 @@ pub struct LayoutThread {
|
|||
/// The number of Web fonts that have been requested but not yet loaded.
|
||||
outstanding_web_fonts: Arc<AtomicUsize>,
|
||||
|
||||
/// The root box tree.
|
||||
box_tree_root: RefCell<Option<BoxTreeRoot>>,
|
||||
/// The root of the box tree.
|
||||
box_tree_root: RefCell<Option<layout::BoxTreeRoot>>,
|
||||
|
||||
/// The root of the fragment tree.
|
||||
fragment_tree_root: RefCell<Option<layout::FragmentTreeRoot>>,
|
||||
|
||||
/// The document-specific shared lock used for author-origin stylesheets
|
||||
document_shared_lock: Option<SharedRwLock>,
|
||||
|
@ -497,6 +501,7 @@ impl LayoutThread {
|
|||
_new_animations_receiver: new_animations_receiver,
|
||||
outstanding_web_fonts: Arc::new(AtomicUsize::new(0)),
|
||||
box_tree_root: Default::default(),
|
||||
fragment_tree_root: Default::default(),
|
||||
document_shared_lock: None,
|
||||
epoch: Cell::new(Epoch(0)),
|
||||
viewport_size: Size2D::new(Au(0), Au(0)),
|
||||
|
@ -1084,7 +1089,12 @@ impl LayoutThread {
|
|||
let shared = DomTraversal::<ServoLayoutElement>::shared_context(&traversal);
|
||||
let box_tree =
|
||||
BoxTreeRoot::construct(shared, document.root_element().unwrap().as_node());
|
||||
let fragment_tree = box_tree.layout(Size2D::new(
|
||||
self.viewport_size.width.to_f32_px(),
|
||||
self.viewport_size.height.to_f32_px(),
|
||||
));
|
||||
*self.box_tree_root.borrow_mut() = Some(box_tree);
|
||||
*self.fragment_tree_root.borrow_mut() = Some(fragment_tree);
|
||||
}
|
||||
|
||||
for element in elements_with_snapshot {
|
||||
|
@ -1099,7 +1109,9 @@ impl LayoutThread {
|
|||
}
|
||||
|
||||
// Perform post-style recalculation layout passes.
|
||||
self.perform_post_style_recalc_layout_passes(&data.reflow_goal, Some(&document));
|
||||
if let Some(root) = &*self.fragment_tree_root.borrow() {
|
||||
self.perform_post_style_recalc_layout_passes(root, &data.reflow_goal, Some(&document));
|
||||
}
|
||||
|
||||
self.first_reflow.set(false);
|
||||
self.respond_to_query_if_necessary(&data.reflow_goal, &mut *rw_data, &mut layout_context);
|
||||
|
@ -1221,7 +1233,10 @@ impl LayoutThread {
|
|||
);
|
||||
}
|
||||
|
||||
if let Some(author_shared_lock) = self.document_shared_lock.clone() {
|
||||
if let Some(root) = &*self.fragment_tree_root.borrow() {
|
||||
// Unwrap here should not panic since self.fragment_tree_root is only ever set to Some(_)
|
||||
// in handle_reflow() where self.document_shared_lock is as well.
|
||||
let author_shared_lock = self.document_shared_lock.clone().unwrap();
|
||||
let author_guard = author_shared_lock.read();
|
||||
let ua_or_user_guard = UA_STYLESHEETS.shared_lock.read();
|
||||
let _guards = StylesheetGuards {
|
||||
|
@ -1229,12 +1244,13 @@ impl LayoutThread {
|
|||
ua_or_user: &ua_or_user_guard,
|
||||
};
|
||||
|
||||
self.perform_post_style_recalc_layout_passes(&ReflowGoal::TickAnimations, None);
|
||||
self.perform_post_style_recalc_layout_passes(root, &ReflowGoal::TickAnimations, None);
|
||||
}
|
||||
}
|
||||
|
||||
fn perform_post_style_recalc_layout_passes(
|
||||
&self,
|
||||
fragment_tree: &layout::FragmentTreeRoot,
|
||||
reflow_goal: &ReflowGoal,
|
||||
document: Option<&ServoLayoutDocument>,
|
||||
) {
|
||||
|
@ -1252,16 +1268,13 @@ impl LayoutThread {
|
|||
document.will_paint();
|
||||
}
|
||||
|
||||
let viewport_size = Size2D::new(
|
||||
let viewport_size = webrender_api::units::LayoutSize::from_untyped(Size2D::new(
|
||||
self.viewport_size.width.to_f32_px(),
|
||||
self.viewport_size.height.to_f32_px(),
|
||||
);
|
||||
|
||||
let viewport_size = webrender_api::units::LayoutSize::from_untyped(viewport_size);
|
||||
|
||||
let display_list =
|
||||
webrender_api::DisplayListBuilder::new(self.id.to_webrender(), viewport_size);
|
||||
let is_contentful = false;
|
||||
));
|
||||
let mut display_list = DisplayListBuilder::new(self.id.to_webrender(), viewport_size);
|
||||
let is_contentful =
|
||||
fragment_tree.build_display_list(&mut display_list, self.id, viewport_size);
|
||||
|
||||
debug!("Layout done!");
|
||||
|
||||
|
@ -1273,14 +1286,14 @@ impl LayoutThread {
|
|||
// sending the display list to WebRender in order to set time related
|
||||
// Progressive Web Metrics.
|
||||
self.paint_time_metrics
|
||||
.maybe_observe_paint_time(self, epoch, is_contentful);
|
||||
.maybe_observe_paint_time(self, epoch, is_contentful.0);
|
||||
|
||||
let mut txn = webrender_api::Transaction::new();
|
||||
txn.set_display_list(
|
||||
webrender_api::Epoch(epoch.0),
|
||||
None,
|
||||
viewport_size,
|
||||
display_list.finalize(),
|
||||
display_list.wr.finalize(),
|
||||
true,
|
||||
);
|
||||
txn.generate_frame();
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
"border-%s-color" % side_name, "Color",
|
||||
"computed_value::T::currentcolor()",
|
||||
engines="gecko servo-2013 servo-2020",
|
||||
servo_2020_pref="layout.2020.unimplemented",
|
||||
alias=maybe_moz_logical_alias(engine, side, "-moz-border-%s-color"),
|
||||
spec=maybe_logical_spec(side, "color"),
|
||||
animation_value_type="AnimatedColor",
|
||||
|
@ -51,7 +50,6 @@
|
|||
"BorderSideWidth",
|
||||
"crate::values::computed::NonNegativeLength::new(3.)",
|
||||
engines="gecko servo-2013 servo-2020",
|
||||
servo_2020_pref="layout.2020.unimplemented",
|
||||
computed_type="crate::values::computed::NonNegativeLength",
|
||||
alias=maybe_moz_logical_alias(engine, side, "-moz-border-%s-width"),
|
||||
spec=maybe_logical_spec(side, "width"),
|
||||
|
|
|
@ -63,7 +63,6 @@ ${helpers.predefined_type(
|
|||
"Float",
|
||||
"computed::Float::None",
|
||||
engines="gecko servo-2013 servo-2020",
|
||||
servo_2020_pref="layout.2020.unimplemented",
|
||||
initial_specified_value="specified::Float::None",
|
||||
spec="https://drafts.csswg.org/css-box/#propdef-float",
|
||||
animation_value_type="discrete",
|
||||
|
|
|
@ -29,6 +29,7 @@ ${helpers.single_keyword(
|
|||
rl=horizontal-tb rl-tb=horizontal-tb \
|
||||
tb=vertical-rl tb-rl=vertical-rl",
|
||||
servo_2013_pref="layout.writing-mode.enabled",
|
||||
servo_2020_pref="layout.writing-mode.enabled",
|
||||
animation_value_type="none",
|
||||
spec="https://drafts.csswg.org/css-writing-modes/#propdef-writing-mode",
|
||||
servo_restyle_damage="rebuild_and_reflow",
|
||||
|
@ -38,6 +39,7 @@ ${helpers.single_keyword(
|
|||
"direction",
|
||||
"ltr rtl",
|
||||
engines="gecko servo-2013 servo-2020",
|
||||
servo_2020_pref="layout.2020.unimplemented",
|
||||
animation_value_type="none",
|
||||
spec="https://drafts.csswg.org/css-writing-modes/#propdef-direction",
|
||||
needs_conversion=True,
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
"LengthPercentageOrAuto",
|
||||
"computed::LengthPercentageOrAuto::zero()",
|
||||
engines="gecko servo-2013 servo-2020",
|
||||
servo_2020_pref="layout.2020.unimplemented",
|
||||
alias=maybe_moz_logical_alias(engine, side, "-moz-margin-%s"),
|
||||
allow_quirks="No" if side[1] else "Yes",
|
||||
animation_value_type="ComputedValue",
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
"NonNegativeLengthPercentage",
|
||||
"computed::NonNegativeLengthPercentage::zero()",
|
||||
engines="gecko servo-2013 servo-2020",
|
||||
servo_2020_pref="layout.2020.unimplemented",
|
||||
alias=maybe_moz_logical_alias(engine, side, "-moz-padding-%s"),
|
||||
animation_value_type="NonNegativeLengthPercentage",
|
||||
logical=side[1],
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
"LengthPercentageOrAuto",
|
||||
"computed::LengthPercentageOrAuto::auto()",
|
||||
engines="gecko servo-2013 servo-2020",
|
||||
servo_2020_pref="layout.2020.unimplemented",
|
||||
spec="https://www.w3.org/TR/CSS2/visuren.html#propdef-%s" % side,
|
||||
animation_value_type="ComputedValue",
|
||||
allow_quirks="Yes",
|
||||
|
@ -30,7 +29,6 @@
|
|||
"LengthPercentageOrAuto",
|
||||
"computed::LengthPercentageOrAuto::auto()",
|
||||
engines="gecko servo-2013 servo-2020",
|
||||
servo_2020_pref="layout.2020.unimplemented",
|
||||
spec="https://drafts.csswg.org/css-logical-props/#propdef-inset-%s" % side,
|
||||
alias="offset-%s:layout.css.offset-logical-properties.enabled" % side,
|
||||
animation_value_type="ComputedValue",
|
||||
|
@ -278,7 +276,6 @@ ${helpers.predefined_type(
|
|||
"Size",
|
||||
"computed::Size::auto()",
|
||||
engines="gecko servo-2013 servo-2020",
|
||||
servo_2020_pref="layout.2020.unimplemented",
|
||||
logical=logical,
|
||||
logical_group="size",
|
||||
allow_quirks="No" if logical else "Yes",
|
||||
|
|
|
@ -9,7 +9,7 @@ ${helpers.four_sides_shorthand(
|
|||
"border-color",
|
||||
"border-%s-color",
|
||||
"specified::Color::parse",
|
||||
engines="gecko servo-2013",
|
||||
engines="gecko servo-2013 servo-2020",
|
||||
spec="https://drafts.csswg.org/css-backgrounds/#border-color",
|
||||
allow_quirks="Yes",
|
||||
)}
|
||||
|
@ -18,14 +18,14 @@ ${helpers.four_sides_shorthand(
|
|||
"border-style",
|
||||
"border-%s-style",
|
||||
"specified::BorderStyle::parse",
|
||||
engines="gecko servo-2013",
|
||||
engines="gecko servo-2013 servo-2020",
|
||||
needs_context=False,
|
||||
spec="https://drafts.csswg.org/css-backgrounds/#border-style",
|
||||
)}
|
||||
|
||||
<%helpers:shorthand
|
||||
name="border-width"
|
||||
engines="gecko servo-2013"
|
||||
engines="gecko servo-2013 servo-2020"
|
||||
sub_properties="${
|
||||
' '.join('border-%s-width' % side
|
||||
for side in PHYSICAL_SIDES)}"
|
||||
|
|
|
@ -8,7 +8,7 @@ ${helpers.four_sides_shorthand(
|
|||
"margin",
|
||||
"margin-%s",
|
||||
"specified::LengthPercentageOrAuto::parse",
|
||||
engines="gecko servo-2013",
|
||||
engines="gecko servo-2013 servo-2020",
|
||||
spec="https://drafts.csswg.org/css-box/#propdef-margin",
|
||||
allowed_in_page_rule=True,
|
||||
allow_quirks="Yes",
|
||||
|
@ -19,7 +19,7 @@ ${helpers.two_properties_shorthand(
|
|||
"margin-block-start",
|
||||
"margin-block-end",
|
||||
"specified::LengthPercentageOrAuto::parse",
|
||||
engines="gecko servo-2013",
|
||||
engines="gecko servo-2013 servo-2020",
|
||||
spec="https://drafts.csswg.org/css-logical/#propdef-margin-block"
|
||||
)}
|
||||
|
||||
|
@ -28,7 +28,7 @@ ${helpers.two_properties_shorthand(
|
|||
"margin-inline-start",
|
||||
"margin-inline-end",
|
||||
"specified::LengthPercentageOrAuto::parse",
|
||||
engines="gecko servo-2013",
|
||||
engines="gecko servo-2013 servo-2020",
|
||||
spec="https://drafts.csswg.org/css-logical/#propdef-margin-inline"
|
||||
)}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ ${helpers.four_sides_shorthand(
|
|||
"padding",
|
||||
"padding-%s",
|
||||
"specified::NonNegativeLengthPercentage::parse",
|
||||
engines="gecko servo-2013",
|
||||
engines="gecko servo-2013 servo-2020",
|
||||
spec="https://drafts.csswg.org/css-box-3/#propdef-padding",
|
||||
allow_quirks="Yes",
|
||||
)}
|
||||
|
@ -18,7 +18,7 @@ ${helpers.two_properties_shorthand(
|
|||
"padding-block-start",
|
||||
"padding-block-end",
|
||||
"specified::NonNegativeLengthPercentage::parse",
|
||||
engines="gecko servo-2013",
|
||||
engines="gecko servo-2013 servo-2020",
|
||||
spec="https://drafts.csswg.org/css-logical/#propdef-padding-block"
|
||||
)}
|
||||
|
||||
|
@ -27,7 +27,7 @@ ${helpers.two_properties_shorthand(
|
|||
"padding-inline-start",
|
||||
"padding-inline-end",
|
||||
"specified::NonNegativeLengthPercentage::parse",
|
||||
engines="gecko servo-2013",
|
||||
engines="gecko servo-2013 servo-2020",
|
||||
spec="https://drafts.csswg.org/css-logical/#propdef-padding-inline"
|
||||
)}
|
||||
|
||||
|
|
|
@ -611,7 +611,6 @@ impl Size {
|
|||
Clone,
|
||||
ComputeSquaredDistance,
|
||||
Copy,
|
||||
Debug,
|
||||
MallocSizeOf,
|
||||
PartialEq,
|
||||
PartialOrd,
|
||||
|
@ -623,6 +622,13 @@ impl Size {
|
|||
#[repr(C)]
|
||||
pub struct CSSPixelLength(CSSFloat);
|
||||
|
||||
impl fmt::Debug for CSSPixelLength {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.0.fmt(f)?;
|
||||
f.write_str(" px")
|
||||
}
|
||||
}
|
||||
|
||||
impl CSSPixelLength {
|
||||
/// Return a new CSSPixelLength.
|
||||
#[inline]
|
||||
|
|
|
@ -619,7 +619,7 @@ impl Parse for Display {
|
|||
// Now parse the single-keyword `display` values.
|
||||
Ok(try_match_ident_ignore_ascii_case! { input,
|
||||
"none" => Display::None,
|
||||
#[cfg(feature = "gecko")]
|
||||
#[cfg(any(feature = "servo-layout-2020", feature = "gecko"))]
|
||||
"contents" => Display::Contents,
|
||||
"inline-block" => Display::InlineBlock,
|
||||
#[cfg(any(feature = "servo-layout-2013", feature = "gecko"))]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue