aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock69
-rw-r--r--components/fallible/Cargo.toml2
-rw-r--r--components/gfx/font.rs2
-rw-r--r--components/gfx/font_context.rs2
-rw-r--r--components/layout/block.rs31
-rw-r--r--components/layout/display_list/background.rs4
-rw-r--r--components/layout/display_list/border.rs20
-rw-r--r--components/layout/display_list/builder.rs4
-rw-r--r--components/layout/display_list/gradient.rs47
-rw-r--r--components/layout/flex.rs18
-rw-r--r--components/layout/flow.rs16
-rw-r--r--components/layout/fragment.rs73
-rw-r--r--components/layout/inline.rs6
-rw-r--r--components/layout/lib.rs1
-rw-r--r--components/layout/model.rs16
-rw-r--r--components/layout/multicol.rs8
-rw-r--r--components/layout/table_colgroup.rs2
-rw-r--r--components/layout/table_row.rs12
-rw-r--r--components/layout/text.rs2
-rw-r--r--components/layout_2020/geom.rs19
-rw-r--r--components/layout_2020/positioned.rs22
-rw-r--r--components/layout_2020/sizing.rs10
-rw-r--r--components/layout_2020/style_ext.rs50
-rw-r--r--components/malloc_size_of/Cargo.toml2
-rw-r--r--components/selectors/Cargo.toml4
-rw-r--r--components/selectors/builder.rs14
-rw-r--r--components/selectors/parser.rs8
-rw-r--r--components/style/Cargo.toml4
-rw-r--r--components/style/bloom.rs6
-rw-r--r--components/style/dom.rs36
-rw-r--r--components/style/font_metrics.rs10
-rw-r--r--components/style/gecko/media_queries.rs7
-rw-r--r--components/style/gecko/non_ts_pseudo_class_list.rs4
-rw-r--r--components/style/gecko/pseudo_element_definition.mako.rs8
-rw-r--r--components/style/gecko/selector_parser.rs22
-rw-r--r--components/style/gecko/snapshot.rs2
-rw-r--r--components/style/gecko/wrapper.rs18
-rw-r--r--components/style/gecko_bindings/sugar/ns_t_array.rs9
-rw-r--r--components/style/invalidation/element/invalidation_map.rs54
-rw-r--r--components/style/invalidation/element/invalidator.rs2
-rw-r--r--components/style/invalidation/element/state_and_attributes.rs16
-rw-r--r--components/style/logical_geometry.rs18
-rw-r--r--components/style/matching.rs2
-rw-r--r--components/style/parallel.rs4
-rw-r--r--components/style/properties/cascade.rs3
-rw-r--r--components/style/properties/counted_unknown_properties.py4
-rw-r--r--components/style/properties/data.py1
-rw-r--r--components/style/properties/declaration_block.rs2
-rw-r--r--components/style/properties/gecko.mako.rs22
-rw-r--r--components/style/properties/longhands/border.mako.rs5
-rw-r--r--components/style/properties/longhands/box.mako.rs3
-rw-r--r--components/style/properties/longhands/inherited_box.mako.rs1
-rw-r--r--components/style/properties/longhands/inherited_text.mako.rs16
-rw-r--r--components/style/properties/longhands/inherited_ui.mako.rs1
-rw-r--r--components/style/properties/properties.mako.rs56
-rw-r--r--components/style/properties/shorthands/border.mako.rs10
-rw-r--r--components/style/rule_collector.rs5
-rw-r--r--components/style/rule_tree/mod.rs14
-rw-r--r--components/style/servo/media_queries.rs4
-rw-r--r--components/style/servo/selector_parser.rs5
-rw-r--r--components/style/stylesheets/mod.rs1
-rw-r--r--components/style/stylesheets/namespace_rule.rs14
-rw-r--r--components/style/stylesheets/stylesheet.rs88
-rw-r--r--components/style/stylist.rs17
-rw-r--r--components/style/values/animated/transform.rs2
-rw-r--r--components/style/values/computed/font.rs8
-rw-r--r--components/style/values/computed/length.rs10
-rw-r--r--components/style/values/computed/mod.rs1
-rw-r--r--components/style/values/computed/text.rs1
-rw-r--r--components/style/values/generics/length.rs9
-rw-r--r--components/style/values/specified/align.rs6
-rw-r--r--components/style/values/specified/box.rs17
-rw-r--r--components/style/values/specified/font.rs39
-rw-r--r--components/style/values/specified/gecko.rs5
-rw-r--r--components/style/values/specified/length.rs43
-rw-r--r--components/style/values/specified/mod.rs1
-rw-r--r--components/style/values/specified/text.rs108
-rw-r--r--components/to_shmem/Cargo.toml2
-rw-r--r--servo-tidy.toml6
-rw-r--r--tests/wpt/metadata/css/cssom/border-shorthand-serialization.html.ini4
80 files changed, 770 insertions, 450 deletions
diff --git a/Cargo.lock b/Cargo.lock
index f8bcf052113..ac076d7dca6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -887,7 +887,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f0ed1a4de2235cabda8558ff5840bffb97fcb64c97827f354a451307df5f72b"
dependencies = [
"crossbeam-utils",
- "smallvec",
+ "smallvec 0.6.10",
]
[[package]]
@@ -947,7 +947,7 @@ dependencies = [
"proc-macro2 1.0.1",
"quote 1.0.2",
"serde",
- "smallvec",
+ "smallvec 0.6.10",
"syn 1.0.3",
]
@@ -1103,6 +1103,17 @@ dependencies = [
]
[[package]]
+name = "derive_more"
+version = "0.99.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2159be042979966de68315bce7034bb000c775f22e3e834e1c52ff78f041cae8"
+dependencies = [
+ "proc-macro2 1.0.1",
+ "quote 1.0.2",
+ "syn 1.0.3",
+]
+
+[[package]]
name = "device"
version = "0.0.1"
source = "git+https://github.com/servo/devices#cb28c4725ffbfece99dab842d17d3e8c50774778"
@@ -1387,7 +1398,7 @@ name = "fallible"
version = "0.0.1"
dependencies = [
"hashglobe",
- "smallvec",
+ "smallvec 1.0.0",
]
[[package]]
@@ -1609,7 +1620,7 @@ dependencies = [
"servo_arc",
"servo_atoms",
"servo_url",
- "smallvec",
+ "smallvec 0.6.10",
"style",
"time",
"truetype",
@@ -1646,7 +1657,7 @@ dependencies = [
"parking_lot",
"range-alloc",
"raw-window-handle",
- "smallvec",
+ "smallvec 0.6.10",
"spirv_cross",
"winapi",
"wio",
@@ -1665,7 +1676,7 @@ dependencies = [
"log",
"range-alloc",
"raw-window-handle",
- "smallvec",
+ "smallvec 0.6.10",
"spirv_cross",
"winapi",
]
@@ -1702,7 +1713,7 @@ dependencies = [
"parking_lot",
"range-alloc",
"raw-window-handle",
- "smallvec",
+ "smallvec 0.6.10",
"spirv_cross",
"storage-map",
]
@@ -1722,7 +1733,7 @@ dependencies = [
"log",
"objc",
"raw-window-handle",
- "smallvec",
+ "smallvec 0.6.10",
"winapi",
"x11",
]
@@ -1735,7 +1746,7 @@ checksum = "7c88981665c780447bb08eb099e1ded330754a7246719bab927ee4a949c0ba7f"
dependencies = [
"bitflags",
"raw-window-handle",
- "smallvec",
+ "smallvec 0.6.10",
]
[[package]]
@@ -2706,7 +2717,7 @@ dependencies = [
"servo_geometry",
"servo_url",
"size_of_test",
- "smallvec",
+ "smallvec 0.6.10",
"style",
"style_traits",
"unicode-bidi",
@@ -2938,7 +2949,7 @@ dependencies = [
"rust-webvr",
"servo-egl",
"simpleservo",
- "smallvec",
+ "smallvec 0.6.10",
"webxr",
"webxr-api",
]
@@ -3137,7 +3148,7 @@ dependencies = [
"serde_bytes",
"servo_arc",
"smallbitvec",
- "smallvec",
+ "smallvec 1.0.0",
"string_cache",
"thin-slice",
"time",
@@ -3812,7 +3823,7 @@ dependencies = [
"libc",
"redox_syscall",
"rustc_version",
- "smallvec",
+ "smallvec 0.6.10",
"winapi",
]
@@ -4307,7 +4318,7 @@ dependencies = [
"gfx-hal",
"log",
"relevant",
- "smallvec",
+ "smallvec 0.6.10",
]
[[package]]
@@ -4322,7 +4333,7 @@ dependencies = [
"log",
"relevant",
"slab",
- "smallvec",
+ "smallvec 0.6.10",
]
[[package]]
@@ -4514,7 +4525,7 @@ dependencies = [
"servo_geometry",
"servo_rand",
"servo_url",
- "smallvec",
+ "smallvec 0.6.10",
"sparkle",
"style",
"style_traits",
@@ -4633,7 +4644,7 @@ version = "0.21.0"
dependencies = [
"bitflags",
"cssparser",
- "derive_more",
+ "derive_more 0.99.2",
"fxhash",
"log",
"matches",
@@ -4641,7 +4652,7 @@ dependencies = [
"phf_codegen",
"precomputed-hash",
"servo_arc",
- "smallvec",
+ "smallvec 1.0.0",
"thin-slice",
"to_shmem",
"to_shmem_derive",
@@ -4836,7 +4847,7 @@ dependencies = [
"servo-media-player",
"servo-media-traits",
"servo_media_derive",
- "smallvec",
+ "smallvec 0.6.10",
]
[[package]]
@@ -5224,6 +5235,12 @@ dependencies = [
]
[[package]]
+name = "smallvec"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86"
+
+[[package]]
name = "smithay-client-toolkit"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5351,7 +5368,7 @@ dependencies = [
"byteorder",
"crossbeam-channel",
"cssparser",
- "derive_more",
+ "derive_more 0.99.2",
"encoding_rs",
"euclid",
"fallible",
@@ -5384,7 +5401,7 @@ dependencies = [
"servo_config",
"servo_url",
"smallbitvec",
- "smallvec",
+ "smallvec 1.0.0",
"string_cache",
"style_derive",
"style_traits",
@@ -5689,7 +5706,7 @@ dependencies = [
"cssparser",
"servo_arc",
"smallbitvec",
- "smallvec",
+ "smallvec 1.0.0",
"string_cache",
"thin-slice",
]
@@ -6279,7 +6296,7 @@ dependencies = [
"malloc_size_of",
"serde",
"servo_config",
- "smallvec",
+ "smallvec 0.6.10",
"wgpu-core",
]
@@ -6314,7 +6331,7 @@ dependencies = [
"serde",
"serde_json",
"sha2",
- "smallvec",
+ "smallvec 0.6.10",
"svg_fmt",
"thread_profiler",
"time",
@@ -6334,7 +6351,7 @@ dependencies = [
"byteorder",
"core-foundation",
"core-graphics",
- "derive_more",
+ "derive_more 0.13.0",
"euclid",
"malloc_size_of_derive",
"peek-poke",
@@ -6443,7 +6460,7 @@ dependencies = [
"rendy-descriptor",
"rendy-memory",
"serde",
- "smallvec",
+ "smallvec 0.6.10",
"vec_map",
]
diff --git a/components/fallible/Cargo.toml b/components/fallible/Cargo.toml
index e8f5314693b..49064da33ea 100644
--- a/components/fallible/Cargo.toml
+++ b/components/fallible/Cargo.toml
@@ -10,7 +10,7 @@ name = "fallible"
path = "lib.rs"
[dependencies]
-smallvec = "0.6"
+smallvec = "1.0"
hashglobe = { path = "../hashglobe" }
# This crate effectively does nothing except if the `known_system_malloc`
diff --git a/components/gfx/font.rs b/components/gfx/font.rs
index 3dd5ac9f244..439784ba680 100644
--- a/components/gfx/font.rs
+++ b/components/gfx/font.rs
@@ -131,7 +131,7 @@ impl<'a> From<&'a FontStyleStruct> for FontDescriptor {
FontDescriptor {
template_descriptor: FontTemplateDescriptor::from(style),
variant: style.font_variant_caps,
- pt_size: style.font_size.size(),
+ pt_size: Au::from_f32_px(style.font_size.size().px()),
}
}
}
diff --git a/components/gfx/font_context.rs b/components/gfx/font_context.rs
index 06755205935..113b384f84d 100644
--- a/components/gfx/font_context.rs
+++ b/components/gfx/font_context.rs
@@ -95,7 +95,7 @@ impl<S: FontSource> FontContext<S> {
self.expire_font_caches_if_necessary();
let cache_key = FontGroupCacheKey {
- size: style.font_size.size(),
+ size: Au::from_f32_px(style.font_size.size().px()),
style,
};
diff --git a/components/layout/block.rs b/components/layout/block.rs
index 80c0fae2243..4b0999489ee 100644
--- a/components/layout/block.rs
+++ b/components/layout/block.rs
@@ -2029,7 +2029,7 @@ impl BlockFlow {
// If `max-width` is set, then don't perform this speculation. We guess that the
// page set `max-width` in order to avoid hitting floats. The search box on Google
// SERPs falls into this category.
- if self.fragment.style.max_inline_size() != MaxSize::None {
+ if !matches!(self.fragment.style.max_inline_size(), MaxSize::None) {
return;
}
@@ -2548,8 +2548,16 @@ impl Flow for BlockFlow {
.base
.flags
.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) &&
- self.fragment.style().logical_position().inline_start == LengthPercentageOrAuto::Auto &&
- self.fragment.style().logical_position().inline_end == LengthPercentageOrAuto::Auto
+ self.fragment
+ .style()
+ .logical_position()
+ .inline_start
+ .is_auto() &&
+ self.fragment
+ .style()
+ .logical_position()
+ .inline_end
+ .is_auto()
{
self.base.position.start.i = inline_position
}
@@ -2560,8 +2568,12 @@ impl Flow for BlockFlow {
.base
.flags
.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) &&
- self.fragment.style().logical_position().block_start == LengthPercentageOrAuto::Auto &&
- self.fragment.style().logical_position().block_end == LengthPercentageOrAuto::Auto
+ self.fragment
+ .style()
+ .logical_position()
+ .block_start
+ .is_auto() &&
+ self.fragment.style().logical_position().block_end.is_auto()
{
self.base.position.start.b = block_position
}
@@ -2848,16 +2860,15 @@ pub trait ISizeAndMarginsComputer {
parent_flow_inline_size: Au,
shared_context: &SharedStyleContext,
) -> MaybeAuto {
+ let inline_size =
+ self.containing_block_inline_size(block, parent_flow_inline_size, shared_context);
+
MaybeAuto::from_option(
block
.fragment()
.style()
.content_inline_size()
- .to_used_value(self.containing_block_inline_size(
- block,
- parent_flow_inline_size,
- shared_context,
- )),
+ .to_used_value(inline_size),
)
}
diff --git a/components/layout/display_list/background.rs b/components/layout/display_list/background.rs
index 9d05cef9054..c08dcfe8598 100644
--- a/components/layout/display_list/background.rs
+++ b/components/layout/display_list/background.rs
@@ -47,7 +47,7 @@ pub fn get_cyclic<T>(arr: &[T], index: usize) -> &T {
/// For a given area and an image compute how big the
/// image should be displayed on the background.
fn compute_background_image_size(
- bg_size: BackgroundSize,
+ bg_size: &BackgroundSize,
bounds_size: Size2D<Au>,
intrinsic_size: Option<Size2D<Au>>,
) -> Size2D<Au> {
@@ -156,7 +156,7 @@ pub fn placement(
let bg_position_x = get_cyclic(&bg.background_position_x.0, index);
let bg_position_y = get_cyclic(&bg.background_position_y.0, index);
let bg_repeat = get_cyclic(&bg.background_repeat.0, index);
- let bg_size = *get_cyclic(&bg.background_size.0, index);
+ let bg_size = get_cyclic(&bg.background_size.0, index);
let (clip_rect, clip_radii) = clip(
bg_clip,
diff --git a/components/layout/display_list/border.rs b/components/layout/display_list/border.rs
index 4970b2a34de..14ca2abe84f 100644
--- a/components/layout/display_list/border.rs
+++ b/components/layout/display_list/border.rs
@@ -25,7 +25,7 @@ use webrender_api::{BorderRadius, BorderSide, BorderStyle, ColorF, NormalBorder}
///
/// [1]: https://drafts.csswg.org/css-backgrounds-3/#border-radius
fn corner_radius(
- radius: BorderCornerRadius,
+ radius: &BorderCornerRadius,
containing_size: UntypedSize2D<Au>,
) -> UntypedSize2D<Au> {
let w = radius.0.width().to_used_value(containing_size.width);
@@ -91,13 +91,13 @@ pub fn radii(abs_bounds: Rect<Au>, border_style: &Border) -> BorderRadius {
overlapping_radii(
abs_bounds.size.to_layout(),
BorderRadius {
- top_left: corner_radius(border_style.border_top_left_radius, abs_bounds.size)
+ top_left: corner_radius(&border_style.border_top_left_radius, abs_bounds.size)
.to_layout(),
- top_right: corner_radius(border_style.border_top_right_radius, abs_bounds.size)
+ top_right: corner_radius(&border_style.border_top_right_radius, abs_bounds.size)
.to_layout(),
- bottom_right: corner_radius(border_style.border_bottom_right_radius, abs_bounds.size)
+ bottom_right: corner_radius(&border_style.border_bottom_right_radius, abs_bounds.size)
.to_layout(),
- bottom_left: corner_radius(border_style.border_bottom_left_radius, abs_bounds.size)
+ bottom_left: corner_radius(&border_style.border_bottom_left_radius, abs_bounds.size)
.to_layout(),
},
)
@@ -161,7 +161,7 @@ pub fn image_outset(
}
fn side_image_width(
- border_image_width: BorderImageSideWidth,
+ border_image_width: &BorderImageSideWidth,
border_width: f32,
total_length: Au,
) -> f32 {
@@ -178,10 +178,10 @@ pub fn image_width(
border_area: UntypedSize2D<Au>,
) -> LayoutSideOffsets {
LayoutSideOffsets::new(
- side_image_width(width.0, border.top, border_area.height),
- side_image_width(width.1, border.right, border_area.width),
- side_image_width(width.2, border.bottom, border_area.height),
- side_image_width(width.3, border.left, border_area.width),
+ side_image_width(&width.0, border.top, border_area.height),
+ side_image_width(&width.1, border.right, border_area.width),
+ side_image_width(&width.2, border.bottom, border_area.height),
+ side_image_width(&width.3, border.left, border_area.width),
)
}
diff --git a/components/layout/display_list/builder.rs b/components/layout/display_list/builder.rs
index 258c4f5490c..542ab95172a 100644
--- a/components/layout/display_list/builder.rs
+++ b/components/layout/display_list/builder.rs
@@ -995,7 +995,7 @@ impl Fragment {
};
DisplayItem::Gradient(CommonDisplayItem::with_data(base, item, stops))
},
- GradientKind::Radial(shape, center) => {
+ GradientKind::Radial(ref shape, ref center) => {
let (gradient, stops) = gradient::radial(
style,
placement.tile_size,
@@ -1238,7 +1238,7 @@ impl Fragment {
stops = linear_stops;
NinePatchBorderSource::Gradient(wr_gradient)
},
- GradientKind::Radial(shape, center) => {
+ GradientKind::Radial(ref shape, ref center) => {
let (wr_gradient, radial_stops) = gradient::radial(
style,
border_image_area,
diff --git a/components/layout/display_list/gradient.rs b/components/layout/display_list/gradient.rs
index 3d7730e4fe6..e683bbb963c 100644
--- a/components/layout/display_list/gradient.rs
+++ b/components/layout/display_list/gradient.rs
@@ -91,9 +91,12 @@ fn convert_gradient_stops(
color,
position: None,
}),
- GradientItem::ComplexColorStop { color, position } => Some(ColorStop {
+ GradientItem::ComplexColorStop {
color,
- position: Some(position),
+ ref position,
+ } => Some(ColorStop {
+ color,
+ position: Some(position.clone()),
}),
_ => None,
})
@@ -122,15 +125,24 @@ fn convert_gradient_stops(
// Step 2: Move any stops placed before earlier stops to the
// same position as the preceding stop.
- let mut last_stop_position = stop_items.first().unwrap().position.unwrap();
+ //
+ // FIXME(emilio): Once we know the offsets, it seems like converting the
+ // positions to absolute at once then process that would be cheaper.
+ let mut last_stop_position = stop_items
+ .first()
+ .unwrap()
+ .position
+ .as_ref()
+ .unwrap()
+ .clone();
for stop in stop_items.iter_mut().skip(1) {
- if let Some(pos) = stop.position {
- if position_to_offset(last_stop_position, total_length) >
+ if let Some(ref pos) = stop.position {
+ if position_to_offset(&last_stop_position, total_length) >
position_to_offset(pos, total_length)
{
stop.position = Some(last_stop_position);
}
- last_stop_position = stop.position.unwrap();
+ last_stop_position = stop.position.as_ref().unwrap().clone();
}
}
@@ -144,8 +156,10 @@ fn convert_gradient_stops(
// Initialize a new stop run.
// `unwrap()` here should never fail because this is the beginning of
// a stop run, which is always bounded by a length or percentage.
- let start_offset =
- position_to_offset(stop_items[i - 1].position.unwrap(), total_length);
+ let start_offset = position_to_offset(
+ stop_items[i - 1].position.as_ref().unwrap(),
+ total_length,
+ );
// `unwrap()` here should never fail because this is the end of
// a stop run, which is always bounded by a length or percentage.
let (end_index, end_stop) = stop_items[(i + 1)..]
@@ -153,7 +167,8 @@ fn convert_gradient_stops(
.enumerate()
.find(|&(_, ref stop)| stop.position.is_some())
.unwrap();
- let end_offset = position_to_offset(end_stop.position.unwrap(), total_length);
+ let end_offset =
+ position_to_offset(end_stop.position.as_ref().unwrap(), total_length);
stop_run = Some(StopRun {
start_offset,
end_offset,
@@ -168,7 +183,7 @@ fn convert_gradient_stops(
stop_run_length * (i - stop_run.start_index) as f32 /
((2 + stop_run.stop_count) as f32)
},
- Some(position) => {
+ Some(ref position) => {
stop_run = None;
position_to_offset(position, total_length)
},
@@ -212,7 +227,7 @@ where
Size2D::new(cmp(left_side, right_side), cmp(top_side, bottom_side))
}
-fn position_to_offset(position: LengthPercentage, total_length: Au) -> f32 {
+fn position_to_offset(position: &LengthPercentage, total_length: Au) -> f32 {
if total_length == Au(0) {
return 0.0;
}
@@ -289,8 +304,8 @@ pub fn radial(
style: &ComputedValues,
size: Size2D<Au>,
stops: &[GradientItem],
- shape: EndingShape,
- center: Position,
+ shape: &EndingShape,
+ center: &Position,
repeating: bool,
) -> (RadialGradient, Vec<GradientStop>) {
let center = Point2D::new(
@@ -299,15 +314,15 @@ pub fn radial(
);
let radius = match shape {
EndingShape::Circle(Circle::Radius(length)) => {
- let length = Au::from(length);
+ let length = Au::from(*length);
Size2D::new(length, length)
},
- EndingShape::Circle(Circle::Extent(extent)) => circle_size_keyword(extent, &size, &center),
+ EndingShape::Circle(Circle::Extent(extent)) => circle_size_keyword(*extent, &size, &center),
EndingShape::Ellipse(Ellipse::Radii(x, y)) => {
Size2D::new(x.to_used_value(size.width), y.to_used_value(size.height))
},
EndingShape::Ellipse(Ellipse::Extent(extent)) => {
- ellipse_size_keyword(extent, &size, &center)
+ ellipse_size_keyword(*extent, &size, &center)
},
};
diff --git a/components/layout/flex.rs b/components/layout/flex.rs
index 8d2f7b98fe1..204e87f23fc 100644
--- a/components/layout/flex.rs
+++ b/components/layout/flex.rs
@@ -43,7 +43,7 @@ enum AxisSize {
impl AxisSize {
/// Generate a new available cross or main axis size from the specified size of the container,
/// containing block size, min constraint, and max constraint
- pub fn new(size: Size, content_size: Option<Au>, min: Size, max: MaxSize) -> AxisSize {
+ pub fn new(size: &Size, content_size: Option<Au>, min: &Size, max: &MaxSize) -> AxisSize {
match size {
Size::Auto => AxisSize::MinMax(SizeConstraint::new(content_size, min, max, None)),
Size::LengthPercentage(ref lp) => match lp.maybe_to_used_value(content_size) {
@@ -58,10 +58,10 @@ impl AxisSize {
/// and the container size, then return the used value of flex basis. it can be used to help
/// determining the flex base size and to indicate whether the main size of the item
/// is definite after flex size resolving.
-fn from_flex_basis(flex_basis: FlexBasis, main_length: Size, containing_length: Au) -> MaybeAuto {
+fn from_flex_basis(flex_basis: &FlexBasis, main_length: &Size, containing_length: Au) -> MaybeAuto {
let width = match flex_basis {
FlexBasis::Content => return MaybeAuto::Auto,
- FlexBasis::Size(width) => width,
+ FlexBasis::Size(ref width) => width,
};
let width = match width {
@@ -135,7 +135,7 @@ impl FlexItem {
// https://drafts.csswg.org/css-flexbox-1/#min-size-auto
Direction::Inline => {
let basis = from_flex_basis(
- block.fragment.style.get_position().flex_basis,
+ &block.fragment.style.get_position().flex_basis,
block.fragment.style.content_inline_size(),
containing_length,
);
@@ -170,7 +170,7 @@ impl FlexItem {
},
Direction::Block => {
let basis = from_flex_basis(
- block.fragment.style.get_position().flex_basis,
+ &block.fragment.style.get_position().flex_basis,
block.fragment.style.content_block_size(),
containing_length,
);
@@ -452,7 +452,7 @@ impl FlexFlow {
fn inline_mode_bubble_inline_sizes(&mut self) {
// FIXME(emilio): This doesn't handle at all writing-modes.
let fixed_width =
- !model::style_length(self.block_flow.fragment.style().get_position().width, None)
+ !model::style_length(&self.block_flow.fragment.style().get_position().width, None)
.is_auto();
let mut computation = self.block_flow.fragment.compute_intrinsic_inline_sizes();
@@ -478,7 +478,7 @@ impl FlexFlow {
// stripped out.
fn block_mode_bubble_inline_sizes(&mut self) {
let fixed_width =
- !model::style_length(self.block_flow.fragment.style().get_position().width, None)
+ !model::style_length(&self.block_flow.fragment.style().get_position().width, None)
.is_auto();
let mut computation = self.block_flow.fragment.compute_intrinsic_inline_sizes();
@@ -960,9 +960,9 @@ impl Flow for FlexFlow {
let style = &self.block_flow.fragment.style;
let (specified_block_size, specified_inline_size) = if style.writing_mode.is_vertical()
{
- (style.get_position().width, style.get_position().height)
+ (&style.get_position().width, &style.get_position().height)
} else {
- (style.get_position().height, style.get_position().width)
+ (&style.get_position().height, &style.get_position().width)
};
let available_inline_size = AxisSize::new(
diff --git a/components/layout/flow.rs b/components/layout/flow.rs
index 2d6e449766e..c2d01b7f9f9 100644
--- a/components/layout/flow.rs
+++ b/components/layout/flow.rs
@@ -64,7 +64,6 @@ use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
use style::properties::ComputedValues;
use style::selector_parser::RestyleDamage;
use style::servo::restyle_damage::ServoRestyleDamage;
-use style::values::computed::LengthPercentageOrAuto;
use webrender_api::units::LayoutTransform;
/// This marker trait indicates that a type is a struct with `#[repr(C)]` whose first field
@@ -1020,13 +1019,13 @@ impl BaseFlow {
flags.insert(FlowFlags::IS_ABSOLUTELY_POSITIONED);
let logical_position = style.logical_position();
- if logical_position.inline_start == LengthPercentageOrAuto::Auto &&
- logical_position.inline_end == LengthPercentageOrAuto::Auto
+ if logical_position.inline_start.is_auto() &&
+ logical_position.inline_end.is_auto()
{
flags.insert(FlowFlags::INLINE_POSITION_IS_STATIC);
}
- if logical_position.block_start == LengthPercentageOrAuto::Auto &&
- logical_position.block_end == LengthPercentageOrAuto::Auto
+ if logical_position.block_start.is_auto() &&
+ logical_position.block_end.is_auto()
{
flags.insert(FlowFlags::BLOCK_POSITION_IS_STATIC);
}
@@ -1113,13 +1112,12 @@ impl BaseFlow {
let logical_position = style.logical_position();
self.flags.set(
FlowFlags::INLINE_POSITION_IS_STATIC,
- logical_position.inline_start == LengthPercentageOrAuto::Auto &&
- logical_position.inline_end == LengthPercentageOrAuto::Auto,
+ logical_position.inline_start.is_auto() &&
+ logical_position.inline_end.is_auto(),
);
self.flags.set(
FlowFlags::BLOCK_POSITION_IS_STATIC,
- logical_position.block_start == LengthPercentageOrAuto::Auto &&
- logical_position.block_end == LengthPercentageOrAuto::Auto,
+ logical_position.block_start.is_auto() && logical_position.block_end.is_auto(),
);
}
}
diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs
index f663dad744d..c0240f72071 100644
--- a/components/layout/fragment.rs
+++ b/components/layout/fragment.rs
@@ -61,10 +61,9 @@ use style::selector_parser::RestyleDamage;
use style::servo::restyle_damage::ServoRestyleDamage;
use style::str::char_is_whitespace;
use style::values::computed::counters::ContentItem;
-use style::values::computed::{LengthPercentage, LengthPercentageOrAuto, Size, VerticalAlign};
+use style::values::computed::{Size, VerticalAlign};
use style::values::generics::box_::{Perspective, VerticalAlignKeyword};
use style::values::generics::transform;
-use style::Zero;
use webrender_api;
use webrender_api::units::LayoutTransform;
@@ -1329,13 +1328,17 @@ impl Fragment {
return;
},
_ => {
- let margin = self.style().logical_margin();
- self.margin.inline_start =
- MaybeAuto::from_style(margin.inline_start, containing_block_inline_size)
- .specified_or_zero();
- self.margin.inline_end =
- MaybeAuto::from_style(margin.inline_end, containing_block_inline_size)
- .specified_or_zero();
+ let (inline_start, inline_end) = {
+ let margin = self.style().logical_margin();
+ (
+ MaybeAuto::from_style(margin.inline_start, containing_block_inline_size)
+ .specified_or_zero(),
+ MaybeAuto::from_style(margin.inline_end, containing_block_inline_size)
+ .specified_or_zero(),
+ )
+ };
+ self.margin.inline_start = inline_start;
+ self.margin.inline_end = inline_end;
},
}
@@ -1384,13 +1387,17 @@ impl Fragment {
_ => {
// NB: Percentages are relative to containing block inline-size (not block-size)
// per CSS 2.1.
- let margin = self.style().logical_margin();
- self.margin.block_start =
- MaybeAuto::from_style(margin.block_start, containing_block_inline_size)
- .specified_or_zero();
- self.margin.block_end =
- MaybeAuto::from_style(margin.block_end, containing_block_inline_size)
- .specified_or_zero();
+ let (block_start, block_end) = {
+ let margin = self.style().logical_margin();
+ (
+ MaybeAuto::from_style(margin.block_start, containing_block_inline_size)
+ .specified_or_zero(),
+ MaybeAuto::from_style(margin.block_end, containing_block_inline_size)
+ .specified_or_zero(),
+ )
+ };
+ self.margin.block_start = block_start;
+ self.margin.block_end = block_end;
},
}
}
@@ -1458,14 +1465,14 @@ impl Fragment {
pub fn relative_position(&self, containing_block_size: &LogicalSize<Au>) -> LogicalSize<Au> {
fn from_style(style: &ComputedValues, container_size: &LogicalSize<Au>) -> LogicalSize<Au> {
let offsets = style.logical_position();
- let offset_i = if offsets.inline_start != LengthPercentageOrAuto::Auto {
+ let offset_i = if !offsets.inline_start.is_auto() {
MaybeAuto::from_style(offsets.inline_start, container_size.inline)
.specified_or_zero()
} else {
-MaybeAuto::from_style(offsets.inline_end, container_size.inline)
.specified_or_zero()
};
- let offset_b = if offsets.block_start != LengthPercentageOrAuto::Auto {
+ let offset_b = if !offsets.block_start.is_auto() {
MaybeAuto::from_style(offsets.block_start, container_size.block).specified_or_zero()
} else {
-MaybeAuto::from_style(offsets.block_end, container_size.block).specified_or_zero()
@@ -2520,13 +2527,19 @@ impl Fragment {
{
continue;
}
- if inline_context_node.style.logical_margin().inline_end !=
- LengthPercentageOrAuto::zero()
+ if !inline_context_node
+ .style
+ .logical_margin()
+ .inline_end
+ .is_definitely_zero()
{
return false;
}
- if inline_context_node.style.logical_padding().inline_end !=
- LengthPercentage::zero()
+ if !inline_context_node
+ .style
+ .logical_padding()
+ .inline_end
+ .is_definitely_zero()
{
return false;
}
@@ -2546,13 +2559,19 @@ impl Fragment {
{
continue;
}
- if inline_context_node.style.logical_margin().inline_start !=
- LengthPercentageOrAuto::zero()
+ if !inline_context_node
+ .style
+ .logical_margin()
+ .inline_start
+ .is_definitely_zero()
{
return false;
}
- if inline_context_node.style.logical_padding().inline_start !=
- LengthPercentage::zero()
+ if !inline_context_node
+ .style
+ .logical_padding()
+ .inline_start
+ .is_definitely_zero()
{
return false;
}
@@ -3193,7 +3212,7 @@ impl Fragment {
) -> Option<LayoutTransform> {
match self.style().get_box().perspective {
Perspective::Length(length) => {
- let perspective_origin = self.style().get_box().perspective_origin;
+ let perspective_origin = &self.style().get_box().perspective_origin;
let perspective_origin = Point2D::new(
perspective_origin
.horizontal
diff --git a/components/layout/inline.rs b/components/layout/inline.rs
index 5ba82c1c95b..dfdb20e309b 100644
--- a/components/layout/inline.rs
+++ b/components/layout/inline.rs
@@ -1275,7 +1275,7 @@ impl InlineFlow {
&mut line_metrics,
&inline_metrics,
style.get_box().display,
- VerticalAlign::baseline(),
+ &VerticalAlign::baseline(),
&mut largest_block_size_for_top_fragments,
&mut largest_block_size_for_bottom_fragments,
);
@@ -1296,7 +1296,7 @@ impl InlineFlow {
&mut line_metrics,
&inline_metrics,
node.style.get_box().display,
- node.style.get_box().vertical_align,
+ &node.style.get_box().vertical_align,
&mut largest_block_size_for_top_fragments,
&mut largest_block_size_for_bottom_fragments,
);
@@ -1318,7 +1318,7 @@ impl InlineFlow {
line_metrics: &mut LineMetrics,
inline_metrics: &InlineMetrics,
display_value: Display,
- vertical_align_value: VerticalAlign,
+ vertical_align_value: &VerticalAlign,
largest_block_size_for_top_fragments: &mut Au,
largest_block_size_for_bottom_fragments: &mut Au,
) {
diff --git a/components/layout/lib.rs b/components/layout/lib.rs
index fdf3971fc3f..582a3e284d5 100644
--- a/components/layout/lib.rs
+++ b/components/layout/lib.rs
@@ -3,6 +3,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
#![deny(unsafe_code)]
+#![feature(matches_macro)]
#[macro_use]
extern crate bitflags;
diff --git a/components/layout/model.rs b/components/layout/model.rs
index e6be75e45a4..08f916142e9 100644
--- a/components/layout/model.rs
+++ b/components/layout/model.rs
@@ -437,7 +437,7 @@ pub enum MaybeAuto {
impl MaybeAuto {
#[inline]
- pub fn from_style(length: LengthPercentageOrAuto, containing_length: Au) -> MaybeAuto {
+ pub fn from_style(length: &LengthPercentageOrAuto, containing_length: Au) -> MaybeAuto {
match length {
LengthPercentageOrAuto::Auto => MaybeAuto::Auto,
LengthPercentageOrAuto::LengthPercentage(ref lp) => {
@@ -498,7 +498,7 @@ impl MaybeAuto {
/// Receive an optional container size and return used value for width or height.
///
/// `style_length`: content size as given in the CSS.
-pub fn style_length(style_length: Size, container_size: Option<Au>) -> MaybeAuto {
+pub fn style_length(style_length: &Size, container_size: Option<Au>) -> MaybeAuto {
match style_length {
Size::Auto => MaybeAuto::Auto,
Size::LengthPercentage(ref lp) => {
@@ -546,10 +546,10 @@ pub fn specified_margin_from_style(
LogicalMargin::from_physical(
writing_mode,
SideOffsets2D::new(
- MaybeAuto::from_style(margin_style.margin_top, Au(0)).specified_or_zero(),
- MaybeAuto::from_style(margin_style.margin_right, Au(0)).specified_or_zero(),
- MaybeAuto::from_style(margin_style.margin_bottom, Au(0)).specified_or_zero(),
- MaybeAuto::from_style(margin_style.margin_left, Au(0)).specified_or_zero(),
+ MaybeAuto::from_style(&margin_style.margin_top, Au(0)).specified_or_zero(),
+ MaybeAuto::from_style(&margin_style.margin_right, Au(0)).specified_or_zero(),
+ MaybeAuto::from_style(&margin_style.margin_bottom, Au(0)).specified_or_zero(),
+ MaybeAuto::from_style(&margin_style.margin_left, Au(0)).specified_or_zero(),
),
)
}
@@ -568,8 +568,8 @@ impl SizeConstraint {
/// Create a `SizeConstraint` for an axis.
pub fn new(
container_size: Option<Au>,
- min_size: Size,
- max_size: MaxSize,
+ min_size: &Size,
+ max_size: &MaxSize,
border: Option<Au>,
) -> SizeConstraint {
let mut min_size = match min_size {
diff --git a/components/layout/multicol.rs b/components/layout/multicol.rs
index 8890c08e189..4e1bfdf8d58 100644
--- a/components/layout/multicol.rs
+++ b/components/layout/multicol.rs
@@ -102,14 +102,14 @@ impl Flow for MulticolFlow {
let column_width;
{
let style = &self.block_flow.fragment.style;
- let column_gap = match style.get_position().column_gap {
- NonNegativeLengthPercentageOrNormal::LengthPercentage(len) => {
- len.0.to_pixel_length(content_inline_size).into()
+ let column_gap = Au::from(match style.get_position().column_gap {
+ NonNegativeLengthPercentageOrNormal::LengthPercentage(ref len) => {
+ len.0.to_pixel_length(content_inline_size)
},
NonNegativeLengthPercentageOrNormal::Normal => {
self.block_flow.fragment.style.get_font().font_size.size()
},
- };
+ });
let column_style = style.get_column();
let mut column_count;
diff --git a/components/layout/table_colgroup.rs b/components/layout/table_colgroup.rs
index b318dd95efd..ce097083f62 100644
--- a/components/layout/table_colgroup.rs
+++ b/components/layout/table_colgroup.rs
@@ -76,7 +76,7 @@ impl Flow for TableColGroupFlow {
// Retrieve the specified value from the appropriate CSS property.
let inline_size = fragment.style().content_inline_size();
for _ in 0..fragment.column_span() {
- self.inline_sizes.push(inline_size)
+ self.inline_sizes.push(inline_size.clone())
}
}
}
diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs
index ffaf720467b..58fb40bde3a 100644
--- a/components/layout/table_row.rs
+++ b/components/layout/table_row.rs
@@ -403,11 +403,6 @@ impl Flow for TableRowFlow {
let child_row_span;
{
let child_table_cell = kid.as_mut_table_cell();
- child_specified_inline_size = child_table_cell
- .block_flow
- .fragment
- .style
- .content_inline_size();
child_column_span = child_table_cell.column_span;
child_row_span = child_table_cell.row_span;
@@ -422,6 +417,13 @@ impl Flow for TableRowFlow {
&mut self.preliminary_collapsed_borders,
)
}
+
+ child_specified_inline_size = child_table_cell
+ .block_flow
+ .fragment
+ .style
+ .content_inline_size()
+ .clone();
}
// Collect minimum and preferred inline-sizes of the cell for automatic table layout
diff --git a/components/layout/text.rs b/components/layout/text.rs
index 199bd7e07f2..ef9515b0726 100644
--- a/components/layout/text.rs
+++ b/components/layout/text.rs
@@ -519,7 +519,7 @@ pub fn line_height_from_style(style: &ComputedValues, metrics: &FontMetrics) ->
let font_size = style.get_font().font_size.size();
match style.get_inherited_text().line_height {
LineHeight::Normal => Au::from(metrics.line_gap),
- LineHeight::Number(l) => font_size.scale_by(l.0),
+ LineHeight::Number(l) => Au::from(font_size * l.0),
LineHeight::Length(l) => Au::from(l),
}
}
diff --git a/components/layout_2020/geom.rs b/components/layout_2020/geom.rs
index 562fad5c4f6..86e6faf45a7 100644
--- a/components/layout_2020/geom.rs
+++ b/components/layout_2020/geom.rs
@@ -175,13 +175,18 @@ impl flow_relative::Vec2<MaxSize<LengthPercentage>> {
containing_block: &ContainingBlock,
) -> flow_relative::Vec2<Option<Length>> {
flow_relative::Vec2 {
- inline: self
- .inline
- .to_option()
- .map(|lp| lp.percentage_relative_to(containing_block.inline_size)),
- block: self.block.to_option().and_then(|olp| {
- olp.maybe_percentage_relative_to(containing_block.block_size.non_auto())
- }),
+ inline: match self.inline {
+ MaxSize::None => None,
+ MaxSize::LengthPercentage(ref lp) => {
+ Some(lp.percentage_relative_to(containing_block.inline_size))
+ },
+ },
+ block: match self.block {
+ MaxSize::None => None,
+ MaxSize::LengthPercentage(ref lp) => {
+ lp.maybe_percentage_relative_to(containing_block.block_size.non_auto())
+ },
+ },
}
}
}
diff --git a/components/layout_2020/positioned.rs b/components/layout_2020/positioned.rs
index c9ad2dd97c4..b10b489bc1d 100644
--- a/components/layout_2020/positioned.rs
+++ b/components/layout_2020/positioned.rs
@@ -40,7 +40,7 @@ pub(crate) struct HoistedAbsolutelyPositionedBox<'box_tree> {
box_offsets: Vec2<AbsoluteBoxOffsets>,
}
-#[derive(Clone, Copy, Debug)]
+#[derive(Clone, Debug)]
pub(crate) enum AbsoluteBoxOffsets {
StaticStart {
start: Length,
@@ -113,13 +113,13 @@ impl AbsolutelyPositionedBox {
box_offsets: Vec2 {
inline: absolute_box_offsets(
initial_start_corner.inline,
- box_offsets.inline_start,
- box_offsets.inline_end,
+ box_offsets.inline_start.clone(),
+ box_offsets.inline_end.clone(),
),
block: absolute_box_offsets(
initial_start_corner.block,
- box_offsets.block_start,
- box_offsets.block_end,
+ box_offsets.block_start.clone(),
+ box_offsets.block_end.clone(),
),
},
}
@@ -372,20 +372,20 @@ impl<'box_tree> HoistedAbsolutelyPositionedBox<'box_tree> {
let inline_axis = solve_axis(
cbis,
pb.inline_sum(),
- computed_margin.inline_start,
- computed_margin.inline_end,
+ computed_margin.inline_start.clone(),
+ computed_margin.inline_end.clone(),
/* avoid_negative_margin_start */ true,
- self.box_offsets.inline,
+ self.box_offsets.inline.clone(),
size.inline,
);
let block_axis = solve_axis(
cbis,
pb.block_sum(),
- computed_margin.block_start,
- computed_margin.block_end,
+ computed_margin.block_start.clone(),
+ computed_margin.block_end.clone(),
/* avoid_negative_margin_start */ false,
- self.box_offsets.block,
+ self.box_offsets.block.clone(),
size.block,
);
diff --git a/components/layout_2020/sizing.rs b/components/layout_2020/sizing.rs
index e3c74d3733f..dc7513a7859 100644
--- a/components/layout_2020/sizing.rs
+++ b/components/layout_2020/sizing.rs
@@ -7,6 +7,7 @@
use crate::style_ext::ComputedValuesExt;
use style::properties::ComputedValues;
use style::values::computed::{Length, LengthPercentage, Percentage};
+use style::values::generics::length::MaxSize;
use style::Zero;
/// Which min/max-content values should be computed during box construction
@@ -114,11 +115,10 @@ impl BoxContentSizes {
.inline
.percentage_relative_to(Length::zero())
.auto_is(Length::zero);
- let max_inline_size = style
- .max_box_size()
- .inline
- .to_option()
- .and_then(|lp| lp.as_length());
+ let max_inline_size = match style.max_box_size().inline {
+ MaxSize::None => None,
+ MaxSize::LengthPercentage(ref lp) => lp.as_length(),
+ };
let clamp = |l: Length| l.clamp_between_extremums(min_inline_size, max_inline_size);
// Percentages for 'width' are treated as 'auto'
diff --git a/components/layout_2020/style_ext.rs b/components/layout_2020/style_ext.rs
index 67d8bc78d7e..2d5af4da38e 100644
--- a/components/layout_2020/style_ext.rs
+++ b/components/layout_2020/style_ext.rs
@@ -55,9 +55,9 @@ impl ComputedValuesExt for ComputedValues {
fn inline_size_is_length(&self) -> bool {
let position = self.get_position();
let size = if self.writing_mode.is_horizontal() {
- position.width
+ &position.width
} else {
- position.height
+ &position.height
};
matches!(size, Size::LengthPercentage(lp) if lp.0.as_length().is_some())
}
@@ -65,21 +65,21 @@ impl ComputedValuesExt for ComputedValues {
fn inline_box_offsets_are_both_non_auto(&self) -> bool {
let position = self.get_position();
let (a, b) = if self.writing_mode.is_horizontal() {
- (position.left, position.right)
+ (&position.left, &position.right)
} else {
- (position.top, position.bottom)
+ (&position.top, &position.bottom)
};
- a != LengthPercentageOrAuto::Auto && b != LengthPercentageOrAuto::Auto
+ !a.is_auto() && !b.is_auto()
}
#[inline]
fn box_offsets(&self) -> flow_relative::Sides<LengthPercentageOrAuto> {
let position = self.get_position();
physical::Sides {
- top: position.top,
- left: position.left,
- bottom: position.bottom,
- right: position.right,
+ top: position.top.clone(),
+ left: position.left.clone(),
+ bottom: position.bottom.clone(),
+ right: position.right.clone(),
}
.to_flow_relative(self.writing_mode)
}
@@ -88,8 +88,8 @@ impl ComputedValuesExt for ComputedValues {
fn box_size(&self) -> flow_relative::Vec2<LengthPercentageOrAuto> {
let position = self.get_position();
physical::Vec2 {
- x: size_to_length(position.width),
- y: size_to_length(position.height),
+ x: size_to_length(position.width.clone()),
+ y: size_to_length(position.height.clone()),
}
.size_to_flow_relative(self.writing_mode)
}
@@ -98,8 +98,8 @@ impl ComputedValuesExt for ComputedValues {
fn min_box_size(&self) -> flow_relative::Vec2<LengthPercentageOrAuto> {
let position = self.get_position();
physical::Vec2 {
- x: size_to_length(position.min_width),
- y: size_to_length(position.min_height),
+ x: size_to_length(position.min_width.clone()),
+ y: size_to_length(position.min_height.clone()),
}
.size_to_flow_relative(self.writing_mode)
}
@@ -112,8 +112,8 @@ impl ComputedValuesExt for ComputedValues {
};
let position = self.get_position();
physical::Vec2 {
- x: unwrap(position.max_width),
- y: unwrap(position.max_height),
+ x: unwrap(position.max_width.clone()),
+ y: unwrap(position.max_height.clone()),
}
.size_to_flow_relative(self.writing_mode)
}
@@ -122,10 +122,10 @@ impl ComputedValuesExt for ComputedValues {
fn padding(&self) -> flow_relative::Sides<LengthPercentage> {
let padding = self.get_padding();
physical::Sides {
- top: padding.padding_top.0,
- left: padding.padding_left.0,
- bottom: padding.padding_bottom.0,
- right: padding.padding_right.0,
+ top: padding.padding_top.0.clone(),
+ left: padding.padding_left.0.clone(),
+ bottom: padding.padding_bottom.0.clone(),
+ right: padding.padding_right.0.clone(),
}
.to_flow_relative(self.writing_mode)
}
@@ -144,10 +144,10 @@ impl ComputedValuesExt for ComputedValues {
fn margin(&self) -> flow_relative::Sides<LengthPercentageOrAuto> {
let margin = self.get_margin();
physical::Sides {
- top: margin.margin_top,
- left: margin.margin_left,
- bottom: margin.margin_bottom,
- right: margin.margin_right,
+ top: margin.margin_top.clone(),
+ left: margin.margin_left.clone(),
+ bottom: margin.margin_bottom.clone(),
+ right: margin.margin_right.clone(),
}
.to_flow_relative(self.writing_mode)
}
@@ -180,7 +180,9 @@ impl From<stylo::Display> for Display {
fn size_to_length(size: Size) -> LengthPercentageOrAuto {
match size {
- Size::LengthPercentage(length) => LengthPercentageOrAuto::LengthPercentage(length.0),
+ Size::LengthPercentage(length) => {
+ LengthPercentageOrAuto::LengthPercentage(length.0.clone())
+ },
Size::Auto => LengthPercentageOrAuto::Auto,
}
}
diff --git a/components/malloc_size_of/Cargo.toml b/components/malloc_size_of/Cargo.toml
index d2068a30e9b..1b4872e67f1 100644
--- a/components/malloc_size_of/Cargo.toml
+++ b/components/malloc_size_of/Cargo.toml
@@ -40,7 +40,7 @@ serde = { version = "1.0.27", optional = true }
serde_bytes = { version = "0.11", optional = true }
servo_arc = { path = "../servo_arc" }
smallbitvec = "2.3.0"
-smallvec = "0.6"
+smallvec = "1.0"
string_cache = { version = "0.8", optional = true }
thin-slice = "0.1.0"
time = { version = "0.1.17", optional = true }
diff --git a/components/selectors/Cargo.toml b/components/selectors/Cargo.toml
index d32e82a2336..8bf0ba716cb 100644
--- a/components/selectors/Cargo.toml
+++ b/components/selectors/Cargo.toml
@@ -23,13 +23,13 @@ bench = []
bitflags = "1.0"
matches = "0.1"
cssparser = "0.27"
-derive_more = "0.13"
+derive_more = "0.99"
log = "0.4"
fxhash = "0.2"
phf = "0.8"
precomputed-hash = "0.1"
servo_arc = { version = "0.1", path = "../servo_arc" }
-smallvec = "0.6"
+smallvec = "1.0"
thin-slice = "0.1.0"
to_shmem = { path = "../to_shmem" }
to_shmem_derive = { path = "../to_shmem_derive" }
diff --git a/components/selectors/builder.rs b/components/selectors/builder.rs
index 41b83b0c40e..7a58e35d17f 100644
--- a/components/selectors/builder.rs
+++ b/components/selectors/builder.rs
@@ -17,7 +17,7 @@
//! is non-trivial. This module encapsulates those details and presents an
//! easy-to-use API for the parser.
-use crate::parser::{Combinator, Component, SelectorImpl};
+use crate::parser::{Combinator, Component, NonTSPseudoClass, SelectorImpl};
use crate::sink::Push;
use servo_arc::{Arc, HeaderWithLength, ThinArc};
use smallvec::{self, SmallVec};
@@ -142,7 +142,7 @@ impl<Impl: SelectorImpl> SelectorBuilder<Impl> {
let iter = SelectorBuilderIter {
current_simple_selectors: current.iter(),
rest_of_simple_selectors: rest,
- combinators: self.combinators.drain().rev(),
+ combinators: self.combinators.drain(..).rev(),
};
Arc::into_thin(Arc::from_header_and_iter(header, iter))
@@ -152,7 +152,7 @@ impl<Impl: SelectorImpl> SelectorBuilder<Impl> {
struct SelectorBuilderIter<'a, Impl: SelectorImpl> {
current_simple_selectors: slice::Iter<'a, Component<Impl>>,
rest_of_simple_selectors: &'a [Component<Impl>],
- combinators: iter::Rev<smallvec::Drain<'a, (Combinator, usize)>>,
+ combinators: iter::Rev<smallvec::Drain<'a, [(Combinator, usize); 16]>>,
}
impl<'a, Impl: SelectorImpl> ExactSizeIterator for SelectorBuilderIter<'a, Impl> {
@@ -322,10 +322,14 @@ where
Component::NthLastOfType(..) |
Component::FirstOfType |
Component::LastOfType |
- Component::OnlyOfType |
- Component::NonTSPseudoClass(..) => {
+ Component::OnlyOfType => {
specificity.class_like_selectors += 1;
},
+ Component::NonTSPseudoClass(ref pseudo) => {
+ if !pseudo.has_zero_specificity() {
+ specificity.class_like_selectors += 1;
+ }
+ },
Component::ExplicitUniversalType |
Component::ExplicitAnyNamespace |
Component::ExplicitNoNamespace |
diff --git a/components/selectors/parser.rs b/components/selectors/parser.rs
index 507121bbf97..92a5b039b90 100644
--- a/components/selectors/parser.rs
+++ b/components/selectors/parser.rs
@@ -52,6 +52,9 @@ pub trait NonTSPseudoClass: Sized + ToCss {
///
/// https://drafts.csswg.org/selectors-4/#useraction-pseudos
fn is_user_action_state(&self) -> bool;
+
+ /// Whether this pseudo-class has zero specificity.
+ fn has_zero_specificity(&self) -> bool;
}
/// Returns a Cow::Borrowed if `s` is already ASCII lowercase, and a
@@ -2336,6 +2339,11 @@ pub mod tests {
fn is_user_action_state(&self) -> bool {
self.is_active_or_hover()
}
+
+ #[inline]
+ fn has_zero_specificity(&self) -> bool {
+ false
+ }
}
impl ToCss for PseudoClass {
diff --git a/components/style/Cargo.toml b/components/style/Cargo.toml
index 47a0d4392ef..6adb71e89d7 100644
--- a/components/style/Cargo.toml
+++ b/components/style/Cargo.toml
@@ -35,7 +35,7 @@ bitflags = "1.0"
byteorder = "1.0"
cssparser = "0.27"
crossbeam-channel = { version = "0.3", optional = true }
-derive_more = "0.13"
+derive_more = "0.99"
new_debug_unreachable = "1.0"
encoding_rs = {version = "0.8", optional = true}
euclid = "0.20"
@@ -66,7 +66,7 @@ servo_arc = { path = "../servo_arc" }
servo_atoms = {path = "../atoms", optional = true}
servo_config = {path = "../config", optional = true}
smallbitvec = "2.3.0"
-smallvec = "0.6.6"
+smallvec = "1.0"
string_cache = { version = "0.8", optional = true }
style_derive = {path = "../style_derive"}
style_traits = {path = "../style_traits"}
diff --git a/components/style/bloom.rs b/components/style/bloom.rs
index a24dac42b2a..c17b31d1bee 100644
--- a/components/style/bloom.rs
+++ b/components/style/bloom.rs
@@ -216,7 +216,7 @@ impl<E: TElement> StyleBloom<E> {
self.filter.clear();
self.pushed_hashes.clear();
} else {
- for hash in self.pushed_hashes.drain() {
+ for hash in self.pushed_hashes.drain(..) {
self.filter.remove_hash(hash);
}
debug_assert!(self.filter.is_zeroed());
@@ -233,7 +233,7 @@ impl<E: TElement> StyleBloom<E> {
element = parent;
}
- for parent in parents_to_insert.drain().rev() {
+ for parent in parents_to_insert.drain(..).rev() {
self.push(parent);
}
}
@@ -374,7 +374,7 @@ impl<E: TElement> StyleBloom<E> {
// Now the parents match, so insert the stack of elements we have been
// collecting so far.
- for parent in parents_to_insert.drain().rev() {
+ for parent in parents_to_insert.drain(..).rev() {
self.push(parent);
}
diff --git a/components/style/dom.rs b/components/style/dom.rs
index fbe35e2e49d..74067e225c8 100644
--- a/components/style/dom.rs
+++ b/components/style/dom.rs
@@ -807,6 +807,9 @@ pub trait TElement:
/// data if it comes from Shadow DOM.
///
/// Returns whether normal document author rules should apply.
+ ///
+ /// TODO(emilio): We could separate the invalidation data for elements
+ /// matching in other scopes to avoid over-invalidation.
fn each_applicable_non_document_style_rule_data<'a, F>(&self, mut f: F) -> bool
where
Self: 'a,
@@ -841,11 +844,42 @@ pub trait TElement:
// Slots can only have assigned nodes when in a shadow tree.
let shadow = slot.containing_shadow().unwrap();
if let Some(data) = shadow.style_data() {
- f(data, shadow.host());
+ if data.any_slotted_rule() {
+ f(data, shadow.host());
+ }
}
current = slot.assigned_slot();
}
+ if target.has_part_attr() {
+ if let Some(mut inner_shadow) = target.containing_shadow() {
+ loop {
+ let inner_shadow_host = inner_shadow.host();
+ match inner_shadow_host.containing_shadow() {
+ Some(shadow) => {
+ if let Some(data) = shadow.style_data() {
+ if data.any_part_rule() {
+ f(data, shadow.host())
+ }
+ }
+ // TODO: Could be more granular.
+ if !shadow.host().exports_any_part() {
+ break;
+ }
+ inner_shadow = shadow;
+ },
+ None => {
+ // TODO(emilio): Should probably distinguish with
+ // MatchesDocumentRules::{No,Yes,IfPart} or
+ // something so that we could skip some work.
+ doc_rules_apply = true;
+ break;
+ },
+ }
+ }
+ }
+ }
+
doc_rules_apply
}
diff --git a/components/style/font_metrics.rs b/components/style/font_metrics.rs
index 8e69118ade4..b521fdf76c9 100644
--- a/components/style/font_metrics.rs
+++ b/components/style/font_metrics.rs
@@ -7,17 +7,17 @@
#![deny(missing_docs)]
use crate::context::SharedStyleContext;
+use crate::values::computed::Length;
use crate::Atom;
-use app_units::Au;
/// Represents the font metrics that style needs from a font to compute the
/// value of certain CSS units like `ex`.
#[derive(Clone, Debug, Default, PartialEq)]
pub struct FontMetrics {
/// The x-height of the font.
- pub x_height: Option<Au>,
+ pub x_height: Option<Length>,
/// The zero advance. This is usually writing mode dependent
- pub zero_advance_measure: Option<Au>,
+ pub zero_advance_measure: Option<Length>,
}
/// Type of font metrics to retrieve.
@@ -47,7 +47,7 @@ pub trait FontMetricsProvider {
&self,
font_name: &Atom,
font_family: crate::values::computed::font::GenericFontFamily,
- ) -> Au;
+ ) -> Length;
/// Construct from a shared style context
fn create_from(context: &SharedStyleContext) -> Self
@@ -70,7 +70,7 @@ impl FontMetricsProvider for ServoMetricsProvider {
ServoMetricsProvider
}
- fn get_size(&self, _: &Atom, _: crate::values::computed::font::GenericFontFamily) -> Au {
+ fn get_size(&self, _: &Atom, _: crate::values::computed::font::GenericFontFamily) -> Length {
unreachable!("Dummy provider should never be used to compute font size")
}
}
diff --git a/components/style/gecko/media_queries.rs b/components/style/gecko/media_queries.rs
index 3463c1f95e9..3f82b832bce 100644
--- a/components/style/gecko/media_queries.rs
+++ b/components/style/gecko/media_queries.rs
@@ -11,10 +11,9 @@ use crate::gecko_bindings::structs;
use crate::media_queries::MediaType;
use crate::properties::ComputedValues;
use crate::string_cache::Atom;
-use crate::values::computed::font::FontSize;
+use crate::values::specified::font::FONT_MEDIUM_PX;
use crate::values::{CustomIdent, KeyframesName};
-use app_units::Au;
-use app_units::AU_PER_PX;
+use app_units::{Au, AU_PER_PX};
use cssparser::RGBA;
use euclid::default::Size2D;
use euclid::Scale;
@@ -87,7 +86,7 @@ impl Device {
document,
default_values: ComputedValues::default_values(doc),
// FIXME(bz): Seems dubious?
- root_font_size: AtomicIsize::new(FontSize::medium().size().0 as isize),
+ root_font_size: AtomicIsize::new(Au::from_px(FONT_MEDIUM_PX as i32).0 as isize),
body_text_color: AtomicUsize::new(prefs.mDefaultColor as usize),
used_root_font_size: AtomicBool::new(false),
used_viewport_size: AtomicBool::new(false),
diff --git a/components/style/gecko/non_ts_pseudo_class_list.rs b/components/style/gecko/non_ts_pseudo_class_list.rs
index f38757189d0..8d9fc3d2d85 100644
--- a/components/style/gecko/non_ts_pseudo_class_list.rs
+++ b/components/style/gecko/non_ts_pseudo_class_list.rs
@@ -48,8 +48,7 @@ macro_rules! apply_non_ts_list {
("indeterminate", Indeterminate, indeterminate, IN_INDETERMINATE_STATE, _),
("-moz-devtools-highlighted", MozDevtoolsHighlighted, mozDevtoolsHighlighted, IN_DEVTOOLS_HIGHLIGHTED_STATE, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS),
("-moz-styleeditor-transitioning", MozStyleeditorTransitioning, mozStyleeditorTransitioning, IN_STYLEEDITOR_TRANSITIONING_STATE, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS),
- ("fullscreen", Fullscreen, fullscreen, IN_FULLSCREEN_STATE, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME),
- ("-moz-full-screen", MozFullScreen, mozFullScreen, IN_FULLSCREEN_STATE, _),
+ ("fullscreen", Fullscreen, fullscreen, IN_FULLSCREEN_STATE, _),
// TODO(emilio): This is inconsistently named (the capital R).
("-moz-focusring", MozFocusRing, mozFocusRing, IN_FOCUSRING_STATE, _),
("-moz-broken", MozBroken, mozBroken, IN_BROKEN_STATE, _),
@@ -94,6 +93,7 @@ macro_rules! apply_non_ts_list {
("-moz-last-node", MozLastNode, lastNode, _, _),
("-moz-only-whitespace", MozOnlyWhitespace, mozOnlyWhitespace, _, _),
("-moz-native-anonymous", MozNativeAnonymous, mozNativeAnonymous, _, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS),
+ ("-moz-native-anonymous-no-specificity", MozNativeAnonymousNoSpecificity, mozNativeAnonymousNoSpecificity, _, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS),
("-moz-use-shadow-tree-root", MozUseShadowTreeRoot, mozUseShadowTreeRoot, _, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS),
("-moz-is-html", MozIsHTML, mozIsHTML, _, _),
("-moz-placeholder", MozPlaceholder, mozPlaceholder, _, _),
diff --git a/components/style/gecko/pseudo_element_definition.mako.rs b/components/style/gecko/pseudo_element_definition.mako.rs
index d8d80d60165..f4a6671bd39 100644
--- a/components/style/gecko/pseudo_element_definition.mako.rs
+++ b/components/style/gecko/pseudo_element_definition.mako.rs
@@ -193,18 +193,18 @@ impl PseudoElement {
% for pseudo in SIMPLE_PSEUDOS:
"${pseudo.value[1:]}" => {
return Some(${pseudo_element_variant(pseudo)})
- }
+ },
% endfor
// Alias some legacy prefixed pseudos to their standardized name at parse time:
"-moz-selection" => {
return Some(PseudoElement::Selection);
- }
+ },
"-moz-placeholder" => {
return Some(PseudoElement::Placeholder);
- }
+ },
"-moz-list-bullet" | "-moz-list-number" => {
return Some(PseudoElement::Marker);
- }
+ },
_ => {
if starts_with_ignore_ascii_case(name, "-moz-tree-") {
return PseudoElement::tree_pseudo_element(name, Box::new([]))
diff --git a/components/style/gecko/selector_parser.rs b/components/style/gecko/selector_parser.rs
index 2aad41adc9c..9f5b49c5c13 100644
--- a/components/style/gecko/selector_parser.rs
+++ b/components/style/gecko/selector_parser.rs
@@ -137,6 +137,7 @@ impl NonTSPseudoClass {
([$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*]) => {
match_ignore_ascii_case! { &name,
$($css => Some(NonTSPseudoClass::$name),)*
+ "-moz-full-screen" => Some(NonTSPseudoClass::Fullscreen),
_ => None,
}
}
@@ -169,16 +170,9 @@ impl NonTSPseudoClass {
}
/// Returns whether the pseudo-class is enabled in content sheets.
+ #[inline]
fn is_enabled_in_content(&self) -> bool {
- match *self {
- // For pseudo-classes with pref, the availability in content
- // depends on the pref.
- NonTSPseudoClass::Fullscreen => static_prefs::pref!("full-screen-api.unprefix.enabled"),
- // Otherwise, a pseudo-class is enabled in content when it
- // doesn't have any enabled flag.
- _ => !self
- .has_any_flag(NonTSPseudoClassFlag::PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME),
- }
+ !self.has_any_flag(NonTSPseudoClassFlag::PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME)
}
/// Get the state flag associated with a pseudo-class, if any.
@@ -233,6 +227,9 @@ impl NonTSPseudoClass {
// across all the elements involved and the latter is already
// checked for by our caching precondtions.
NonTSPseudoClass::MozIsHTML |
+ // We prevent style sharing for NAC.
+ NonTSPseudoClass::MozNativeAnonymous |
+ NonTSPseudoClass::MozNativeAnonymousNoSpecificity |
// :-moz-placeholder is parsed but never matches.
NonTSPseudoClass::MozPlaceholder |
// :-moz-locale-dir and :-moz-window-inactive depend only on
@@ -275,6 +272,11 @@ impl ::selectors::parser::NonTSPseudoClass for NonTSPseudoClass {
NonTSPseudoClass::Hover | NonTSPseudoClass::Active | NonTSPseudoClass::Focus
)
}
+
+ #[inline]
+ fn has_zero_specificity(&self) -> bool {
+ matches!(*self, NonTSPseudoClass::MozNativeAnonymousNoSpecificity)
+ }
}
/// The dummy struct we use to implement our selector parsing.
@@ -394,7 +396,7 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
parser,
)?.into()
)
- }
+ },
_ => return Err(parser.new_custom_error(
SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name.clone())
))
diff --git a/components/style/gecko/snapshot.rs b/components/style/gecko/snapshot.rs
index 02707682b4d..fa9914f6222 100644
--- a/components/style/gecko/snapshot.rs
+++ b/components/style/gecko/snapshot.rs
@@ -71,7 +71,7 @@ impl GeckoElementSnapshot {
}
/// Returns true if the snapshot recorded an attribute change which isn't a
- /// class or id change.
+ /// class / id
#[inline]
pub fn other_attr_changed(&self) -> bool {
self.mOtherAttributeChanged()
diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs
index bf4da090646..e4b2d7f0be1 100644
--- a/components/style/gecko/wrapper.rs
+++ b/components/style/gecko/wrapper.rs
@@ -68,6 +68,7 @@ use crate::shared_lock::Locked;
use crate::string_cache::{Atom, Namespace, WeakAtom, WeakNamespace};
use crate::stylist::CascadeData;
use crate::values::computed::font::GenericFontFamily;
+use crate::values::computed::Length;
use crate::values::specified::length::FontBaseSize;
use crate::CaseSensitivityExt;
use app_units::Au;
@@ -929,7 +930,7 @@ impl FontMetricsProvider for GeckoFontMetricsProvider {
GeckoFontMetricsProvider::new()
}
- fn get_size(&self, font_name: &Atom, font_family: GenericFontFamily) -> Au {
+ fn get_size(&self, font_name: &Atom, font_family: GenericFontFamily) -> Length {
let mut cache = self.font_size_cache.borrow_mut();
if let Some(sizes) = cache.iter().find(|el| el.0 == *font_name) {
return sizes.1.size_for_generic(font_family);
@@ -950,7 +951,7 @@ impl FontMetricsProvider for GeckoFontMetricsProvider {
None => return Default::default(),
};
- let size = base_size.resolve(context);
+ let size = Au::from(base_size.resolve(context));
let style = context.style();
let (wm, font) = match base_size {
@@ -977,9 +978,9 @@ impl FontMetricsProvider for GeckoFontMetricsProvider {
)
};
FontMetrics {
- x_height: Some(Au(gecko_metrics.mXSize)),
+ x_height: Some(Au(gecko_metrics.mXSize).into()),
zero_advance_measure: if gecko_metrics.mChSize >= 0 {
- Some(Au(gecko_metrics.mChSize))
+ Some(Au(gecko_metrics.mChSize).into())
} else {
None
},
@@ -988,7 +989,7 @@ impl FontMetricsProvider for GeckoFontMetricsProvider {
}
impl structs::FontSizePrefs {
- fn size_for_generic(&self, font_family: GenericFontFamily) -> Au {
+ fn size_for_generic(&self, font_family: GenericFontFamily) -> Length {
Au(match font_family {
GenericFontFamily::None => self.mDefaultVariableSize,
GenericFontFamily::Serif => self.mDefaultSerifSize,
@@ -1000,6 +1001,7 @@ impl structs::FontSizePrefs {
"Should never get here, since this doesn't (yet) appear on font family"
),
})
+ .into()
}
}
@@ -2045,7 +2047,6 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
NonTSPseudoClass::Disabled |
NonTSPseudoClass::Checked |
NonTSPseudoClass::Fullscreen |
- NonTSPseudoClass::MozFullScreen |
NonTSPseudoClass::Indeterminate |
NonTSPseudoClass::PlaceholderShown |
NonTSPseudoClass::Target |
@@ -2130,7 +2131,10 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
}
true
},
- NonTSPseudoClass::MozNativeAnonymous => self.is_in_native_anonymous_subtree(),
+ NonTSPseudoClass::MozNativeAnonymous |
+ NonTSPseudoClass::MozNativeAnonymousNoSpecificity => {
+ self.is_in_native_anonymous_subtree()
+ },
NonTSPseudoClass::MozUseShadowTreeRoot => self.is_root_of_use_element_shadow_tree(),
NonTSPseudoClass::MozTableBorderNonzero => unsafe {
bindings::Gecko_IsTableBorderNonzero(self.0)
diff --git a/components/style/gecko_bindings/sugar/ns_t_array.rs b/components/style/gecko_bindings/sugar/ns_t_array.rs
index 64ca9ffab78..e3d4e5b86bd 100644
--- a/components/style/gecko_bindings/sugar/ns_t_array.rs
+++ b/components/style/gecko_bindings/sugar/ns_t_array.rs
@@ -89,9 +89,11 @@ impl<T> nsTArray<T> {
pub unsafe fn set_len(&mut self, len: u32) {
// this can leak
debug_assert!(len >= self.len() as u32);
+ if self.len() == len as usize {
+ return;
+ }
self.ensure_capacity(len as usize);
- let header = self.header_mut();
- header.mLength = len;
+ self.header_mut().mLength = len;
}
/// Resizes an array containing only POD elements
@@ -103,6 +105,9 @@ impl<T> nsTArray<T> {
where
T: Copy,
{
+ if self.len() == len as usize {
+ return;
+ }
self.ensure_capacity(len as usize);
let header = self.header_mut();
header.mLength = len;
diff --git a/components/style/invalidation/element/invalidation_map.rs b/components/style/invalidation/element/invalidation_map.rs
index e0b9cf8d747..6d9f6a8602d 100644
--- a/components/style/invalidation/element/invalidation_map.rs
+++ b/components/style/invalidation/element/invalidation_map.rs
@@ -142,6 +142,19 @@ pub struct DocumentStateDependency {
pub state: DocumentState,
}
+bitflags! {
+ /// A set of flags that denote whether any invalidations have occurred
+ /// for a particular attribute selector.
+ #[derive(MallocSizeOf)]
+ #[repr(C)]
+ pub struct InvalidationMapFlags : u8 {
+ /// Whether [class] or such is used.
+ const HAS_CLASS_ATTR_SELECTOR = 1 << 0;
+ /// Whether [id] or such is used.
+ const HAS_ID_ATTR_SELECTOR = 1 << 1;
+ }
+}
+
/// A map where we store invalidations.
///
/// This is slightly different to a SelectorMap, in the sense of that the same
@@ -164,16 +177,9 @@ pub struct InvalidationMap {
pub document_state_selectors: Vec<DocumentStateDependency>,
/// A map of other attribute affecting selectors.
pub other_attribute_affecting_selectors: SelectorMap<Dependency>,
- /// Whether there are attribute rules of the form `[class~="foo"]` that may
- /// match. In that case, we need to look at
- /// `other_attribute_affecting_selectors` too even if only the `class` has
- /// changed.
- pub has_class_attribute_selectors: bool,
- /// Whether there are attribute rules of the form `[id|="foo"]` that may
- /// match. In that case, we need to look at
- /// `other_attribute_affecting_selectors` too even if only the `id` has
- /// changed.
- pub has_id_attribute_selectors: bool,
+ /// A set of flags that contain whether various special attributes are used
+ /// in this invalidation map.
+ pub flags: InvalidationMapFlags,
}
impl InvalidationMap {
@@ -185,8 +191,7 @@ impl InvalidationMap {
state_affecting_selectors: SelectorMap::new(),
document_state_selectors: Vec::new(),
other_attribute_affecting_selectors: SelectorMap::new(),
- has_class_attribute_selectors: false,
- has_id_attribute_selectors: false,
+ flags: InvalidationMapFlags::empty(),
}
}
@@ -210,8 +215,7 @@ impl InvalidationMap {
self.state_affecting_selectors.clear();
self.document_state_selectors.clear();
self.other_attribute_affecting_selectors.clear();
- self.has_id_attribute_selectors = false;
- self.has_class_attribute_selectors = false;
+ self.flags = InvalidationMapFlags::empty();
}
/// Adds a selector to this `InvalidationMap`. Returns Err(..) to
@@ -238,8 +242,7 @@ impl InvalidationMap {
state: ElementState::empty(),
document_state: &mut document_state,
other_attributes: false,
- has_id_attribute_selectors: false,
- has_class_attribute_selectors: false,
+ flags: &mut self.flags,
};
// Visit all the simple selectors in this sequence.
@@ -255,9 +258,6 @@ impl InvalidationMap {
index += 1; // Account for the simple selector.
}
- self.has_id_attribute_selectors |= compound_visitor.has_id_attribute_selectors;
- self.has_class_attribute_selectors |= compound_visitor.has_class_attribute_selectors;
-
for class in compound_visitor.classes {
self.class_to_selector
.try_entry(class, quirks_mode)?
@@ -349,11 +349,8 @@ struct CompoundSelectorDependencyCollector<'a> {
/// [id] attribute selectors).
other_attributes: bool,
- /// Whether there were attribute selectors with the id attribute.
- has_id_attribute_selectors: bool,
-
- /// Whether there were attribute selectors with the class attribute.
- has_class_attribute_selectors: bool,
+ /// The invalidation map flags, that we set when some attribute selectors are present.
+ flags: &'a mut InvalidationMapFlags,
}
impl<'a> SelectorVisitor for CompoundSelectorDependencyCollector<'a> {
@@ -398,8 +395,13 @@ impl<'a> SelectorVisitor for CompoundSelectorDependencyCollector<'a> {
};
if may_match_in_no_namespace {
- self.has_id_attribute_selectors |= *local_name_lower == local_name!("id");
- self.has_class_attribute_selectors |= *local_name_lower == local_name!("class");
+ if *local_name_lower == local_name!("id") {
+ self.flags
+ .insert(InvalidationMapFlags::HAS_ID_ATTR_SELECTOR)
+ } else if *local_name_lower == local_name!("class") {
+ self.flags
+ .insert(InvalidationMapFlags::HAS_CLASS_ATTR_SELECTOR)
+ }
}
true
diff --git a/components/style/invalidation/element/invalidator.rs b/components/style/invalidation/element/invalidator.rs
index e094be281b4..f0f55595dff 100644
--- a/components/style/invalidation/element/invalidator.rs
+++ b/components/style/invalidation/element/invalidator.rs
@@ -698,7 +698,7 @@ where
}
}
- sibling_invalidations.extend(new_sibling_invalidations.drain());
+ sibling_invalidations.extend(new_sibling_invalidations.drain(..));
invalidated_self
}
diff --git a/components/style/invalidation/element/state_and_attributes.rs b/components/style/invalidation/element/state_and_attributes.rs
index e678413218c..628f174a3d7 100644
--- a/components/style/invalidation/element/state_and_attributes.rs
+++ b/components/style/invalidation/element/state_and_attributes.rs
@@ -42,6 +42,7 @@ where
descendant_invalidations: &'a mut DescendantInvalidationLists<'selectors>,
sibling_invalidations: &'a mut InvalidationVector<'selectors>,
invalidates_self: bool,
+ attr_selector_flags: InvalidationMapFlags,
}
/// An invalidation processor for style changes due to state and attribute
@@ -155,6 +156,8 @@ where
return false;
}
+ let mut attr_selector_flags = InvalidationMapFlags::empty();
+
// If we the visited state changed, we force a restyle here. Matching
// doesn't depend on the actual visited state at all, so we can't look
// at matching results to decide what to do for this case.
@@ -172,6 +175,7 @@ where
let mut classes_removed = SmallVec::<[Atom; 8]>::new();
let mut classes_added = SmallVec::<[Atom; 8]>::new();
if snapshot.class_changed() {
+ attr_selector_flags.insert(InvalidationMapFlags::HAS_CLASS_ATTR_SELECTOR);
// TODO(emilio): Do this more efficiently!
snapshot.each_class(|c| {
if !element.has_class(c, CaseSensitivity::CaseSensitive) {
@@ -189,6 +193,7 @@ where
let mut id_removed = None;
let mut id_added = None;
if snapshot.id_changed() {
+ attr_selector_flags.insert(InvalidationMapFlags::HAS_ID_ATTR_SELECTOR);
let old_id = snapshot.id_attr();
let current_id = element.id();
@@ -199,7 +204,10 @@ where
}
if log_enabled!(::log::Level::Debug) {
- debug!("Collecting changes for: {:?}", element);
+ debug!(
+ "Collecting changes for: {:?}, flags {:?}",
+ element, attr_selector_flags
+ );
if !state_changes.is_empty() {
debug!(" > state: {:?}", state_changes);
}
@@ -247,6 +255,7 @@ where
descendant_invalidations,
sibling_invalidations,
invalidates_self: false,
+ attr_selector_flags,
};
let document_origins = if !matches_document_author_rules {
@@ -356,9 +365,8 @@ where
}
}
- let should_examine_attribute_selector_map = self.snapshot.other_attr_changed() ||
- (self.snapshot.class_changed() && map.has_class_attribute_selectors) ||
- (self.snapshot.id_changed() && map.has_id_attribute_selectors);
+ let should_examine_attribute_selector_map =
+ self.snapshot.other_attr_changed() || map.flags.intersects(self.attr_selector_flags);
if should_examine_attribute_selector_map {
self.collect_dependencies_in_map(&map.other_attribute_affecting_selectors)
diff --git a/components/style/logical_geometry.rs b/components/style/logical_geometry.rs
index cb45544146b..d4d058adc61 100644
--- a/components/style/logical_geometry.rs
+++ b/components/style/logical_geometry.rs
@@ -468,7 +468,7 @@ impl<T: Zero> LogicalSize<T> {
}
}
-impl<T: Copy> LogicalSize<T> {
+impl<T> LogicalSize<T> {
#[inline]
pub fn new(mode: WritingMode, inline: T, block: T) -> LogicalSize<T> {
LogicalSize {
@@ -486,7 +486,9 @@ impl<T: Copy> LogicalSize<T> {
LogicalSize::new(mode, size.width, size.height)
}
}
+}
+impl<T: Copy> LogicalSize<T> {
#[inline]
pub fn width(&self, mode: WritingMode) -> T {
self.debug_writing_mode.check(mode);
@@ -860,7 +862,7 @@ impl<T: Zero> LogicalMargin<T> {
}
}
-impl<T: Copy> LogicalMargin<T> {
+impl<T> LogicalMargin<T> {
#[inline]
pub fn new(
mode: WritingMode,
@@ -879,11 +881,6 @@ impl<T: Copy> LogicalMargin<T> {
}
#[inline]
- pub fn new_all_same(mode: WritingMode, value: T) -> LogicalMargin<T> {
- LogicalMargin::new(mode, value, value, value, value)
- }
-
- #[inline]
pub fn from_physical(mode: WritingMode, offsets: SideOffsets2D<T>) -> LogicalMargin<T> {
let block_start;
let inline_end;
@@ -917,6 +914,13 @@ impl<T: Copy> LogicalMargin<T> {
}
LogicalMargin::new(mode, block_start, inline_end, block_end, inline_start)
}
+}
+
+impl<T: Copy> LogicalMargin<T> {
+ #[inline]
+ pub fn new_all_same(mode: WritingMode, value: T) -> LogicalMargin<T> {
+ LogicalMargin::new(mode, value, value, value, value)
+ }
#[inline]
pub fn top(&self, mode: WritingMode) -> T {
diff --git a/components/style/matching.rs b/components/style/matching.rs
index 01246ed3878..7ec94d35346 100644
--- a/components/style/matching.rs
+++ b/components/style/matching.rs
@@ -715,7 +715,7 @@ pub trait MatchMethods: TElement {
.map_or(true, |s| s.get_font().clone_font_size() != new_font_size)
{
debug_assert!(self.owner_doc_matches_for_testing(device));
- device.set_root_font_size(new_font_size.size());
+ device.set_root_font_size(new_font_size.size().into());
// If the root font-size changed since last time, and something
// in the document did use rem units, ensure we recascade the
// entire tree.
diff --git a/components/style/parallel.rs b/components/style/parallel.rs
index d4aa0af6acf..9e578e9e9e6 100644
--- a/components/style/parallel.rs
+++ b/components/style/parallel.rs
@@ -180,7 +180,7 @@ fn top_down_dom<'a, 'scope, E, D>(
let mut traversal_data_copy = traversal_data.clone();
traversal_data_copy.current_dom_depth += 1;
traverse_nodes(
- discovered_child_nodes.drain(),
+ discovered_child_nodes.drain(..),
DispatchMode::NotTailCall,
recursion_ok,
root,
@@ -210,7 +210,7 @@ fn top_down_dom<'a, 'scope, E, D>(
if !discovered_child_nodes.is_empty() {
traversal_data.current_dom_depth += 1;
traverse_nodes(
- discovered_child_nodes.drain(),
+ discovered_child_nodes.drain(..),
DispatchMode::TailCall,
recursion_ok,
root,
diff --git a/components/style/properties/cascade.rs b/components/style/properties/cascade.rs
index a667cba09bc..dd87916cf7d 100644
--- a/components/style/properties/cascade.rs
+++ b/components/style/properties/cascade.rs
@@ -743,6 +743,7 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
fn recompute_keyword_font_size_if_needed(&mut self) {
use crate::values::computed::ToComputedValue;
use crate::values::specified;
+ use app_units::Au;
if !self.seen.contains(LonghandId::XLang) &&
!self.seen.contains(LonghandId::FontFamily) {
@@ -759,7 +760,7 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
None => return,
};
- if font.gecko().mScriptUnconstrainedSize == new_size.size().0 {
+ if font.gecko().mScriptUnconstrainedSize == Au::from(new_size.size()).0 {
return;
}
diff --git a/components/style/properties/counted_unknown_properties.py b/components/style/properties/counted_unknown_properties.py
index de36199e77a..047d129a2ff 100644
--- a/components/style/properties/counted_unknown_properties.py
+++ b/components/style/properties/counted_unknown_properties.py
@@ -10,7 +10,8 @@
# "offset-distance",
# "offset-path",
# "offset-rotate",
-# "offset"
+# "offset",
+# "text-underline-position",
COUNTED_UNKNOWN_PROPERTIES = [
"-webkit-font-smoothing",
"-webkit-tap-highlight-color",
@@ -40,7 +41,6 @@ COUNTED_UNKNOWN_PROPERTIES = [
"baseline-shift",
"-webkit-hyphenate-character",
"page",
- "text-underline-position",
"-webkit-highlight",
"background-repeat-x",
"-webkit-padding-end",
diff --git a/components/style/properties/data.py b/components/style/properties/data.py
index 87ec87a7fa5..15ab380789b 100644
--- a/components/style/properties/data.py
+++ b/components/style/properties/data.py
@@ -385,6 +385,7 @@ class Longhand(object):
"TextDecorationLine",
"TextEmphasisPosition",
"TextTransform",
+ "TextUnderlinePosition",
"TouchAction",
"TransformStyle",
"UserSelect",
diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs
index 930d4400d3d..90dec0a47d7 100644
--- a/components/style/properties/declaration_block.rs
+++ b/components/style/properties/declaration_block.rs
@@ -1433,7 +1433,7 @@ fn report_css_errors(
selectors: Option<&SelectorList<SelectorImpl>>,
errors: &mut SmallParseErrorVec,
) {
- for (error, slice, property) in errors.drain() {
+ for (error, slice, property) in errors.drain(..) {
report_one_css_error(context, Some(block), selectors, error, slice, property)
}
}
diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs
index b6cd741038c..14262e7a074 100644
--- a/components/style/properties/gecko.mako.rs
+++ b/components/style/properties/gecko.mako.rs
@@ -426,7 +426,7 @@ def set_gecko_property(ffi_name, expr):
pub fn copy_${ident}_from(&mut self, other: &Self) {
use crate::gecko_bindings::structs::nsStyleSVG_${ident.upper()}_CONTEXT as CONTEXT_VALUE;
- self.gecko.${gecko_ffi_name} = other.gecko.${gecko_ffi_name};
+ self.gecko.${gecko_ffi_name} = other.gecko.${gecko_ffi_name}.clone();
self.gecko.mContextFlags =
(self.gecko.mContextFlags & !CONTEXT_VALUE) |
(other.gecko.mContextFlags & CONTEXT_VALUE);
@@ -442,7 +442,7 @@ def set_gecko_property(ffi_name, expr):
if (self.gecko.mContextFlags & CONTEXT_VALUE) != 0 {
return SVGLength::ContextValue;
}
- SVGLength::LengthPercentage(self.gecko.${gecko_ffi_name})
+ SVGLength::LengthPercentage(self.gecko.${gecko_ffi_name}.clone())
}
</%def>
@@ -563,7 +563,7 @@ def set_gecko_property(ffi_name, expr):
#[allow(non_snake_case)]
pub fn copy_${ident}_from(&mut self, other: &Self) {
self.gecko.${gecko_ffi_name}.${index} =
- other.gecko.${gecko_ffi_name}.${index};
+ other.gecko.${gecko_ffi_name}.${index}.clone();
}
#[allow(non_snake_case)]
pub fn reset_${ident}(&mut self, other: &Self) {
@@ -572,7 +572,7 @@ def set_gecko_property(ffi_name, expr):
#[allow(non_snake_case)]
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
- self.gecko.${gecko_ffi_name}.${index}
+ self.gecko.${gecko_ffi_name}.${index}.clone()
}
</%def>
@@ -601,7 +601,7 @@ def set_gecko_property(ffi_name, expr):
#[allow(non_snake_case)]
pub fn copy_${ident}_from(&mut self, other: &Self) {
self.gecko.${gecko_ffi_name}.${corner} =
- other.gecko.${gecko_ffi_name}.${corner};
+ other.gecko.${gecko_ffi_name}.${corner}.clone();
}
#[allow(non_snake_case)]
pub fn reset_${ident}(&mut self, other: &Self) {
@@ -609,7 +609,7 @@ def set_gecko_property(ffi_name, expr):
}
#[allow(non_snake_case)]
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
- self.gecko.${gecko_ffi_name}.${corner}
+ self.gecko.${gecko_ffi_name}.${corner}.clone()
}
</%def>
@@ -1134,7 +1134,7 @@ fn static_assert() {
pub fn set_font_size(&mut self, v: FontSize) {
use crate::values::specified::font::KeywordSize;
- let size = v.size();
+ let size = Au::from(v.size());
self.gecko.mScriptUnconstrainedSize = size.0;
// These two may be changed from Cascade::fixup_font_stuff.
@@ -1852,7 +1852,7 @@ fn static_assert() {
for (layer, other) in self.gecko.${layers_field_name}.mLayers.iter_mut()
.zip(other.gecko.${layers_field_name}.mLayers.iter())
.take(count as usize) {
- layer.${field_name} = other.${field_name};
+ layer.${field_name} = other.${field_name}.clone();
}
self.gecko.${layers_field_name}.${field_name}Count = count;
}
@@ -2006,7 +2006,7 @@ fn static_assert() {
for (layer, other) in self.gecko.${image_layers_field}.mLayers.iter_mut()
.zip(other.gecko.${image_layers_field}.mLayers.iter())
.take(count as usize) {
- layer.mPosition.${keyword} = other.mPosition.${keyword};
+ layer.mPosition.${keyword} = other.mPosition.${keyword}.clone();
}
self.gecko.${image_layers_field}.mPosition${orientation.upper()}Count = count;
}
@@ -2020,7 +2020,7 @@ fn static_assert() {
longhands::${shorthand}_position_${orientation}::computed_value::List(
self.gecko.${image_layers_field}.mLayers.iter()
.take(self.gecko.${image_layers_field}.mPosition${orientation.upper()}Count as usize)
- .map(|position| position.mPosition.${keyword})
+ .map(|position| position.mPosition.${keyword}.clone())
.collect()
)
}
@@ -2054,7 +2054,7 @@ fn static_assert() {
pub fn clone_${shorthand}_size(&self) -> longhands::${shorthand}_size::computed_value::T {
longhands::${shorthand}_size::computed_value::List(
- self.gecko.${image_layers_field}.mLayers.iter().map(|layer| layer.mSize).collect()
+ self.gecko.${image_layers_field}.mLayers.iter().map(|layer| layer.mSize.clone()).collect()
)
}
diff --git a/components/style/properties/longhands/border.mako.rs b/components/style/properties/longhands/border.mako.rs
index 4d68c8bfc93..09cbea19a7f 100644
--- a/components/style/properties/longhands/border.mako.rs
+++ b/components/style/properties/longhands/border.mako.rs
@@ -108,7 +108,6 @@ ${helpers.predefined_type(
"border-image-source",
"ImageLayer",
engines="gecko servo-2013 servo-2020",
- servo_2020_pref="layout.2020.unimplemented",
initial_value="computed::ImageLayer::none()",
initial_specified_value="specified::ImageLayer::none()",
spec="https://drafts.csswg.org/css-backgrounds/#the-background-image",
@@ -122,7 +121,6 @@ ${helpers.predefined_type(
"border-image-outset",
"NonNegativeLengthOrNumberRect",
engines="gecko servo-2013 servo-2020",
- servo_2020_pref="layout.2020.unimplemented",
initial_value="generics::rect::Rect::all(computed::NonNegativeLengthOrNumber::zero())",
initial_specified_value="generics::rect::Rect::all(specified::NonNegativeLengthOrNumber::zero())",
spec="https://drafts.csswg.org/css-backgrounds/#border-image-outset",
@@ -135,7 +133,6 @@ ${helpers.predefined_type(
"BorderImageRepeat",
"computed::BorderImageRepeat::stretch()",
engines="gecko servo-2013 servo-2020",
- servo_2020_pref="layout.2020.unimplemented",
initial_specified_value="specified::BorderImageRepeat::stretch()",
animation_value_type="discrete",
spec="https://drafts.csswg.org/css-backgrounds/#the-border-image-repeat",
@@ -145,7 +142,6 @@ ${helpers.predefined_type(
"border-image-width",
"BorderImageWidth",
engines="gecko servo-2013 servo-2020",
- servo_2020_pref="layout.2020.unimplemented",
initial_value="computed::BorderImageWidth::all(computed::BorderImageSideWidth::one())",
initial_specified_value="specified::BorderImageWidth::all(specified::BorderImageSideWidth::one())",
spec="https://drafts.csswg.org/css-backgrounds/#border-image-width",
@@ -157,7 +153,6 @@ ${helpers.predefined_type(
"border-image-slice",
"BorderImageSlice",
engines="gecko servo-2013 servo-2020",
- servo_2020_pref="layout.2020.unimplemented",
initial_value="computed::BorderImageSlice::hundred_percent()",
initial_specified_value="specified::BorderImageSlice::hundred_percent()",
spec="https://drafts.csswg.org/css-backgrounds/#border-image-slice",
diff --git a/components/style/properties/longhands/box.mako.rs b/components/style/properties/longhands/box.mako.rs
index aa6118b8a8a..f5f09f32e6e 100644
--- a/components/style/properties/longhands/box.mako.rs
+++ b/components/style/properties/longhands/box.mako.rs
@@ -24,7 +24,7 @@ ${helpers.single_keyword(
"-moz-top-layer",
"none top",
engines="gecko",
- gecko_constant_prefix="NS_STYLE_TOP_LAYER",
+ gecko_enum_prefix="StyleTopLayer",
gecko_ffi_name="mTopLayer",
animation_value_type="none",
enabled_in="ua",
@@ -494,6 +494,7 @@ ${helpers.single_keyword(
engines="gecko",
spec="https://drafts.fxtf.org/compositing/#isolation",
flags="CREATES_STACKING_CONTEXT",
+ gecko_enum_prefix="StyleIsolation",
animation_value_type="discrete",
)}
diff --git a/components/style/properties/longhands/inherited_box.mako.rs b/components/style/properties/longhands/inherited_box.mako.rs
index a92d638671b..78c2e6023ee 100644
--- a/components/style/properties/longhands/inherited_box.mako.rs
+++ b/components/style/properties/longhands/inherited_box.mako.rs
@@ -16,6 +16,7 @@ ${helpers.single_keyword(
gecko_ffi_name="mVisible",
animation_value_type="ComputedValue",
spec="https://drafts.csswg.org/css-box/#propdef-visibility",
+ gecko_enum_prefix="StyleVisibility",
)}
// CSS Writing Modes Level 3
diff --git a/components/style/properties/longhands/inherited_text.mako.rs b/components/style/properties/longhands/inherited_text.mako.rs
index e7cfbba377b..9784e2529e9 100644
--- a/components/style/properties/longhands/inherited_text.mako.rs
+++ b/components/style/properties/longhands/inherited_text.mako.rs
@@ -53,7 +53,7 @@ ${helpers.single_keyword(
"-moz-text-size-adjust",
"auto none",
engines="gecko",
- gecko_constant_prefix="NS_STYLE_TEXT_SIZE_ADJUST",
+ gecko_enum_prefix="StyleTextSizeAdjust",
gecko_ffi_name="mTextSizeAdjust",
animation_value_type="discrete",
spec="https://drafts.csswg.org/css-size-adjust/#adjustment-control",
@@ -332,6 +332,7 @@ ${helpers.single_keyword(
"space-around start center space-between",
engines="gecko",
animation_value_type="discrete",
+ gecko_enum_prefix="StyleRubyAlign",
spec="https://drafts.csswg.org/css-ruby/#ruby-align-property",
)}
@@ -341,6 +342,7 @@ ${helpers.single_keyword(
engines="gecko",
animation_value_type="discrete",
spec="https://drafts.csswg.org/css-ruby/#ruby-position-property",
+ gecko_enum_prefix="StyleRubyPosition",
)}
// CSS Writing Modes Module Level 3
@@ -389,6 +391,18 @@ ${helpers.predefined_type(
spec="https://drafts.csswg.org/css-text-decor-4/#underline-offset",
)}
+// text underline position
+${helpers.predefined_type(
+ "text-underline-position",
+ "TextUnderlinePosition",
+ "computed::TextUnderlinePosition::AUTO",
+ engines="gecko",
+ animation_value_type="discrete",
+ gecko_pref="layout.css.text-underline-position.enabled",
+ has_effect_on_gecko_scrollbars=False,
+ spec="https://drafts.csswg.org/css-text-decor-3/#text-underline-position-property",
+)}
+
// text decoration skip ink
${helpers.predefined_type(
"text-decoration-skip-ink",
diff --git a/components/style/properties/longhands/inherited_ui.mako.rs b/components/style/properties/longhands/inherited_ui.mako.rs
index a7b83f0ea99..25b53190964 100644
--- a/components/style/properties/longhands/inherited_ui.mako.rs
+++ b/components/style/properties/longhands/inherited_ui.mako.rs
@@ -26,6 +26,7 @@ ${helpers.single_keyword(
animation_value_type="discrete",
extra_gecko_values="visiblepainted visiblefill visiblestroke visible painted fill stroke all",
spec="https://www.w3.org/TR/SVG11/interact.html#PointerEventsProperty",
+ gecko_enum_prefix="StylePointerEvents",
)}
${helpers.single_keyword(
diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs
index 38243aa45e4..30a03f79290 100644
--- a/components/style/properties/properties.mako.rs
+++ b/components/style/properties/properties.mako.rs
@@ -3121,59 +3121,59 @@ impl ComputedValuesInner {
/// Get the logical computed inline size.
#[inline]
- pub fn content_inline_size(&self) -> computed::Size {
+ pub fn content_inline_size(&self) -> &computed::Size {
let position_style = self.get_position();
if self.writing_mode.is_vertical() {
- position_style.height
+ &position_style.height
} else {
- position_style.width
+ &position_style.width
}
}
/// Get the logical computed block size.
#[inline]
- pub fn content_block_size(&self) -> computed::Size {
+ pub fn content_block_size(&self) -> &computed::Size {
let position_style = self.get_position();
- if self.writing_mode.is_vertical() { position_style.width } else { position_style.height }
+ if self.writing_mode.is_vertical() { &position_style.width } else { &position_style.height }
}
/// Get the logical computed min inline size.
#[inline]
- pub fn min_inline_size(&self) -> computed::Size {
+ pub fn min_inline_size(&self) -> &computed::Size {
let position_style = self.get_position();
- if self.writing_mode.is_vertical() { position_style.min_height } else { position_style.min_width }
+ if self.writing_mode.is_vertical() { &position_style.min_height } else { &position_style.min_width }
}
/// Get the logical computed min block size.
#[inline]
- pub fn min_block_size(&self) -> computed::Size {
+ pub fn min_block_size(&self) -> &computed::Size {
let position_style = self.get_position();
- if self.writing_mode.is_vertical() { position_style.min_width } else { position_style.min_height }
+ if self.writing_mode.is_vertical() { &position_style.min_width } else { &position_style.min_height }
}
/// Get the logical computed max inline size.
#[inline]
- pub fn max_inline_size(&self) -> computed::MaxSize {
+ pub fn max_inline_size(&self) -> &computed::MaxSize {
let position_style = self.get_position();
- if self.writing_mode.is_vertical() { position_style.max_height } else { position_style.max_width }
+ if self.writing_mode.is_vertical() { &position_style.max_height } else { &position_style.max_width }
}
/// Get the logical computed max block size.
#[inline]
- pub fn max_block_size(&self) -> computed::MaxSize {
+ pub fn max_block_size(&self) -> &computed::MaxSize {
let position_style = self.get_position();
- if self.writing_mode.is_vertical() { position_style.max_width } else { position_style.max_height }
+ if self.writing_mode.is_vertical() { &position_style.max_width } else { &position_style.max_height }
}
/// Get the logical computed padding for this writing mode.
#[inline]
- pub fn logical_padding(&self) -> LogicalMargin<computed::LengthPercentage> {
+ pub fn logical_padding(&self) -> LogicalMargin<<&computed::LengthPercentage> {
let padding_style = self.get_padding();
LogicalMargin::from_physical(self.writing_mode, SideOffsets2D::new(
- padding_style.padding_top.0,
- padding_style.padding_right.0,
- padding_style.padding_bottom.0,
- padding_style.padding_left.0,
+ &padding_style.padding_top.0,
+ &padding_style.padding_right.0,
+ &padding_style.padding_bottom.0,
+ &padding_style.padding_left.0,
))
}
@@ -3197,26 +3197,26 @@ impl ComputedValuesInner {
/// Gets the logical computed margin from this style.
#[inline]
- pub fn logical_margin(&self) -> LogicalMargin<computed::LengthPercentageOrAuto> {
+ pub fn logical_margin(&self) -> LogicalMargin<<&computed::LengthPercentageOrAuto> {
let margin_style = self.get_margin();
LogicalMargin::from_physical(self.writing_mode, SideOffsets2D::new(
- margin_style.margin_top,
- margin_style.margin_right,
- margin_style.margin_bottom,
- margin_style.margin_left,
+ &margin_style.margin_top,
+ &margin_style.margin_right,
+ &margin_style.margin_bottom,
+ &margin_style.margin_left,
))
}
/// Gets the logical position from this style.
#[inline]
- pub fn logical_position(&self) -> LogicalMargin<computed::LengthPercentageOrAuto> {
+ pub fn logical_position(&self) -> LogicalMargin<<&computed::LengthPercentageOrAuto> {
// FIXME(SimonSapin): should be the writing mode of the containing block, maybe?
let position_style = self.get_position();
LogicalMargin::from_physical(self.writing_mode, SideOffsets2D::new(
- position_style.top,
- position_style.right,
- position_style.bottom,
- position_style.left,
+ &position_style.top,
+ &position_style.right,
+ &position_style.bottom,
+ &position_style.left,
))
}
diff --git a/components/style/properties/shorthands/border.mako.rs b/components/style/properties/shorthands/border.mako.rs
index c1bf200fe45..d584e568aed 100644
--- a/components/style/properties/shorthands/border.mako.rs
+++ b/components/style/properties/shorthands/border.mako.rs
@@ -179,6 +179,16 @@ pub fn parse_border<'i, 't>(
impl<'a> ToCss for LonghandsToSerialize<'a> {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write {
+ use crate::properties::longhands;
+
+ // If any of the border-image longhands differ from their initial specified values we should not
+ // invoke serialize_directional_border(), so there is no point in continuing on to compute all_equal.
+ % for name in "outset repeat slice source width".split():
+ if *self.border_image_${name} != longhands::border_image_${name}::get_initial_specified_value() {
+ return Ok(());
+ }
+ % endfor
+
let all_equal = {
% for side in PHYSICAL_SIDES:
let border_${side}_width = self.border_${side}_width;
diff --git a/components/style/rule_collector.rs b/components/style/rule_collector.rs
index ab1fb88d7f2..9841eb9e70f 100644
--- a/components/style/rule_collector.rs
+++ b/components/style/rule_collector.rs
@@ -348,7 +348,8 @@ where
return;
}
- let outer_shadow = inner_shadow.host().containing_shadow();
+ let inner_shadow_host = inner_shadow.host();
+ let outer_shadow = inner_shadow_host.containing_shadow();
let part_rules = match outer_shadow {
Some(shadow) => shadow
.style_data()
@@ -387,8 +388,6 @@ where
shadow_cascade_order.inc();
}
- let inner_shadow_host = inner_shadow.host();
-
inner_shadow = match outer_shadow {
Some(s) => s,
None => break, // Nowhere to export to.
diff --git a/components/style/rule_tree/mod.rs b/components/style/rule_tree/mod.rs
index 7cb153de375..19e3accb851 100644
--- a/components/style/rule_tree/mod.rs
+++ b/components/style/rule_tree/mod.rs
@@ -345,7 +345,7 @@ impl RuleTree {
important_author.sort_by_key(|&(_, order)| -order);
}
- for (source, shadow_cascade_order) in important_author.drain() {
+ for (source, shadow_cascade_order) in important_author.drain(..) {
current = current.ensure_child(
self.root.downgrade(),
source,
@@ -355,11 +355,11 @@ impl RuleTree {
);
}
- for source in important_user.drain() {
+ for source in important_user.drain(..) {
current = current.ensure_child(self.root.downgrade(), source, UserImportant);
}
- for source in important_ua.drain() {
+ for source in important_ua.drain(..) {
current = current.ensure_child(self.root.downgrade(), source, UAImportant);
}
@@ -378,7 +378,7 @@ impl RuleTree {
guards: &StylesheetGuards,
) -> StrongRuleNode {
self.insert_ordered_rules_with_important(
- applicable_declarations.drain().map(|d| d.for_rule_tree()),
+ applicable_declarations.drain(..).map(|d| d.for_rule_tree()),
guards,
)
}
@@ -556,7 +556,7 @@ impl RuleTree {
// Now the rule is in the relevant place, push the children as
// necessary.
- let rule = self.insert_ordered_rules_from(current, children.drain().rev());
+ let rule = self.insert_ordered_rules_from(current, children.drain(..).rev());
Some(rule)
}
@@ -592,8 +592,8 @@ impl RuleTree {
last = node;
}
- let rule =
- self.insert_ordered_rules_from(last.parent().unwrap().clone(), children.drain().rev());
+ let rule = self
+ .insert_ordered_rules_from(last.parent().unwrap().clone(), children.drain(..).rev());
rule
}
diff --git a/components/style/servo/media_queries.rs b/components/style/servo/media_queries.rs
index df7bf93b8ac..4cdfc80eef7 100644
--- a/components/style/servo/media_queries.rs
+++ b/components/style/servo/media_queries.rs
@@ -10,8 +10,8 @@ use crate::media_queries::media_feature::{Evaluator, MediaFeatureDescription};
use crate::media_queries::media_feature_expression::RangeOrOperator;
use crate::media_queries::MediaType;
use crate::properties::ComputedValues;
-use crate::values::computed::font::FontSize;
use crate::values::computed::CSSPixelLength;
+use crate::values::specified::font::FONT_MEDIUM_PX;
use crate::values::KeyframesName;
use app_units::Au;
use cssparser::RGBA;
@@ -68,7 +68,7 @@ impl Device {
viewport_size,
device_pixel_ratio,
// FIXME(bz): Seems dubious?
- root_font_size: AtomicIsize::new(FontSize::medium().size().0 as isize),
+ root_font_size: AtomicIsize::new(Au::from_px(FONT_MEDIUM_PX).0 as isize),
used_root_font_size: AtomicBool::new(false),
used_viewport_units: AtomicBool::new(false),
environment: CssEnvironment,
diff --git a/components/style/servo/selector_parser.rs b/components/style/servo/selector_parser.rs
index 977a6c59a85..942dcdba1bb 100644
--- a/components/style/servo/selector_parser.rs
+++ b/components/style/servo/selector_parser.rs
@@ -309,6 +309,11 @@ impl ::selectors::parser::NonTSPseudoClass for NonTSPseudoClass {
NonTSPseudoClass::Active | NonTSPseudoClass::Hover | NonTSPseudoClass::Focus
)
}
+
+ #[inline]
+ fn has_zero_specificity(&self) -> bool {
+ false
+ }
}
impl ToCss for NonTSPseudoClass {
diff --git a/components/style/stylesheets/mod.rs b/components/style/stylesheets/mod.rs
index b74413866f5..c9697ead615 100644
--- a/components/style/stylesheets/mod.rs
+++ b/components/style/stylesheets/mod.rs
@@ -59,6 +59,7 @@ pub use self::rules_iterator::{AllRules, EffectiveRules};
pub use self::rules_iterator::{NestedRuleIterationCondition, RulesIterator};
pub use self::style_rule::StyleRule;
pub use self::stylesheet::{DocumentStyleSheet, Namespaces, Stylesheet};
+pub use self::stylesheet::{SanitizationData, SanitizationKind};
pub use self::stylesheet::{StylesheetContents, StylesheetInDocument, UserAgentStylesheets};
pub use self::supports_rule::SupportsRule;
pub use self::viewport_rule::ViewportRule;
diff --git a/components/style/stylesheets/namespace_rule.rs b/components/style/stylesheets/namespace_rule.rs
index 81a92f1c300..d76703e4f81 100644
--- a/components/style/stylesheets/namespace_rule.rs
+++ b/components/style/stylesheets/namespace_rule.rs
@@ -7,8 +7,9 @@
use crate::shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
use crate::str::CssStringWriter;
use crate::{Namespace, Prefix};
-use cssparser::SourceLocation;
+use cssparser::{self, SourceLocation};
use std::fmt::{self, Write};
+use style_traits::{CssWriter, ToCss};
/// A `@namespace` rule.
#[derive(Clone, Debug, PartialEq, ToShmem)]
@@ -27,13 +28,12 @@ impl ToCssWithGuard for NamespaceRule {
fn to_css(&self, _guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result {
dest.write_str("@namespace ")?;
if let Some(ref prefix) = self.prefix {
- dest.write_str(&*prefix.to_string())?;
+ let prefix = prefix.to_string();
+ cssparser::serialize_identifier(&prefix, dest)?;
dest.write_str(" ")?;
}
-
- // FIXME(emilio): Pretty sure this needs some escaping, or something?
- dest.write_str("url(\"")?;
- dest.write_str(&*self.url.to_string())?;
- dest.write_str("\");")
+ dest.write_str("url(")?;
+ self.url.to_string().to_css(&mut CssWriter::new(dest))?;
+ dest.write_str(");")
}
}
diff --git a/components/style/stylesheets/stylesheet.rs b/components/style/stylesheets/stylesheet.rs
index f5194d7d443..068bfb6502a 100644
--- a/components/style/stylesheets/stylesheet.rs
+++ b/components/style/stylesheets/stylesheet.rs
@@ -81,6 +81,7 @@ impl StylesheetContents {
quirks_mode: QuirksMode,
line_number_offset: u32,
use_counters: Option<&UseCounters>,
+ sanitization_data: Option<&mut SanitizationData>,
) -> Self {
let namespaces = RwLock::new(Namespaces::default());
let (rules, source_map_url, source_url) = Stylesheet::parse_rules(
@@ -94,6 +95,7 @@ impl StylesheetContents {
quirks_mode,
line_number_offset,
use_counters,
+ sanitization_data,
);
Self {
@@ -341,6 +343,69 @@ impl StylesheetInDocument for DocumentStyleSheet {
}
}
+/// The kind of sanitization to use when parsing a stylesheet.
+#[repr(u8)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub enum SanitizationKind {
+ /// Perform no sanitization.
+ None,
+ /// Allow only @font-face, style rules, and @namespace.
+ Standard,
+ /// Allow everything but conditional rules.
+ NoConditionalRules,
+}
+
+impl SanitizationKind {
+ fn allows(self, rule: &CssRule) -> bool {
+ debug_assert_ne!(self, SanitizationKind::None);
+ // NOTE(emilio): If this becomes more complex (not filtering just by
+ // top-level rules), we should thread all the data through nested rules
+ // and such. But this doesn't seem necessary at the moment.
+ let is_standard = matches!(self, SanitizationKind::Standard);
+ match *rule {
+ CssRule::Document(..) |
+ CssRule::Media(..) |
+ CssRule::Supports(..) |
+ CssRule::Import(..) => false,
+
+ CssRule::FontFace(..) | CssRule::Namespace(..) | CssRule::Style(..) => true,
+
+ CssRule::Keyframes(..) |
+ CssRule::Page(..) |
+ CssRule::FontFeatureValues(..) |
+ CssRule::Viewport(..) |
+ CssRule::CounterStyle(..) => !is_standard,
+ }
+ }
+}
+
+/// A struct to hold the data relevant to style sheet sanitization.
+#[derive(Debug)]
+pub struct SanitizationData {
+ kind: SanitizationKind,
+ output: String,
+}
+
+impl SanitizationData {
+ /// Create a new input for sanitization.
+ #[inline]
+ pub fn new(kind: SanitizationKind) -> Option<Self> {
+ if matches!(kind, SanitizationKind::None) {
+ return None;
+ }
+ Some(Self {
+ kind,
+ output: String::new(),
+ })
+ }
+
+ /// Take the sanitized output.
+ #[inline]
+ pub fn take(self) -> String {
+ self.output
+ }
+}
+
impl Stylesheet {
/// Updates an empty stylesheet from a given string of text.
pub fn update_from_str(
@@ -365,6 +430,7 @@ impl Stylesheet {
existing.contents.quirks_mode,
line_number_offset,
/* use_counters = */ None,
+ /* sanitization_data = */ None,
);
*existing.contents.url_data.write() = url_data;
@@ -391,6 +457,7 @@ impl Stylesheet {
quirks_mode: QuirksMode,
line_number_offset: u32,
use_counters: Option<&UseCounters>,
+ mut sanitization_data: Option<&mut SanitizationData>,
) -> (Vec<CssRule>, Option<String>, Option<String>) {
let mut rules = Vec::new();
let mut input = ParserInput::new_with_line_number_offset(css, line_number_offset);
@@ -419,12 +486,24 @@ impl Stylesheet {
{
let mut iter = RuleListParser::new_for_stylesheet(&mut input, rule_parser);
- while let Some(result) = iter.next() {
+ loop {
+ let rule_start = iter.input.position().byte_index();
+ let result = match iter.next() {
+ Some(result) => result,
+ None => break,
+ };
match result {
Ok(rule) => {
- // Use a fallible push here, and if it fails, just
- // fall out of the loop. This will cause the page to
- // be shown incorrectly, but it's better than OOMing.
+ if let Some(ref mut data) = sanitization_data {
+ if !data.kind.allows(&rule) {
+ continue;
+ }
+ let end = iter.input.position().byte_index();
+ data.output.push_str(&css[rule_start..end]);
+ }
+ // Use a fallible push here, and if it fails, just fall
+ // out of the loop. This will cause the page to be
+ // shown incorrectly, but it's better than OOMing.
if rules.try_push(rule).is_err() {
break;
}
@@ -470,6 +549,7 @@ impl Stylesheet {
quirks_mode,
line_number_offset,
/* use_counters = */ None,
+ /* sanitized_output = */ None,
);
Stylesheet {
diff --git a/components/style/stylist.rs b/components/style/stylist.rs
index 83db2ec4b17..9de1ec4e71b 100644
--- a/components/style/stylist.rs
+++ b/components/style/stylist.rs
@@ -1013,7 +1013,7 @@ impl Stylist {
);
if !declarations.is_empty() {
let rule_node = self.rule_tree.insert_ordered_rules_with_important(
- declarations.drain().map(|a| a.for_rule_tree()),
+ declarations.drain(..).map(|a| a.for_rule_tree()),
guards,
);
if rule_node != *self.rule_tree.root() {
@@ -1889,18 +1889,33 @@ impl CascadeData {
self.host_rules.as_ref().and_then(|d| d.rules(pseudo))
}
+ /// Whether there's any host rule that could match in this scope.
+ pub fn any_host_rules(&self) -> bool {
+ self.host_rules.is_some()
+ }
+
/// Returns the slotted rule map for a given pseudo-element.
#[inline]
pub fn slotted_rules(&self, pseudo: Option<&PseudoElement>) -> Option<&SelectorMap<Rule>> {
self.slotted_rules.as_ref().and_then(|d| d.rules(pseudo))
}
+ /// Whether there's any ::slotted rule that could match in this scope.
+ pub fn any_slotted_rule(&self) -> bool {
+ self.slotted_rules.is_some()
+ }
+
/// Returns the parts rule map for a given pseudo-element.
#[inline]
pub fn part_rules(&self, pseudo: Option<&PseudoElement>) -> Option<&PartMap> {
self.part_rules.as_ref().and_then(|d| d.rules(pseudo))
}
+ /// Whether there's any ::part rule that could match in this scope.
+ pub fn any_part_rule(&self) -> bool {
+ self.part_rules.is_some()
+ }
+
/// Collects all the applicable media query results into `results`.
///
/// This duplicates part of the logic in `add_stylesheet`, which is
diff --git a/components/style/values/animated/transform.rs b/components/style/values/animated/transform.rs
index aceb70f6766..3d93ae93f6d 100644
--- a/components/style/values/animated/transform.rs
+++ b/components/style/values/animated/transform.rs
@@ -1373,7 +1373,7 @@ impl ComputedTranslate {
LengthPercentage::zero(),
Length::zero(),
),
- Translate::Translate(tx, ty, tz) => (tx, ty, tz),
+ Translate::Translate(ref tx, ref ty, ref tz) => (tx.clone(), ty.clone(), tz.clone()),
}
}
}
diff --git a/components/style/values/computed/font.rs b/components/style/values/computed/font.rs
index a4fa6013277..658d3412475 100644
--- a/components/style/values/computed/font.rs
+++ b/components/style/values/computed/font.rs
@@ -21,7 +21,6 @@ use crate::values::specified::font::{
use crate::values::specified::length::{FontBaseSize, NoCalcLength};
use crate::values::CSSFloat;
use crate::Atom;
-use app_units::Au;
use byteorder::{BigEndian, ByteOrder};
use cssparser::{serialize_identifier, CssStringWriter, Parser};
#[cfg(feature = "gecko")]
@@ -148,15 +147,16 @@ impl FontWeight {
impl FontSize {
/// The actual computed font size.
- pub fn size(self) -> Au {
- self.size.into()
+ #[inline]
+ pub fn size(&self) -> Length {
+ self.size.0
}
#[inline]
/// Get default value of font size.
pub fn medium() -> Self {
Self {
- size: Au::from_px(specified::FONT_MEDIUM_PX).into(),
+ size: NonNegative(Length::new(specified::FONT_MEDIUM_PX as CSSFloat)),
keyword_info: Some(KeywordInfo::medium()),
}
}
diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs
index 2423d447a6a..c9248f97c95 100644
--- a/components/style/values/computed/length.rs
+++ b/components/style/values/computed/length.rs
@@ -29,7 +29,7 @@ pub use crate::values::specified::url::UrlOrNone;
pub use crate::values::specified::{Angle, BorderStyle, Time};
impl ToComputedValue for specified::NoCalcLength {
- type ComputedValue = CSSPixelLength;
+ type ComputedValue = Length;
#[inline]
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
@@ -75,9 +75,7 @@ impl ToComputedValue for specified::Length {
///
/// https://drafts.csswg.org/css-values-4/#typedef-length-percentage
#[allow(missing_docs)]
-#[derive(
- Clone, Copy, Debug, Deserialize, MallocSizeOf, Serialize, ToAnimatedZero, ToResolvedValue,
-)]
+#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize, ToAnimatedZero, ToResolvedValue)]
#[repr(C)]
pub struct LengthPercentage {
length: Length,
@@ -543,14 +541,14 @@ impl ToAnimatedValue for NonNegativeLengthPercentage {
impl From<NonNegativeLength> for NonNegativeLengthPercentage {
#[inline]
fn from(length: NonNegativeLength) -> Self {
- LengthPercentage::new(length.0, None).into()
+ NonNegative(LengthPercentage::new(length.0, None))
}
}
impl From<LengthPercentage> for NonNegativeLengthPercentage {
#[inline]
fn from(lp: LengthPercentage) -> Self {
- NonNegative::<LengthPercentage>(lp)
+ NonNegative(lp)
}
}
diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs
index 6e6f20ad0fe..f5b3440f426 100644
--- a/components/style/values/computed/mod.rs
+++ b/components/style/values/computed/mod.rs
@@ -75,6 +75,7 @@ pub use self::resolution::Resolution;
pub use self::svg::MozContextProperties;
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind};
pub use self::svg::{SVGPaintOrder, SVGStrokeDashArray, SVGWidth};
+pub use self::text::TextUnderlinePosition;
pub use self::text::{InitialLetter, LetterSpacing, LineBreak, LineHeight};
pub use self::text::{OverflowWrap, TextOverflow, WordBreak, WordSpacing};
pub use self::text::{TextAlign, TextEmphasisPosition, TextEmphasisStyle};
diff --git a/components/style/values/computed/text.rs b/components/style/values/computed/text.rs
index 4cccd248d1c..3f9ffb2ad0f 100644
--- a/components/style/values/computed/text.rs
+++ b/components/style/values/computed/text.rs
@@ -19,6 +19,7 @@ use std::fmt::{self, Write};
use style_traits::{CssWriter, ToCss};
pub use crate::values::specified::TextAlignKeyword as TextAlign;
+pub use crate::values::specified::TextUnderlinePosition;
pub use crate::values::specified::{LineBreak, OverflowWrap, WordBreak};
pub use crate::values::specified::{TextDecorationLine, TextEmphasisPosition};
pub use crate::values::specified::{TextDecorationSkipInk, TextTransform};
diff --git a/components/style/values/generics/length.rs b/components/style/values/generics/length.rs
index b2f34058283..4183f40a942 100644
--- a/components/style/values/generics/length.rs
+++ b/components/style/values/generics/length.rs
@@ -207,15 +207,6 @@ impl<LengthPercentage> MaxSize<LengthPercentage> {
pub fn none() -> Self {
MaxSize::None
}
-
- /// Convert
- #[cfg(not(feature = "gecko"))]
- pub fn to_option(self) -> Option<LengthPercentage> {
- match self {
- Self::LengthPercentage(lp) => Some(lp),
- Self::None => None,
- }
- }
}
/// A generic `<length>` | `<number>` value for the `-moz-tab-size` property.
diff --git a/components/style/values/specified/align.rs b/components/style/values/specified/align.rs
index 7c2ecda19a4..0dc1e422515 100644
--- a/components/style/values/specified/align.rs
+++ b/components/style/values/specified/align.rs
@@ -691,11 +691,11 @@ fn parse_baseline<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, Pars
"first" => {
input.expect_ident_matching("baseline")?;
Ok(AlignFlags::BASELINE)
- }
+ },
"last" => {
input.expect_ident_matching("baseline")?;
Ok(AlignFlags::LAST_BASELINE)
- }
+ },
}
}
@@ -794,7 +794,7 @@ fn parse_legacy<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseE
.unwrap_or(AlignFlags::empty());
return Ok(AlignFlags::LEGACY | flags)
- }
+ },
"left" => AlignFlags::LEFT,
"right" => AlignFlags::RIGHT,
"center" => AlignFlags::CENTER,
diff --git a/components/style/values/specified/box.rs b/components/style/values/specified/box.rs
index 1fea857d3e8..ad8602ac431 100644
--- a/components/style/values/specified/box.rs
+++ b/components/style/values/specified/box.rs
@@ -389,21 +389,10 @@ impl Display {
};
Display::from3(DisplayOutside::Block, inside, self.is_list_item())
},
- // If this pref is true, then we'll blockify "-moz-inline-box" to
- // "-moz-box", and blockify "-moz-box" to itself. Otherwise, we
- // blockify both to "block".
#[cfg(feature = "gecko")]
- DisplayOutside::XUL => {
- if static_prefs::pref!(
- "layout.css.xul-box-display-values.survive-blockification.enabled"
- ) {
- match self.inside() {
- DisplayInside::MozInlineBox | DisplayInside::MozBox => Display::MozBox,
- _ => Display::Block,
- }
- } else {
- Display::Block
- }
+ DisplayOutside::XUL => match self.inside() {
+ DisplayInside::MozInlineBox | DisplayInside::MozBox => Display::MozBox,
+ _ => Display::Block,
},
DisplayOutside::Block | DisplayOutside::None => *self,
#[cfg(any(feature = "servo-layout-2013", feature = "gecko"))]
diff --git a/components/style/values/specified/font.rs b/components/style/values/specified/font.rs
index c09d5a2c34c..05a29c94087 100644
--- a/components/style/values/specified/font.rs
+++ b/components/style/values/specified/font.rs
@@ -20,7 +20,6 @@ use crate::values::specified::{AllowQuirks, Angle, Integer, LengthPercentage};
use crate::values::specified::{NoCalcLength, NonNegativeNumber, Number, Percentage};
use crate::values::CustomIdent;
use crate::Atom;
-use app_units::Au;
use byteorder::{BigEndian, ByteOrder};
use cssparser::{Parser, Token};
#[cfg(feature = "gecko")]
@@ -773,18 +772,18 @@ impl ToComputedValue for KeywordSize {
type ComputedValue = NonNegativeLength;
#[inline]
fn to_computed_value(&self, _: &Context) -> NonNegativeLength {
+ let medium = Length::new(FONT_MEDIUM_PX as f32);
// https://drafts.csswg.org/css-fonts-3/#font-size-prop
- match *self {
- KeywordSize::XXSmall => Au::from_px(FONT_MEDIUM_PX) * 3 / 5,
- KeywordSize::XSmall => Au::from_px(FONT_MEDIUM_PX) * 3 / 4,
- KeywordSize::Small => Au::from_px(FONT_MEDIUM_PX) * 8 / 9,
- KeywordSize::Medium => Au::from_px(FONT_MEDIUM_PX),
- KeywordSize::Large => Au::from_px(FONT_MEDIUM_PX) * 6 / 5,
- KeywordSize::XLarge => Au::from_px(FONT_MEDIUM_PX) * 3 / 2,
- KeywordSize::XXLarge => Au::from_px(FONT_MEDIUM_PX) * 2,
- KeywordSize::XXXLarge => Au::from_px(FONT_MEDIUM_PX) * 3,
- }
- .into()
+ NonNegative(match *self {
+ KeywordSize::XXSmall => medium * 3.0 / 5.0,
+ KeywordSize::XSmall => medium * 3.0 / 4.0,
+ KeywordSize::Small => medium * 8.0 / 9.0,
+ KeywordSize::Medium => medium,
+ KeywordSize::Large => medium * 6.0 / 5.0,
+ KeywordSize::XLarge => medium * 3.0 / 2.0,
+ KeywordSize::XXLarge => medium * 2.0,
+ KeywordSize::XXXLarge => medium * 3.0,
+ })
}
#[inline]
@@ -799,7 +798,6 @@ impl ToComputedValue for KeywordSize {
#[inline]
fn to_computed_value(&self, cx: &Context) -> NonNegativeLength {
use crate::context::QuirksMode;
- use crate::values::specified::length::au_to_int_px;
// The tables in this function are originally from
// nsRuleNode::CalcFontPointSize in Gecko:
@@ -850,22 +848,21 @@ impl ToComputedValue for KeywordSize {
Atom::with(gecko_font.mLanguage.mRawPtr, |atom| {
cx.font_metrics_provider
.get_size(atom, gecko_font.mGenericID)
- .0
})
};
- let base_size_px = au_to_int_px(base_size as f32);
+ let base_size_px = base_size.px().round() as i32;
let html_size = self.html_size() as usize;
- if base_size_px >= 9 && base_size_px <= 16 {
+ NonNegative(if base_size_px >= 9 && base_size_px <= 16 {
let mapping = if cx.quirks_mode == QuirksMode::Quirks {
QUIRKS_FONT_SIZE_MAPPING
} else {
FONT_SIZE_MAPPING
};
- Au::from_px(mapping[(base_size_px - 9) as usize][html_size]).into()
+ Length::new(mapping[(base_size_px - 9) as usize][html_size] as f32)
} else {
- Au(FONT_SIZE_FACTORS[html_size] * base_size / 100).into()
- }
+ base_size * FONT_SIZE_FACTORS[html_size] as f32 / 100.0
+ })
}
#[inline]
@@ -927,7 +924,7 @@ impl FontSize {
// If the parent font was keyword-derived, this is too.
// Tack the % onto the factor
info = compose_keyword(pc.0);
- base_size.resolve(context).scale_by(pc.0).into()
+ base_size.resolve(context) * pc.0
},
FontSize::Length(LengthPercentage::Calc(ref calc)) => {
let parent = context.style().get_parent_font().clone_font_size();
@@ -964,7 +961,7 @@ impl FontSize {
// others should reject negatives during parsing. But SMIL
// allows parsing negatives, and relies on us _not_ doing that
// clamping. That's so bonkers :(
- CSSPixelLength::from(calc.to_used_value(base_size.resolve(context)))
+ calc.percentage_relative_to(base_size.resolve(context))
.clamp_to_non_negative()
},
FontSize::Keyword(i) => {
diff --git a/components/style/values/specified/gecko.rs b/components/style/values/specified/gecko.rs
index 131c2a1a314..4c85d1df668 100644
--- a/components/style/values/specified/gecko.rs
+++ b/components/style/values/specified/gecko.rs
@@ -5,8 +5,7 @@
//! Specified types for legacy Gecko-only properties.
use crate::parser::{Parse, ParserContext};
-use crate::values::computed::length::CSSPixelLength;
-use crate::values::computed::{self, LengthPercentage};
+use crate::values::computed::{self, Length, LengthPercentage};
use crate::values::generics::rect::Rect;
use cssparser::{Parser, Token};
use std::fmt;
@@ -24,7 +23,7 @@ fn parse_pixel_or_percent<'i, 't>(
value, ref unit, ..
} => {
match_ignore_ascii_case! { unit,
- "px" => Ok(LengthPercentage::new(CSSPixelLength::new(value), None)),
+ "px" => Ok(LengthPercentage::new(Length::new(value), None)),
_ => Err(()),
}
},
diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs
index ebf7746ee11..d9a51665ead 100644
--- a/components/style/values/specified/length.rs
+++ b/components/style/values/specified/length.rs
@@ -47,14 +47,6 @@ pub const AU_PER_PT: CSSFloat = AU_PER_IN / 72.;
/// Number of app units per pica
pub const AU_PER_PC: CSSFloat = AU_PER_PT * 12.;
-/// Same as Gecko's AppUnitsToIntCSSPixels
-///
-/// Converts app units to integer pixel values,
-/// rounding during the conversion
-pub fn au_to_int_px(au: f32) -> i32 {
- (au / AU_PER_PX).round() as i32
-}
-
/// A font relative length.
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss, ToShmem)]
pub enum FontRelativeLength {
@@ -87,7 +79,7 @@ pub enum FontBaseSize {
impl FontBaseSize {
/// Calculate the actual size for a given context
- pub fn resolve(&self, context: &Context) -> Au {
+ pub fn resolve(&self, context: &Context) -> computed::Length {
match *self {
FontBaseSize::CurrentStyle => context.style().get_font().clone_font_size().size(),
FontBaseSize::InheritedStyleButStripEmUnits | FontBaseSize::InheritedStyle => {
@@ -109,13 +101,13 @@ impl FontRelativeLength {
}
/// Computes the font-relative length.
- pub fn to_computed_value(&self, context: &Context, base_size: FontBaseSize) -> CSSPixelLength {
- use std::f32;
+ pub fn to_computed_value(
+ &self,
+ context: &Context,
+ base_size: FontBaseSize,
+ ) -> computed::Length {
let (reference_size, length) = self.reference_font_size_and_length(context, base_size);
- let pixel = (length * reference_size.to_f32_px())
- .min(f32::MAX)
- .max(f32::MIN);
- CSSPixelLength::new(pixel)
+ reference_size * length
}
/// Return reference font size.
@@ -129,7 +121,7 @@ impl FontRelativeLength {
&self,
context: &Context,
base_size: FontBaseSize,
- ) -> (Au, CSSFloat) {
+ ) -> (computed::Length, CSSFloat) {
fn query_font_metrics(
context: &Context,
base_size: FontBaseSize,
@@ -153,7 +145,7 @@ impl FontRelativeLength {
}
if base_size == FontBaseSize::InheritedStyleButStripEmUnits {
- (Au(0), length)
+ (Zero::zero(), length)
} else {
(reference_font_size, length)
}
@@ -175,7 +167,7 @@ impl FontRelativeLength {
// determine the x-height, a value of 0.5em must be
// assumed.
//
- reference_font_size.scale_by(0.5)
+ reference_font_size * 0.5
});
(reference_size, length)
},
@@ -210,7 +202,7 @@ impl FontRelativeLength {
if wm.is_vertical() && wm.is_upright() {
reference_font_size
} else {
- reference_font_size.scale_by(0.5)
+ reference_font_size * 0.5
}
});
(reference_size, length)
@@ -225,7 +217,7 @@ impl FontRelativeLength {
let reference_size = if context.is_root_element || context.in_media_query {
reference_font_size
} else {
- context.device().root_font_size()
+ computed::Length::new(context.device().root_font_size().to_f32_px())
};
(reference_size, length)
},
@@ -290,15 +282,14 @@ pub struct CharacterWidth(pub i32);
impl CharacterWidth {
/// Computes the given character width.
- pub fn to_computed_value(&self, reference_font_size: Au) -> CSSPixelLength {
- // This applies the *converting a character width to pixels* algorithm as specified
- // in HTML5 § 14.5.4.
+ pub fn to_computed_value(&self, reference_font_size: computed::Length) -> computed::Length {
+ // This applies the *converting a character width to pixels* algorithm
+ // as specified in HTML5 § 14.5.4.
//
// TODO(pcwalton): Find these from the font.
- let average_advance = reference_font_size.scale_by(0.5);
+ let average_advance = reference_font_size * 0.5;
let max_advance = reference_font_size;
- let au = average_advance.scale_by(self.0 as CSSFloat - 1.0) + max_advance;
- au.into()
+ average_advance * (self.0 as CSSFloat - 1.0) + max_advance
}
}
diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs
index bc7a8203dee..7f3ecfb96b3 100644
--- a/components/style/values/specified/mod.rs
+++ b/components/style/values/specified/mod.rs
@@ -80,6 +80,7 @@ pub use self::svg::MozContextProperties;
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint};
pub use self::svg::{SVGPaintOrder, SVGStrokeDashArray, SVGWidth};
pub use self::svg_path::SVGPathData;
+pub use self::text::TextUnderlinePosition;
pub use self::text::{InitialLetter, LetterSpacing, LineBreak, LineHeight, TextAlign};
pub use self::text::{OverflowWrap, TextEmphasisPosition, TextEmphasisStyle, WordBreak};
pub use self::text::{TextAlignKeyword, TextDecorationLine, TextOverflow, WordSpacing};
diff --git a/components/style/values/specified/text.rs b/components/style/values/specified/text.rs
index cc4bcee1a55..8c50a61ef94 100644
--- a/components/style/values/specified/text.rs
+++ b/components/style/values/specified/text.rs
@@ -77,7 +77,6 @@ impl ToComputedValue for LineHeight {
#[inline]
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
- use crate::values::computed::Length as ComputedLength;
use crate::values::specified::length::FontBaseSize;
match *self {
GenericLineHeight::Normal => GenericLineHeight::Normal,
@@ -97,16 +96,8 @@ impl ToComputedValue for LineHeight {
LengthPercentage::Calc(ref calc) => {
let computed_calc =
calc.to_computed_value_zoomed(context, FontBaseSize::CurrentStyle);
- let font_relative_length =
- FontRelativeLength::Em(computed_calc.percentage())
- .to_computed_value(context, FontBaseSize::CurrentStyle)
- .px();
-
- let absolute_length = computed_calc.unclamped_length().px();
- let pixel = computed_calc
- .clamping_mode
- .clamp(absolute_length + font_relative_length);
- ComputedLength::new(pixel)
+ let base = context.style().get_font().clone_font_size().size();
+ computed_calc.percentage_relative_to(base)
},
};
GenericLineHeight::Length(result.into())
@@ -1054,3 +1045,98 @@ impl TextDecorationLength {
matches!(*self, GenericTextDecorationLength::Auto)
}
}
+
+bitflags! {
+ #[derive(MallocSizeOf, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem)]
+ #[value_info(other_values = "auto,under,left,right")]
+ #[repr(C)]
+ /// Specified keyword values for the text-underline-position property.
+ /// (Non-exclusive, but not all combinations are allowed: only `under` may occur
+ /// together with either `left` or `right`.)
+ /// https://drafts.csswg.org/css-text-decor-3/#text-underline-position-property
+ pub struct TextUnderlinePosition: u8 {
+ /// Use automatic positioning below the alphabetic baseline.
+ const AUTO = 0;
+ /// Below the glyph box.
+ const UNDER = 1 << 0;
+ /// In vertical mode, place to the left of the text.
+ const LEFT = 1 << 1;
+ /// In vertical mode, place to the right of the text.
+ const RIGHT = 1 << 2;
+ }
+}
+
+impl Parse for TextUnderlinePosition {
+ fn parse<'i, 't>(
+ _context: &ParserContext,
+ input: &mut Parser<'i, 't>,
+ ) -> Result<TextUnderlinePosition, ParseError<'i>> {
+ let mut result = TextUnderlinePosition::empty();
+
+ loop {
+ let location = input.current_source_location();
+ let ident = match input.next() {
+ Ok(&Token::Ident(ref ident)) => ident,
+ Ok(other) => return Err(location.new_unexpected_token_error(other.clone())),
+ Err(..) => break,
+ };
+
+ match_ignore_ascii_case! { ident,
+ "auto" if result.is_empty() => {
+ return Ok(result);
+ },
+ "under" if !result.intersects(TextUnderlinePosition::UNDER) => {
+ result.insert(TextUnderlinePosition::UNDER);
+ },
+ "left" if !result.intersects(TextUnderlinePosition::LEFT |
+ TextUnderlinePosition::RIGHT) => {
+ result.insert(TextUnderlinePosition::LEFT);
+ },
+ "right" if !result.intersects(TextUnderlinePosition::LEFT |
+ TextUnderlinePosition::RIGHT) => {
+ result.insert(TextUnderlinePosition::RIGHT);
+ },
+ _ => return Err(location.new_custom_error(
+ SelectorParseErrorKind::UnexpectedIdent(ident.clone())
+ )),
+ }
+ }
+
+ if !result.is_empty() {
+ Ok(result)
+ } else {
+ Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
+ }
+ }
+}
+
+impl ToCss for TextUnderlinePosition {
+ fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
+ where
+ W: Write,
+ {
+ if self.is_empty() {
+ return dest.write_str("auto");
+ }
+
+ let mut writer = SequenceWriter::new(dest, " ");
+ let mut any = false;
+
+ macro_rules! maybe_write {
+ ($ident:ident => $str:expr) => {
+ if self.contains(TextUnderlinePosition::$ident) {
+ any = true;
+ writer.raw_item($str)?;
+ }
+ };
+ }
+
+ maybe_write!(UNDER => "under");
+ maybe_write!(LEFT => "left");
+ maybe_write!(RIGHT => "right");
+
+ debug_assert!(any);
+
+ Ok(())
+ }
+}
diff --git a/components/to_shmem/Cargo.toml b/components/to_shmem/Cargo.toml
index dd3614111e1..76be7671da3 100644
--- a/components/to_shmem/Cargo.toml
+++ b/components/to_shmem/Cargo.toml
@@ -17,6 +17,6 @@ gecko = []
cssparser = "0.27"
servo_arc = { path = "../servo_arc" }
smallbitvec = "2.1.1"
-smallvec = "0.6.6"
+smallvec = "1.0"
string_cache = { version = "0.8", optional = true }
thin-slice = "0.1.0"
diff --git a/servo-tidy.toml b/servo-tidy.toml
index c35e180c260..b0d2477edad 100644
--- a/servo-tidy.toml
+++ b/servo-tidy.toml
@@ -35,6 +35,12 @@ packages = [
# https://github.com/servo/servo/pull/23288#issuecomment-494687746
"gl_generator",
+ # Just needs a WR update.
+ "derive_more",
+
+ # Lots of crates to update.
+ "smallvec",
+
# https://github.com/servo/servo/issues/24421
"proc-macro2",
"quote",
diff --git a/tests/wpt/metadata/css/cssom/border-shorthand-serialization.html.ini b/tests/wpt/metadata/css/cssom/border-shorthand-serialization.html.ini
deleted file mode 100644
index 5e4163cc85d..00000000000
--- a/tests/wpt/metadata/css/cssom/border-shorthand-serialization.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[border-shorthand-serialization.html]
- [Declaration with border longhands and border-image is not serialized to a border shorthand declaration.]
- expected: FAIL
-