From fa26e87030a344cd94362875f6a31918153dea0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 31 Dec 2016 03:17:41 +0100 Subject: [PATCH 01/19] layout: Remove get_font_arc in favor of clone_font. Since they do the same. --- components/layout/fragment.rs | 4 ++-- components/layout/inline.rs | 4 ++-- components/layout/text.rs | 2 +- components/style/properties/properties.mako.rs | 5 ----- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 35ed91cf6eb..873993f8982 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -2005,7 +2005,7 @@ impl Fragment { } // See CSS 2.1 ยง 10.8.1. let font_metrics = text::font_metrics_for_style(&mut layout_context.font_context(), - self.style.get_font_arc()); + self.style.clone_font()); let line_height = text::line_height_from_style(&*self.style, &font_metrics); InlineMetrics::from_font_metrics(&info.run.font_metrics, line_height) } @@ -2085,7 +2085,7 @@ impl Fragment { vertical_align::T::middle => { let font_metrics = text::font_metrics_for_style(&mut layout_context.font_context(), - style.get_font_arc()); + style.clone_font()); offset += (content_inline_metrics.ascent - content_inline_metrics.space_below_baseline - font_metrics.x_height).scale_by(0.5) diff --git a/components/layout/inline.rs b/components/layout/inline.rs index 372aa2ea088..833d93c3039 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -1089,7 +1089,7 @@ impl InlineFlow { return LineMetrics::new(Au(0), Au(0)) } - let font_style = style.get_font_arc(); + let font_style = style.clone_font(); let font_metrics = text::font_metrics_for_style(font_context, font_style); let line_height = text::line_height_from_style(style, &font_metrics); let inline_metrics = InlineMetrics::from_font_metrics(&font_metrics, line_height); @@ -1112,7 +1112,7 @@ impl InlineFlow { for inline_context in fragments.iter() .filter_map(|fragment| fragment.inline_context.as_ref()) { for node in &inline_context.nodes { - let font_style = node.style.get_font_arc(); + let font_style = node.style.clone_font(); let font_metrics = text::font_metrics_for_style(font_context, font_style); let line_height = text::line_height_from_style(&*node.style, &font_metrics); let inline_metrics = InlineMetrics::from_font_metrics(&font_metrics, line_height); diff --git a/components/layout/text.rs b/components/layout/text.rs index 237f339ea71..6e6f12e6ccd 100644 --- a/components/layout/text.rs +++ b/components/layout/text.rs @@ -154,7 +154,7 @@ impl TextRunScanner { let word_break; { let in_fragment = self.clump.front().unwrap(); - let font_style = in_fragment.style().get_font_arc(); + let font_style = in_fragment.style().clone_font(); let inherited_text_style = in_fragment.style().get_inheritedtext(); fontgroup = font_context.layout_font_group_for_style(font_style); compression = match in_fragment.white_space() { diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index d5a1cc192df..271d41e9587 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -1322,11 +1322,6 @@ impl ComputedValues { )) } - #[inline] - pub fn get_font_arc(&self) -> Arc { - self.font.clone() - } - // http://dev.w3.org/csswg/css-transforms/#grouping-property-values pub fn get_used_transform_style(&self) -> computed_values::transform_style::T { use computed_values::mix_blend_mode; From b5ba53655f09c15a4f15c9ff4108d2f9c85892c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 31 Dec 2016 03:20:03 +0100 Subject: [PATCH 02/19] style: Document and remove dead code from cache.rs --- components/style/cache.rs | 76 ++++++++++----------------------------- 1 file changed, 18 insertions(+), 58 deletions(-) diff --git a/components/style/cache.rs b/components/style/cache.rs index b4bac98992f..69be4a62514 100644 --- a/components/style/cache.rs +++ b/components/style/cache.rs @@ -2,18 +2,22 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -//! Two simple cache data structures. +//! A simple LRU cache. + +#![deny(missing_docs)] -use std::collections::hash_map::RandomState; -use std::hash::{Hash, Hasher, BuildHasher}; use std::slice::{Iter, IterMut}; +/// A LRU cache used to store a set of at most `n` elements at the same time. +/// +/// Currently used for the style sharing candidate cache. pub struct LRUCache { entries: Vec<(K, V)>, cache_size: usize, } impl LRUCache { + /// Create a new LRU cache with `size` elements at most. pub fn new(size: usize) -> LRUCache { LRUCache { entries: vec![], @@ -22,6 +26,7 @@ impl LRUCache { } #[inline] + /// Touch a given position, and put it in the last item on the list. pub fn touch(&mut self, pos: usize) -> &V { let last_index = self.entries.len() - 1; if pos != last_index { @@ -31,14 +36,17 @@ impl LRUCache { &self.entries[last_index].1 } + /// Iterate over the contents of this cache. pub fn iter(&self) -> Iter<(K, V)> { self.entries.iter() } + /// Iterate mutably over the contents of this cache. pub fn iter_mut(&mut self) -> IterMut<(K, V)> { self.entries.iter_mut() } + /// Insert a given key and value in the cache. pub fn insert(&mut self, key: K, val: V) { if self.entries.len() == self.cache_size { self.entries.remove(0); @@ -46,6 +54,7 @@ impl LRUCache { self.entries.push((key, val)); } + /// Try to find a key in the cache. pub fn find(&mut self, key: &K) -> Option { match self.entries.iter().position(|&(ref k, _)| key == k) { Some(pos) => Some(self.touch(pos).clone()), @@ -53,7 +62,11 @@ impl LRUCache { } } - pub fn find_or_create(&mut self, key: K, mut blk: F) -> V where F: FnMut() -> V { + /// Try to find a given key, or create a given item with that key executing + /// `blk`. + pub fn find_or_create(&mut self, key: K, mut blk: F) -> V + where F: FnMut() -> V, + { match self.entries.iter().position(|&(ref k, _)| *k == key) { Some(pos) => self.touch(pos).clone(), None => { @@ -64,61 +77,8 @@ impl LRUCache { } } + /// Evict all elements from the cache. pub fn evict_all(&mut self) { self.entries.clear(); } } - -pub struct SimpleHashCache { - entries: Vec>, - random: RandomState, -} - -impl SimpleHashCache { - pub fn new(cache_size: usize) -> SimpleHashCache { - SimpleHashCache { - entries: vec![None; cache_size], - random: RandomState::new(), - } - } - - #[inline] - fn to_bucket(&self, h: usize) -> usize { - h % self.entries.len() - } - - #[inline] - fn bucket_for_key(&self, key: &Q) -> usize { - let mut hasher = self.random.build_hasher(); - key.hash(&mut hasher); - self.to_bucket(hasher.finish() as usize) - } - - pub fn insert(&mut self, key: K, value: V) { - let bucket_index = self.bucket_for_key(&key); - self.entries[bucket_index] = Some((key, value)); - } - - pub fn find(&self, key: &Q) -> Option where Q: PartialEq + Hash + Eq { - let bucket_index = self.bucket_for_key(key); - match self.entries[bucket_index] { - Some((ref existing_key, ref value)) if key == existing_key => Some((*value).clone()), - _ => None, - } - } - - pub fn find_or_create(&mut self, key: K, mut blk: F) -> V where F: FnMut() -> V { - if let Some(value) = self.find(&key) { - return value; - } - let value = blk(); - self.insert(key, value.clone()); - value - } - - pub fn evict_all(&mut self) { - for slot in &mut self.entries { - *slot = None - } - } -} From 56f9a1a55cda9076c622b7ad2b348a938b1010e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 31 Dec 2016 03:18:53 +0100 Subject: [PATCH 03/19] style: Document the animations code. --- components/style/animation.rs | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/components/style/animation.rs b/components/style/animation.rs index cf9f04e161f..2dabb608d99 100644 --- a/components/style/animation.rs +++ b/components/style/animation.rs @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ //! CSS transitions and animations. +#![deny(missing_docs)] use Atom; use bezier::Bezier; @@ -28,8 +29,9 @@ use values::computed::Time; /// have to keep track the current iteration and the max iteration count. #[derive(Debug, Clone)] pub enum KeyframesIterationState { + /// Infinite iterations, so no need to track a state. Infinite, - // current, max + /// Current and max iterations. Finite(u32, u32), } @@ -192,6 +194,7 @@ pub enum Animation { } impl Animation { + /// Mark this animation as expired. #[inline] pub fn mark_as_expired(&mut self) { debug_assert!(!self.is_expired()); @@ -201,6 +204,7 @@ impl Animation { } } + /// Whether this animation is expired. #[inline] pub fn is_expired(&self) -> bool { match *self { @@ -209,6 +213,7 @@ impl Animation { } } + /// The opaque node that owns the animation. #[inline] pub fn node(&self) -> &OpaqueNode { match *self { @@ -217,6 +222,7 @@ impl Animation { } } + /// Whether this animation is paused. A transition can never be paused. #[inline] pub fn is_paused(&self) -> bool { match *self { @@ -237,6 +243,7 @@ pub struct AnimationFrame { pub duration: f64, } +/// Represents an animation for a given property. #[derive(Debug, Clone)] pub struct PropertyAnimation { property: AnimatedProperty, @@ -245,13 +252,15 @@ pub struct PropertyAnimation { } impl PropertyAnimation { - pub fn property_name(&self) -> String { + /// Returns the given property name. + pub fn property_name(&self) -> &'static str { self.property.name() } - /// Creates a new property animation for the given transition index and old and new styles. - /// Any number of animations may be returned, from zero (if the property did not animate) to - /// one (for a single transition property) to arbitrarily many (for `all`). + /// Creates a new property animation for the given transition index and old + /// and new styles. Any number of animations may be returned, from zero (if + /// the property did not animate) to one (for a single transition property) + /// to arbitrarily many (for `all`). pub fn from_transition(transition_index: usize, old_style: &ComputedValues, new_style: &mut ComputedValues) @@ -312,6 +321,7 @@ impl PropertyAnimation { } } + /// Update the given animation at a given point of progress. pub fn update(&self, style: &mut ComputedValues, time: f64) { let progress = match self.timing_function { TransitionTimingFunction::CubicBezier(p1, p2) => { @@ -336,8 +346,9 @@ impl PropertyAnimation { self.property.does_animate() && self.duration != Time(0.0) } + /// Whether this animation has the same end value as another one. #[inline] - pub fn has_the_same_end_value_as(&self, other: &PropertyAnimation) -> bool { + pub fn has_the_same_end_value_as(&self, other: &Self) -> bool { self.property.has_the_same_end_value_as(&other.property) } } @@ -428,6 +439,8 @@ fn compute_style_for_animation_step(context: &SharedStyleContext, } } +/// Triggers animations for a given node looking at the animation property +/// values. pub fn maybe_start_animations(context: &SharedStyleContext, new_animations_sender: &Sender, node: OpaqueNode, From b023791af5fb336cd4d701aa35eb16dc8f094465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 31 Dec 2016 03:21:38 +0100 Subject: [PATCH 04/19] style: Document the animated_properties code. --- components/layout/animation.rs | 2 +- .../helpers/animated_properties.mako.rs | 60 ++++++++++++++++--- .../style/properties/properties.mako.rs | 6 ++ 3 files changed, 60 insertions(+), 8 deletions(-) diff --git a/components/layout/animation.rs b/components/layout/animation.rs index 7fdc452ccc3..f6dd0f85d7a 100644 --- a/components/layout/animation.rs +++ b/components/layout/animation.rs @@ -88,7 +88,7 @@ pub fn update_animation_state(constellation_chan: &IpcSender, if let Animation::Transition(_, unsafe_node, _, ref frame, _) = running_animation { script_chan.send(ConstellationControlMsg::TransitionEnd(unsafe_node, frame.property_animation - .property_name(), + .property_name().into(), frame.duration)) .unwrap(); } diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index 642f25c7ef3..2414948ebd0 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -32,14 +32,18 @@ use values::computed::ToComputedValue; +/// A given transition property, that is either `All`, or an animatable +/// property. // NB: This needs to be here because it needs all the longhands generated // beforehand. #[derive(Copy, Clone, Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum TransitionProperty { + /// All, any animatable property changing should generate a transition. All, % for prop in data.longhands: % if prop.animatable: + /// ${prop.name} ${prop.camel_case}, % endif % endfor @@ -55,6 +59,7 @@ impl TransitionProperty { % endfor } + /// Parse a transition-property value. pub fn parse(input: &mut Parser) -> Result { match_ignore_ascii_case! { try!(input.expect_ident()), "all" => Ok(TransitionProperty::All), @@ -67,6 +72,7 @@ impl TransitionProperty { } } + /// Get a transition property from a property declaration. pub fn from_declaration(declaration: &PropertyDeclaration) -> Option { match *declaration { % for prop in data.longhands: @@ -81,7 +87,9 @@ impl TransitionProperty { } impl ToCss for TransitionProperty { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + fn to_css(&self, dest: &mut W) -> fmt::Result + where W: fmt::Write, + { match *self { TransitionProperty::All => dest.write_str("all"), % for prop in data.longhands: @@ -93,11 +101,14 @@ impl ToCss for TransitionProperty { } } +/// An animated property interpolation between two computed values for that +/// property. #[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum AnimatedProperty { % for prop in data.longhands: % if prop.animatable: + /// ${prop.name} ${prop.camel_case}(longhands::${prop.ident}::computed_value::T, longhands::${prop.ident}::computed_value::T), % endif @@ -105,16 +116,19 @@ pub enum AnimatedProperty { } impl AnimatedProperty { - pub fn name(&self) -> String { + /// Get the name of this property. + pub fn name(&self) -> &'static str { match *self { % for prop in data.longhands: % if prop.animatable: - AnimatedProperty::${prop.camel_case}(..) => "${prop.name}".to_owned(), + AnimatedProperty::${prop.camel_case}(..) => "${prop.name}", % endif % endfor } } + /// Whether this interpolation does animate, that is, whether the start and + /// end values are different. pub fn does_animate(&self) -> bool { match *self { % for prop in data.longhands: @@ -125,7 +139,8 @@ impl AnimatedProperty { } } - pub fn has_the_same_end_value_as(&self, other: &AnimatedProperty) -> bool { + /// Whether an animated property has the same end value as another. + pub fn has_the_same_end_value_as(&self, other: &Self) -> bool { match (self, other) { % for prop in data.longhands: % if prop.animatable: @@ -139,6 +154,8 @@ impl AnimatedProperty { } } + /// Update `style` with the proper computed style corresponding to this + /// animation at `progress`. pub fn update(&self, style: &mut ComputedValues, progress: f64) { match *self { % for prop in data.longhands: @@ -153,6 +170,8 @@ impl AnimatedProperty { } } + /// Get an animatable value from a transition-property, an old style, and a + /// new style. pub fn from_transition_property(transition_property: &TransitionProperty, old_style: &ComputedValues, new_style: &ComputedValues) @@ -188,12 +207,15 @@ impl AnimatedProperty { pub enum AnimationValue { % for prop in data.longhands: % if prop.animatable: + /// ${prop.name} ${prop.camel_case}(longhands::${prop.ident}::computed_value::T), % endif % endfor } impl AnimationValue { + /// "Uncompute" this animation value in order to be used inside the CSS + /// cascade. pub fn uncompute(&self) -> PropertyDeclaration { use properties::{longhands, DeclaredValue}; match *self { @@ -234,6 +256,7 @@ impl Interpolate for AnimationValue { /// /// [interpolated-types]: https://drafts.csswg.org/css-transitions/#interpolated-types pub trait Interpolate: Sized { + /// Interpolate a value with another for a given property. fn interpolate(&self, other: &Self, progress: f64) -> Result; } @@ -249,6 +272,7 @@ impl Interpolate for Vec { }).collect() } } + /// https://drafts.csswg.org/css-transitions/#animtype-number impl Interpolate for Au { #[inline] @@ -257,7 +281,9 @@ impl Interpolate for Au { } } -impl Interpolate for Option where T: Interpolate { +impl Interpolate for Option + where T: Interpolate, +{ #[inline] fn interpolate(&self, other: &Option, progress: f64) -> Result, ()> { match (self, other) { @@ -431,7 +457,7 @@ impl Interpolate for CalcLengthOrPercentage { other: Option, progress: f64) -> Result, ()> - where T: Default + Interpolate + where T: Default + Interpolate, { match (this, other) { (None, None) => Ok(None), @@ -919,27 +945,36 @@ impl Interpolate for LengthOrNone { } } + /// A 2d matrix for interpolation. #[derive(Clone, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + #[allow(missing_docs)] pub struct InnerMatrix2D { pub m11: CSSFloat, pub m12: CSSFloat, pub m21: CSSFloat, pub m22: CSSFloat, } + /// A 2d translation function. #[derive(Clone, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct Translate2D(f32, f32); + /// A 2d scale function. #[derive(Clone, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct Scale2D(f32, f32); + /// A decomposed 2d matrix. #[derive(Clone, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct MatrixDecomposed2D { + /// The translation function. pub translate: Translate2D, + /// The scale function. pub scale: Scale2D, + /// The rotation angle. pub angle: f32, + /// The inner matrix. pub matrix: InnerMatrix2D, } @@ -1143,33 +1178,44 @@ impl Interpolate for LengthOrNone { } } + /// A 3d translation. #[derive(Clone, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct Translate3D(f32, f32, f32); + /// A 3d scale function. #[derive(Clone, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct Scale3D(f32, f32, f32); + /// A 3d skew function. #[derive(Clone, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct Skew(f32, f32, f32); + /// A 3d perspective transformation. #[derive(Clone, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct Perspective(f32, f32, f32, f32); + /// A quaternion used to represent a rotation. #[derive(Clone, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct Quaternion(f32, f32, f32, f32); + /// A decomposed 3d matrix. #[derive(Clone, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct MatrixDecomposed3D { + /// A translation function. pub translate: Translate3D, + /// A scale function. pub scale: Scale3D, + /// The skew component of the transformation. pub skew: Skew, + /// The perspective component of the transformation. pub perspective: Perspective, + /// The quaternion used to represent the rotation. pub quaternion: Quaternion, } @@ -1513,7 +1559,7 @@ impl Interpolate for LengthOrNone { self.m43 != 0.0 || self.m44 != 1.0 } - pub fn determinant(&self) -> CSSFloat { + fn determinant(&self) -> CSSFloat { self.m14 * self.m23 * self.m32 * self.m41 - self.m13 * self.m24 * self.m32 * self.m41 - self.m14 * self.m22 * self.m33 * self.m41 + diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 271d41e9587..d9f55241623 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -158,7 +158,13 @@ pub mod shorthands { <%include file="/shorthand/text.mako.rs" /> } +/// A module with all the code related to animated properties. +/// +/// This needs to be loaded at least after all longhand modules, given they +/// populate the global data. pub mod animated_properties { + #![deny(missing_docs)] + <%include file="/helpers/animated_properties.mako.rs" /> } From 277ef70d39f745aa93a85a1dda67ee0914fe685d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 31 Dec 2016 03:29:52 +0100 Subject: [PATCH 05/19] style: Consistently indent stuff, add a bit of documentation driving by. --- components/style/lib.rs | 29 +- .../style/properties/declaration_block.rs | 8 +- components/style/properties/helpers.mako.rs | 27 +- .../properties/longhand/background.mako.rs | 147 +++++---- .../style/properties/longhand/box.mako.rs | 297 ++++++++++-------- .../style/properties/longhand/font.mako.rs | 5 +- .../style/properties/properties.mako.rs | 148 +++++---- .../properties/shorthand/serialize.mako.rs | 16 +- components/style/stylesheets.rs | 3 +- components/style/values/computed/mod.rs | 6 +- components/style/values/mod.rs | 14 +- components/style/values/specified/length.rs | 9 +- components/style/viewport.rs | 13 +- components/style_traits/values.rs | 9 +- 14 files changed, 435 insertions(+), 296 deletions(-) diff --git a/components/style/lib.rs b/components/style/lib.rs index 2b31dc0f779..53d4e97ee3f 100644 --- a/components/style/lib.rs +++ b/components/style/lib.rs @@ -182,15 +182,24 @@ pub fn arc_ptr_eq(a: &Arc, b: &Arc) -> bool { (a as *const T) == (b as *const T) } -pub fn serialize_comma_separated_list(dest: &mut W, list: &[T]) - -> fmt::Result where W: fmt::Write, T: ToCss { - if list.len() > 0 { - for item in &list[..list.len()-1] { - try!(item.to_css(dest)); - try!(write!(dest, ", ")); - } - list[list.len()-1].to_css(dest) - } else { - Ok(()) +/// Serializes as CSS a comma-separated list of any `T` that supports being +/// serialized as CSS. +pub fn serialize_comma_separated_list(dest: &mut W, + list: &[T]) + -> fmt::Result + where W: fmt::Write, + T: ToCss, +{ + if list.is_empty() { + return Ok(()); } + + try!(list[0].to_css(dest)); + + for item in list.iter().skip(1) { + try!(write!(dest, ", ")); + try!(item.to_css(dest)); + } + + Ok(()) } diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs index de2d274280b..0cf96724dcb 100644 --- a/components/style/properties/declaration_block.rs +++ b/components/style/properties/declaration_block.rs @@ -405,9 +405,10 @@ pub fn append_serialization<'a, W, I, N>(dest: &mut W, importance: Importance, is_first_serialization: &mut bool) -> fmt::Result - where W: fmt::Write, - I: Iterator, - N: ToCss { + where W: fmt::Write, + I: Iterator, + N: ToCss +{ try!(handle_first_serialization(dest, is_first_serialization)); // Overflow does not behave like a normal shorthand. When overflow-x and overflow-y are not of equal @@ -525,4 +526,3 @@ pub fn parse_property_declaration_list(context: &ParserContext, input: &mut Pars super::deduplicate_property_declarations(&mut block); block } - diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index 5efeac958fe..83feda735c2 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -73,16 +73,21 @@ use values::{computed, specified}; ${caller.body()} } + + /// The definition of the computed value for ${name}. pub mod computed_value { pub use super::single_value::computed_value as single_value; pub use self::single_value::T as SingleComputedValue; + /// The computed value, effectively a list of single values. #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct T(pub Vec); } impl ToCss for computed_value::T { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + fn to_css(&self, dest: &mut W) -> fmt::Result + where W: fmt::Write, + { let mut iter = self.0.iter(); if let Some(val) = iter.next() { try!(val.to_css(dest)); @@ -101,12 +106,15 @@ } } + /// The specified value of ${name}. #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue(pub Vec); impl ToCss for SpecifiedValue { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + fn to_css(&self, dest: &mut W) -> fmt::Result + where W: fmt::Write, + { let mut iter = self.0.iter(); if let Some(val) = iter.next() { try!(val.to_css(dest)); @@ -405,7 +413,11 @@ } impl<'a> LonghandsToSerialize<'a> { - pub fn from_iter>(iter: I) -> Result { + /// Tries to get a serializable set of longhands given a set of + /// property declarations. + pub fn from_iter(iter: I) -> Result + where I: Iterator, + { // Define all of the expected variables that correspond to the shorthand % for sub_property in shorthand.sub_properties: let mut ${sub_property.ident} = None; @@ -446,7 +458,9 @@ } impl<'a> ToCss for LonghandsToSerialize<'a> { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + fn to_css(&self, dest: &mut W) -> fmt::Result + where W: fmt::Write, + { let mut all_flags = SerializeFlags::all(); let mut with_variables = false; % for sub_property in shorthand.sub_properties: @@ -477,7 +491,10 @@ } - pub fn parse(context: &ParserContext, input: &mut Parser, + /// Parse the given shorthand and fill the result into the + /// `declarations` vector. + pub fn parse(context: &ParserContext, + input: &mut Parser, declarations: &mut Vec) -> Result<(), ()> { input.look_for_var_functions(); diff --git a/components/style/properties/longhand/background.mako.rs b/components/style/properties/longhand/background.mako.rs index 645e9666c63..26f611bd33b 100644 --- a/components/style/properties/longhand/background.mako.rs +++ b/components/style/properties/longhand/background.mako.rs @@ -87,89 +87,102 @@ ${helpers.predefined_type("background-color", "CSSColor", <%helpers:vector_longhand name="background-position-x" animatable="True"> - use std::fmt; - use style_traits::ToCss; - use values::HasViewportPercentage; - use values::specified::position::HorizontalPosition; + use std::fmt; + use style_traits::ToCss; + use values::HasViewportPercentage; + use values::specified::position::HorizontalPosition; - pub mod computed_value { - use values::computed::position::HorizontalPosition; - use properties::animated_properties::{Interpolate, RepeatableListInterpolate}; + #[allow(missing_docs)] + pub mod computed_value { + use values::computed::position::HorizontalPosition; + use properties::animated_properties::{Interpolate, RepeatableListInterpolate}; - pub type T = HorizontalPosition; - } + pub type T = HorizontalPosition; + } - pub type SpecifiedValue = HorizontalPosition; + #[allow(missing_docs)] + pub type SpecifiedValue = HorizontalPosition; - #[inline] - pub fn get_initial_value() -> computed_value::T { - use values::computed::position::HorizontalPosition; - HorizontalPosition(computed::LengthOrPercentage::Percentage(0.0)) + #[inline] + #[allow(missing_docs)] + pub fn get_initial_value() -> computed_value::T { + use values::computed::position::HorizontalPosition; + HorizontalPosition(computed::LengthOrPercentage::Percentage(0.0)) + } + #[inline] + #[allow(missing_docs)] + pub fn get_initial_specified_value() -> SpecifiedValue { + use values::specified::position::Keyword; + HorizontalPosition { + keyword: Some(Keyword::Left), + position: None, } - #[inline] - pub fn get_initial_specified_value() -> SpecifiedValue { - use values::specified::position::Keyword; - HorizontalPosition { - keyword: Some(Keyword::Left), - position: None, - } - } - #[inline] - pub fn get_initial_position_value() -> SpecifiedValue { - use values::specified::{LengthOrPercentage, Percentage}; - HorizontalPosition { - keyword: None, - position: Some(LengthOrPercentage::Percentage(Percentage(0.0))), - } + } + #[inline] + #[allow(missing_docs)] + pub fn get_initial_position_value() -> SpecifiedValue { + use values::specified::{LengthOrPercentage, Percentage}; + HorizontalPosition { + keyword: None, + position: Some(LengthOrPercentage::Percentage(Percentage(0.0))), } + } - pub fn parse(context: &ParserContext, input: &mut Parser) - -> Result { - HorizontalPosition::parse(context, input) - } + #[allow(missing_docs)] + pub fn parse(context: &ParserContext, input: &mut Parser) + -> Result { + HorizontalPosition::parse(context, input) + } <%helpers:vector_longhand name="background-position-y" animatable="True"> - use std::fmt; - use style_traits::ToCss; - use values::HasViewportPercentage; - use values::specified::position::VerticalPosition; + use std::fmt; + use style_traits::ToCss; + use values::HasViewportPercentage; + use values::specified::position::VerticalPosition; - pub mod computed_value { - use values::computed::position::VerticalPosition; - use properties::animated_properties::{Interpolate, RepeatableListInterpolate}; + #[allow(missing_docs)] + pub mod computed_value { + use values::computed::position::VerticalPosition; + use properties::animated_properties::{Interpolate, RepeatableListInterpolate}; - pub type T = VerticalPosition; - } + pub type T = VerticalPosition; + } - pub type SpecifiedValue = VerticalPosition; + #[allow(missing_docs)] + pub type SpecifiedValue = VerticalPosition; - #[inline] - pub fn get_initial_value() -> computed_value::T { - use values::computed::position::VerticalPosition; - VerticalPosition(computed::LengthOrPercentage::Percentage(0.0)) + #[inline] + #[allow(missing_docs)] + pub fn get_initial_value() -> computed_value::T { + use values::computed::position::VerticalPosition; + VerticalPosition(computed::LengthOrPercentage::Percentage(0.0)) + } + #[inline] + #[allow(missing_docs)] + pub fn get_initial_specified_value() -> SpecifiedValue { + use values::specified::position::Keyword; + VerticalPosition { + keyword: Some(Keyword::Top), + position: None, } - #[inline] - pub fn get_initial_specified_value() -> SpecifiedValue { - use values::specified::position::Keyword; - VerticalPosition { - keyword: Some(Keyword::Top), - position: None, - } - } - #[inline] - pub fn get_initial_position_value() -> SpecifiedValue { - use values::specified::{LengthOrPercentage, Percentage}; - VerticalPosition { - keyword: None, - position: Some(LengthOrPercentage::Percentage(Percentage(0.0))), - } + } + #[inline] + #[allow(missing_docs)] + pub fn get_initial_position_value() -> SpecifiedValue { + use values::specified::{LengthOrPercentage, Percentage}; + VerticalPosition { + keyword: None, + position: Some(LengthOrPercentage::Percentage(Percentage(0.0))), } + } - pub fn parse(context: &ParserContext, input: &mut Parser) - -> Result { - VerticalPosition::parse(context, input) - } + #[inline] + #[allow(missing_docs)] + pub fn parse(context: &ParserContext, input: &mut Parser) + -> Result { + VerticalPosition::parse(context, input) + } ${helpers.single_keyword("background-repeat", @@ -199,6 +212,7 @@ ${helpers.single_keyword("background-origin", use style_traits::ToCss; use values::HasViewportPercentage; + #[allow(missing_docs)] pub mod computed_value { use values::computed::LengthOrPercentageOrAuto; use properties::animated_properties::{Interpolate, RepeatableListInterpolate}; @@ -254,6 +268,7 @@ ${helpers.single_keyword("background-origin", #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + #[allow(missing_docs)] pub struct ExplicitSize { pub width: specified::LengthOrPercentageOrAuto, pub height: specified::LengthOrPercentageOrAuto, diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index c7782eeb0e6..3b5cd6bba4c 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -46,7 +46,8 @@ impl ToCss for T { fn to_css(&self, dest: &mut W) -> ::std::fmt::Result - where W: ::std::fmt::Write { + where W: ::std::fmt::Write, + { match *self { % for value in values: T::${to_rust_ident(value)} => dest.write_str("${value}"), @@ -55,9 +56,14 @@ } } } - #[inline] pub fn get_initial_value() -> computed_value::T { + + /// The initial display value. + #[inline] + pub fn get_initial_value() -> computed_value::T { computed_value::T::${to_rust_ident(values[0])} } + + /// Parse a display value. pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { match_ignore_ascii_case! { try!(input.expect_ident()), @@ -144,119 +150,128 @@ ${helpers.single_keyword("clear", "none left right both", -<%helpers:longhand name="vertical-align" - animatable="True"> - use std::fmt; - use style_traits::ToCss; - use values::HasViewportPercentage; +<%helpers:longhand name="vertical-align" animatable="True"> + use std::fmt; + use style_traits::ToCss; + use values::HasViewportPercentage; - <% vertical_align = data.longhands_by_name["vertical-align"] %> - <% vertical_align.keyword = Keyword("vertical-align", - "baseline sub super top text-top middle bottom text-bottom", - extra_gecko_values="middle-with-baseline") %> - <% vertical_align_keywords = vertical_align.keyword.values_for(product) %> + <% vertical_align = data.longhands_by_name["vertical-align"] %> + <% vertical_align.keyword = Keyword("vertical-align", + "baseline sub super top text-top middle bottom text-bottom", + extra_gecko_values="middle-with-baseline") %> + <% vertical_align_keywords = vertical_align.keyword.values_for(product) %> - impl HasViewportPercentage for SpecifiedValue { - fn has_viewport_percentage(&self) -> bool { - match *self { - SpecifiedValue::LengthOrPercentage(length) => length.has_viewport_percentage(), - _ => false - } - } - } + impl HasViewportPercentage for SpecifiedValue { + fn has_viewport_percentage(&self) -> bool { + match *self { + SpecifiedValue::LengthOrPercentage(length) => length.has_viewport_percentage(), + _ => false + } + } + } - #[allow(non_camel_case_types)] - #[derive(Debug, Clone, PartialEq, Copy)] - #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub enum SpecifiedValue { - % for keyword in vertical_align_keywords: - ${to_rust_ident(keyword)}, - % endfor - LengthOrPercentage(specified::LengthOrPercentage), - } + /// The `vertical-align` value. + #[allow(non_camel_case_types)] + #[derive(Debug, Clone, PartialEq, Copy)] + #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + pub enum SpecifiedValue { + % for keyword in vertical_align_keywords: + ${to_rust_ident(keyword)}, + % endfor + LengthOrPercentage(specified::LengthOrPercentage), + } - impl ToCss for SpecifiedValue { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - % for keyword in vertical_align_keywords: - SpecifiedValue::${to_rust_ident(keyword)} => dest.write_str("${keyword}"), - % endfor - SpecifiedValue::LengthOrPercentage(value) => value.to_css(dest), - } - } - } - /// baseline | sub | super | top | text-top | middle | bottom | text-bottom - /// | | - pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { - input.try(|i| specified::LengthOrPercentage::parse(context, i)) - .map(SpecifiedValue::LengthOrPercentage) - .or_else(|()| { - match_ignore_ascii_case! { try!(input.expect_ident()), - % for keyword in vertical_align_keywords: - "${keyword}" => Ok(SpecifiedValue::${to_rust_ident(keyword)}), - % endfor - _ => Err(()) - } - }) - } - pub mod computed_value { - use app_units::Au; - use std::fmt; - use style_traits::ToCss; - use values::{CSSFloat, computed}; - #[allow(non_camel_case_types)] - #[derive(PartialEq, Copy, Clone, Debug)] - #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub enum T { - % for keyword in vertical_align_keywords: - ${to_rust_ident(keyword)}, - % endfor - LengthOrPercentage(computed::LengthOrPercentage), - } - impl ToCss for T { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - % for keyword in vertical_align_keywords: - T::${to_rust_ident(keyword)} => dest.write_str("${keyword}"), - % endfor - T::LengthOrPercentage(value) => value.to_css(dest), - } - } - } - } - #[inline] - pub fn get_initial_value() -> computed_value::T { computed_value::T::baseline } + impl ToCss for SpecifiedValue { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + % for keyword in vertical_align_keywords: + SpecifiedValue::${to_rust_ident(keyword)} => dest.write_str("${keyword}"), + % endfor + SpecifiedValue::LengthOrPercentage(value) => value.to_css(dest), + } + } + } + /// baseline | sub | super | top | text-top | middle | bottom | text-bottom + /// | | + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { + input.try(|i| specified::LengthOrPercentage::parse(context, i)) + .map(SpecifiedValue::LengthOrPercentage) + .or_else(|_| { + match_ignore_ascii_case! { try!(input.expect_ident()), + % for keyword in vertical_align_keywords: + "${keyword}" => Ok(SpecifiedValue::${to_rust_ident(keyword)}), + % endfor + _ => Err(()) + } + }) + } - impl ToComputedValue for SpecifiedValue { - type ComputedValue = computed_value::T; + /// The computed value for `vertical-align`. + pub mod computed_value { + use app_units::Au; + use std::fmt; + use style_traits::ToCss; + use values::{CSSFloat, computed}; - #[inline] - fn to_computed_value(&self, context: &Context) -> computed_value::T { - match *self { - % for keyword in vertical_align_keywords: - SpecifiedValue::${to_rust_ident(keyword)} => { - computed_value::T::${to_rust_ident(keyword)} - } - % endfor - SpecifiedValue::LengthOrPercentage(value) => - computed_value::T::LengthOrPercentage(value.to_computed_value(context)), - } - } - #[inline] - fn from_computed_value(computed: &computed_value::T) -> Self { - match *computed { - % for keyword in vertical_align_keywords: - computed_value::T::${to_rust_ident(keyword)} => { - SpecifiedValue::${to_rust_ident(keyword)} - } - % endfor - computed_value::T::LengthOrPercentage(value) => - SpecifiedValue::LengthOrPercentage( - ToComputedValue::from_computed_value(&value) - ), - } - } - } + /// The keywords are the same, and the `LengthOrPercentage` is computed + /// here. + #[allow(non_camel_case_types)] + #[derive(PartialEq, Copy, Clone, Debug)] + #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + pub enum T { + % for keyword in vertical_align_keywords: + ${to_rust_ident(keyword)}, + % endfor + LengthOrPercentage(computed::LengthOrPercentage), + } + impl ToCss for T { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + % for keyword in vertical_align_keywords: + T::${to_rust_ident(keyword)} => dest.write_str("${keyword}"), + % endfor + T::LengthOrPercentage(value) => value.to_css(dest), + } + } + } + } + + /// The initial computed value for `vertical-align`. + #[inline] + pub fn get_initial_value() -> computed_value::T { + computed_value::T::baseline + } + + impl ToComputedValue for SpecifiedValue { + type ComputedValue = computed_value::T; + + #[inline] + fn to_computed_value(&self, context: &Context) -> computed_value::T { + match *self { + % for keyword in vertical_align_keywords: + SpecifiedValue::${to_rust_ident(keyword)} => { + computed_value::T::${to_rust_ident(keyword)} + } + % endfor + SpecifiedValue::LengthOrPercentage(value) => + computed_value::T::LengthOrPercentage(value.to_computed_value(context)), + } + } + #[inline] + fn from_computed_value(computed: &computed_value::T) -> Self { + match *computed { + % for keyword in vertical_align_keywords: + computed_value::T::${to_rust_ident(keyword)} => { + SpecifiedValue::${to_rust_ident(keyword)} + } + % endfor + computed_value::T::LengthOrPercentage(value) => + SpecifiedValue::LengthOrPercentage( + ToComputedValue::from_computed_value(&value) + ), + } + } + } @@ -275,44 +290,51 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", gecko_constant_prefix="NS_STYLE_OVERFLOW")} // FIXME(pcwalton, #2742): Implement scrolling for `scroll` and `auto`. -<%helpers:longhand name="overflow-y" - need_clone="True" - animatable="False"> - use super::overflow_x; +<%helpers:longhand name="overflow-y" need_clone="True" animatable="False"> + use super::overflow_x; - use std::fmt; - use style_traits::ToCss; - use values::computed::ComputedValueAsSpecified; - use values::NoViewportPercentage; + use std::fmt; + use style_traits::ToCss; + use values::computed::ComputedValueAsSpecified; + use values::NoViewportPercentage; - pub use self::computed_value::T as SpecifiedValue; + pub use self::computed_value::T as SpecifiedValue; - impl NoViewportPercentage for SpecifiedValue {} + impl NoViewportPercentage for SpecifiedValue {} - impl ToCss for SpecifiedValue { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - self.0.to_css(dest) - } - } + impl ToCss for SpecifiedValue { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + self.0.to_css(dest) + } + } - pub mod computed_value { - #[derive(Debug, Clone, Copy, PartialEq)] - #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub struct T(pub super::super::overflow_x::computed_value::T); - } - impl ComputedValueAsSpecified for SpecifiedValue {} + /// The specified and computed value for overflow-y is a wrapper on top of + /// `overflow-x`, so we re-use the logic, but prevent errors from mistakenly + /// assign one to other. + /// + /// TODO(Manishearth, emilio): We may want to just use the same value. + pub mod computed_value { + #[derive(Debug, Clone, Copy, PartialEq)] + #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + pub struct T(pub super::super::overflow_x::computed_value::T); + } - pub fn get_initial_value() -> computed_value::T { - computed_value::T(overflow_x::get_initial_value()) - } + impl ComputedValueAsSpecified for SpecifiedValue {} - pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { - overflow_x::parse(context, input).map(SpecifiedValue) - } + #[inline] + #[allow(missing_docs)] + pub fn get_initial_value() -> computed_value::T { + computed_value::T(overflow_x::get_initial_value()) + } + + #[inline] + #[allow(missing_docs)] + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { + overflow_x::parse(context, input).map(SpecifiedValue) + } -// TODO(pcwalton): Multiple transitions. <%helpers:longhand name="transition-duration" need_index="True" animatable="False"> @@ -369,7 +391,6 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", // TODO(pcwalton): Lots more timing functions. -// TODO(pcwalton): Multiple transitions. <%helpers:longhand name="transition-timing-function" need_index="True" animatable="False"> diff --git a/components/style/properties/longhand/font.mako.rs b/components/style/properties/longhand/font.mako.rs index ee9ae6a4470..a247594ac58 100644 --- a/components/style/properties/longhand/font.mako.rs +++ b/components/style/properties/longhand/font.mako.rs @@ -315,7 +315,10 @@ ${helpers.single_keyword("font-variant-caps", use app_units::Au; pub type T = Au; } - #[inline] pub fn get_initial_value() -> computed_value::T { + + #[inline] + #[allow(missing_docs)] + pub fn get_initial_value() -> computed_value::T { Au::from_px(FONT_MEDIUM_PX) } diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index d9f55241623..5d1bf766c8a 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -160,8 +160,8 @@ pub mod shorthands { /// A module with all the code related to animated properties. /// -/// This needs to be loaded at least after all longhand modules, given they -/// populate the global data. +/// This needs to be "included" by mako at least after all longhand modules, +/// given they populate the global data. pub mod animated_properties { #![deny(missing_docs)] @@ -467,15 +467,21 @@ impl ShorthandId { } } - /// Serializes possible shorthand name with value to input buffer given a list of longhand declarations. - /// On success, returns true if shorthand value is written and false if no shorthand value is present. + /// Serializes the possible shorthand name with value to input buffer given + /// a list of longhand declarations. + /// + /// On success, returns true if the shorthand value is written, or false if + /// no shorthand value is present. pub fn serialize_shorthand_to_buffer<'a, W, I>(self, dest: &mut W, declarations: I, is_first_serialization: &mut bool, importance: Importance) -> Result - where W: Write, I: IntoIterator, I::IntoIter: Clone { + where W: Write, + I: IntoIterator, + I::IntoIter: Clone, + { match self.get_shorthand_appendable_value(declarations) { None => Ok(false), Some(appendable_value) => { @@ -490,60 +496,73 @@ impl ShorthandId { } } - fn get_shorthand_appendable_value<'a, I>(self, declarations: I) + fn get_shorthand_appendable_value<'a, I>(self, + declarations: I) -> Option> - where I: IntoIterator, I::IntoIter: Clone { - let declarations = declarations.into_iter(); + where I: IntoIterator, + I::IntoIter: Clone, + { + let declarations = declarations.into_iter(); - // Only cloning iterators (a few pointers each) not declarations. - let mut declarations2 = declarations.clone(); - let mut declarations3 = declarations.clone(); + // Only cloning iterators (a few pointers each) not declarations. + let mut declarations2 = declarations.clone(); + let mut declarations3 = declarations.clone(); - let first_declaration = match declarations2.next() { - Some(declaration) => declaration, - None => return None - }; + let first_declaration = match declarations2.next() { + Some(declaration) => declaration, + None => return None + }; - // https://drafts.csswg.org/css-variables/#variables-in-shorthands - if let Some(css) = first_declaration.with_variables_from_shorthand(self) { - if declarations2.all(|d| d.with_variables_from_shorthand(self) == Some(css)) { - return Some(AppendableValue::Css(css)); - } - else { - return None; - } - } + // https://drafts.csswg.org/css-variables/#variables-in-shorthands + if let Some(css) = first_declaration.with_variables_from_shorthand(self) { + if declarations2.all(|d| d.with_variables_from_shorthand(self) == Some(css)) { + return Some(AppendableValue::Css(css)); + } + return None; + } - if !declarations3.any(|d| d.with_variables()) { - return Some(AppendableValue::DeclarationsForShorthand(self, declarations)); - } + if !declarations3.any(|d| d.with_variables()) { + return Some(AppendableValue::DeclarationsForShorthand(self, declarations)); + } - None + None } } +/// Servo's representation of a declared value for a given `T`, which is the +/// declared value for that property. #[derive(Clone, PartialEq, Eq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum DeclaredValue { + /// A known specified value from the stylesheet. Value(T), + /// A value that contained any css variables. WithVariables { + /// The css serialization for this value. css: String, + /// The first token type for this serialization. first_token_type: TokenSerializationType, + /// The base url. base_url: ServoUrl, + /// The shorthand this came from. from_shorthand: Option, }, + /// The `initial` keyword. Initial, + /// The `inherit` keyword. Inherit, + /// The `unset` keyword. Unset, } impl HasViewportPercentage for DeclaredValue { fn has_viewport_percentage(&self) -> bool { match *self { - DeclaredValue::Value(ref v) - => v.has_viewport_percentage(), - DeclaredValue::WithVariables { .. } - => panic!("DeclaredValue::has_viewport_percentage without resolving variables!"), + DeclaredValue::Value(ref v) => v.has_viewport_percentage(), + DeclaredValue::WithVariables { .. } => { + panic!("DeclaredValue::has_viewport_percentage without \ + resolving variables!") + }, DeclaredValue::Initial | DeclaredValue::Inherit | DeclaredValue::Unset => false, @@ -621,7 +640,9 @@ impl fmt::Debug for PropertyId { } impl ToCss for PropertyId { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + fn to_css(&self, dest: &mut W) -> fmt::Result + where W: fmt::Write, + { match *self { PropertyId::Longhand(id) => dest.write_str(id.name()), PropertyId::Shorthand(id) => dest.write_str(id.name()), @@ -1156,19 +1177,22 @@ pub struct ComputedValues { % endfor custom_properties: Option>, shareable: bool, + /// The writing mode of this computed values struct. pub writing_mode: WritingMode, + /// The root element's computed font size. pub root_font_size: Au, } #[cfg(feature = "servo")] impl ComputedValues { + /// Construct a `ComputedValues` instance. pub fn new(custom_properties: Option>, - shareable: bool, - writing_mode: WritingMode, - root_font_size: Au, - % for style_struct in data.active_style_structs(): - ${style_struct.ident}: Arc, - % endfor + shareable: bool, + writing_mode: WritingMode, + root_font_size: Au, + % for style_struct in data.active_style_structs(): + ${style_struct.ident}: Arc, + % endfor ) -> Self { ComputedValues { custom_properties: custom_properties, @@ -1821,16 +1845,21 @@ pub fn apply_declarations<'a, F, I>(viewport_size: Size2D, } if seen.get_font_style() || seen.get_font_weight() || seen.get_font_stretch() || - seen.get_font_family() { + seen.get_font_family() { style.mutate_font().compute_font_hash(); } style } +/// Modifies the style for an anonymous flow so it resets all its non-inherited +/// style structs, and set their borders and outlines to zero. +/// +/// Also, it gets a new display value, which is honored except when it's +/// `inline`. #[cfg(feature = "servo")] pub fn modify_style_for_anonymous_flow(style: &mut Arc, - new_display_value: longhands::display::computed_value::T) { + new_display_value: longhands::display::computed_value::T) { // The 'align-self' property needs some special treatment since // its value depends on the 'align-items' value of its parent. % if "align-items" in data.longhands_by_name: @@ -1870,12 +1899,17 @@ pub fn modify_style_for_anonymous_flow(style: &mut Arc, outline.outline_width = Au(0); } -/// Alters the given style to accommodate replaced content. This is called in flow construction. It -/// handles cases like `
foo bar baz
` (in which `foo`, `bar`, -/// and `baz` must not be absolutely-positioned) and cases like `Foo` (in which the -/// `vertical-align: top` style of `sup` must not propagate down into `Foo`). +/// Alters the given style to accommodate replaced content. This is called in +/// flow construction. It handles cases like: /// -/// FIXME(#5625, pcwalton): It would probably be cleaner and faster to do this in the cascade. +///
foo bar baz
+/// +/// (in which `foo`, `bar`, and `baz` must not be absolutely-positioned) and +/// cases like `Foo` (in which the `vertical-align: top` style of +/// `sup` must not propagate down into `Foo`). +/// +/// FIXME(#5625, pcwalton): It would probably be cleaner and faster to do this +/// in the cascade. #[cfg(feature = "servo")] #[inline] pub fn modify_style_for_replaced_content(style: &mut Arc) { @@ -1908,11 +1942,11 @@ pub fn modify_style_for_replaced_content(style: &mut Arc) { } } -/// Adjusts borders as appropriate to account for a fragment's status as the first or last fragment -/// within the range of an element. +/// Adjusts borders as appropriate to account for a fragment's status as the +/// first or last fragment within the range of an element. /// -/// Specifically, this function sets border widths to zero on the sides for which the fragment is -/// not outermost. +/// Specifically, this function sets border widths to zero on the sides for +/// which the fragment is not outermost. #[cfg(feature = "servo")] #[inline] pub fn modify_border_style_for_inline_sides(style: &mut Arc, @@ -1964,7 +1998,8 @@ pub fn modify_border_style_for_inline_sides(style: &mut Arc, } } -/// Adjusts the `position` property as necessary for the outer fragment wrapper of an inline-block. +/// Adjusts the `position` property as necessary for the outer fragment wrapper +/// of an inline-block. #[cfg(feature = "servo")] #[inline] pub fn modify_style_for_outer_inline_block_fragment(style: &mut Arc) { @@ -1973,10 +2008,11 @@ pub fn modify_style_for_outer_inline_block_fragment(style: &mut Arc) { @@ -2010,8 +2046,8 @@ pub fn modify_style_for_text(style: &mut Arc) { } } -/// Adjusts the `clip` property so that an inline absolute hypothetical fragment doesn't clip its -/// children. +/// Adjusts the `clip` property so that an inline absolute hypothetical fragment +/// doesn't clip its children. #[cfg(feature = "servo")] pub fn modify_style_for_inline_absolute_hypothetical_fragment(style: &mut Arc) { if style.get_effects().clip.0.is_some() { diff --git a/components/style/properties/shorthand/serialize.mako.rs b/components/style/properties/shorthand/serialize.mako.rs index 3dbf39a8ac3..e8b7a76b0cf 100644 --- a/components/style/properties/shorthand/serialize.mako.rs +++ b/components/style/properties/shorthand/serialize.mako.rs @@ -7,8 +7,16 @@ use style_traits::ToCss; use values::specified::{BorderStyle, CSSColor}; use std::fmt; -pub fn serialize_four_sides(dest: &mut W, top: &I, right: &I, bottom: &I, left: &I) - -> fmt::Result where W: fmt::Write, I: ToCss + PartialEq { +#[allow(missing_docs)] +pub fn serialize_four_sides(dest: &mut W, + top: &I, + right: &I, + bottom: &I, + left: &I) + -> fmt::Result + where W: fmt::Write, + I: ToCss + PartialEq, +{ if left == right { let horizontal_value = left; @@ -85,8 +93,10 @@ fn serialize_directional_border(dest: &mut W, } +#[allow(missing_docs)] pub fn is_overflow_shorthand<'a, I>(appendable_value: &AppendableValue<'a, I>) -> bool - where I: Iterator { + where I: Iterator +{ if let AppendableValue::DeclarationsForShorthand(shorthand, _) = *appendable_value { if let ShorthandId::Overflow = shorthand { return true; diff --git a/components/style/stylesheets.rs b/components/style/stylesheets.rs index bc573eb4bfe..dcfa897bfde 100644 --- a/components/style/stylesheets.rs +++ b/components/style/stylesheets.rs @@ -268,7 +268,8 @@ impl CssRule { /// Note that only some types of rules can contain rules. An empty slice is /// used for others. pub fn with_nested_rules_and_mq(&self, mut f: F) -> R - where F: FnMut(&[CssRule], Option<&MediaList>) -> R { + where F: FnMut(&[CssRule], Option<&MediaList>) -> R + { match *self { CssRule::Import(ref lock) => { let rule = lock.read(); diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index a22a799206f..84743325d12 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -72,9 +72,13 @@ pub trait ToComputedValue { fn from_computed_value(computed: &Self::ComputedValue) -> Self; } +/// A marker trait to represent that the specified value is also the computed +/// value. pub trait ComputedValueAsSpecified {} -impl ToComputedValue for T where T: ComputedValueAsSpecified + Clone { +impl ToComputedValue for T + where T: ComputedValueAsSpecified + Clone, +{ type ComputedValue = T; #[inline] diff --git a/components/style/values/mod.rs b/components/style/values/mod.rs index 3be4d742eff..ea073b86f11 100644 --- a/components/style/values/mod.rs +++ b/components/style/values/mod.rs @@ -34,7 +34,8 @@ macro_rules! define_numbered_css_keyword_enum { impl ToCss for $name { fn to_css(&self, dest: &mut W) -> ::std::fmt::Result - where W: ::std::fmt::Write { + where W: ::std::fmt::Write, + { match *self { $( $name::$variant => dest.write_str($css) ),+ } @@ -46,17 +47,26 @@ macro_rules! define_numbered_css_keyword_enum { pub mod computed; pub mod specified; +/// A CSS float value. pub type CSSFloat = f32; +/// The default font size. pub const FONT_MEDIUM_PX: i32 = 16; +/// A trait used to represent whether this value has viewport units. pub trait HasViewportPercentage { + /// Returns true if this value has viewport units. fn has_viewport_percentage(&self) -> bool; } +/// A trait used as a marker to represent that a given value has no viewport +/// units. pub trait NoViewportPercentage {} -impl HasViewportPercentage for T where T: NoViewportPercentage { +impl HasViewportPercentage for T + where T: NoViewportPercentage, +{ + #[inline] fn has_viewport_percentage(&self) -> bool { false } diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index 40fb57a4963..e20b79ad82f 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -23,15 +23,22 @@ pub use super::image::{SizeKeyword, VerticalDirection}; #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +/// A font relative length. pub enum FontRelativeLength { + /// A "em" value: https://drafts.csswg.org/css-values/#em Em(CSSFloat), + /// A "ex" value: https://drafts.csswg.org/css-values/#ex Ex(CSSFloat), + /// A "ch" value: https://drafts.csswg.org/css-values/#ch Ch(CSSFloat), + /// A "rem" value: https://drafts.csswg.org/css-values/#rem Rem(CSSFloat) } impl ToCss for FontRelativeLength { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + fn to_css(&self, dest: &mut W) -> fmt::Result + where W: fmt::Write + { match *self { FontRelativeLength::Em(length) => write!(dest, "{}em", length), FontRelativeLength::Ex(length) => write!(dest, "{}ex", length), diff --git a/components/style/viewport.rs b/components/style/viewport.rs index 2e965da4e54..646a80398a4 100644 --- a/components/style/viewport.rs +++ b/components/style/viewport.rs @@ -127,7 +127,7 @@ pub enum ViewportLength { impl ToCss for ViewportLength { fn to_css(&self, dest: &mut W) -> fmt::Result - where W: fmt::Write + where W: fmt::Write, { match *self { ViewportLength::Specified(length) => length.to_css(dest), @@ -545,7 +545,9 @@ impl Cascade { } pub fn from_stylesheets<'a, I>(stylesheets: I, device: &Device) -> Self - where I: IntoIterator, I::Item: AsRef { + where I: IntoIterator, + I::Item: AsRef, + { let mut cascade = Self::new(); for stylesheet in stylesheets { stylesheet.as_ref().effective_viewport_rules(device, |rule| { @@ -581,10 +583,13 @@ impl Cascade { } } +/// Just a helper trait to be able to implement methods on ViewportConstraints. pub trait MaybeNew { + /// Create a ViewportConstraints from a viewport size and a `@viewport` + /// rule. fn maybe_new(initial_viewport: TypedSize2D, - rule: &ViewportRule) - -> Option; + rule: &ViewportRule) + -> Option; } impl MaybeNew for ViewportConstraints { diff --git a/components/style_traits/values.rs b/components/style_traits/values.rs index b737b6e9b54..f89f442df57 100644 --- a/components/style_traits/values.rs +++ b/components/style_traits/values.rs @@ -95,11 +95,12 @@ macro_rules! __define_css_keyword_enum__actual { impl ToCss for $name { fn to_css(&self, dest: &mut W) -> ::std::fmt::Result - where W: ::std::fmt::Write { - match *self { - $( $name::$variant => dest.write_str($css) ),+ - } + where W: ::std::fmt::Write + { + match *self { + $( $name::$variant => dest.write_str($css) ),+ } + } } } } From 9a8c94b998ff6b8bcfa408e78ebfc26059fb0f36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 31 Dec 2016 03:31:05 +0100 Subject: [PATCH 06/19] style: Document a bit better the rule tree code. --- components/style/rule_tree/mod.rs | 49 ++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/components/style/rule_tree/mod.rs b/components/style/rule_tree/mod.rs index 1ba4232dd44..932b30a8125 100644 --- a/components/style/rule_tree/mod.rs +++ b/components/style/rule_tree/mod.rs @@ -3,6 +3,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #![allow(unsafe_code)] +#![deny(missing_docs)] + +//! The rule tree. use arc_ptr_eq; #[cfg(feature = "servo")] @@ -17,15 +20,40 @@ use std::sync::atomic::{AtomicPtr, AtomicUsize, Ordering}; use stylesheets::StyleRule; use thread_state; +/// The rule tree, the structure servo uses to preserve the results of selector +/// matching. +/// +/// This is organized as a tree of rules. When a node matches a set of rules, +/// they're inserted in order in the tree, starting with the less specific one. +/// +/// When a rule is inserted in the tree, other elements may share the path up to +/// a given rule. If that's the case, we don't duplicate child nodes, but share +/// them. +/// +/// When the rule node refcount drops to zero, it doesn't get freed. It gets +/// instead put into a free list, and it is potentially GC'd after a while in a +/// single-threaded fashion. +/// +/// That way, a rule node that represents a likely-to-match-again rule (like a +/// :hover rule) can be reused if we haven't GC'd it yet. #[derive(Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct RuleTree { root: StrongRuleNode, } +/// A style source for the rule node. It can either be a CSS style rule or a +/// declaration block. +/// +/// Note that, even though the declaration block from inside the style rule +/// could be enough to implement the rule tree, keeping the whole rule provides +/// more debuggability, and also the ability of show those selectors to +/// devtools. #[derive(Debug, Clone)] pub enum StyleSource { + /// A style rule stable pointer. Style(Arc>), + /// A declaration block stable pointer. Declarations(Arc>), } @@ -34,8 +62,11 @@ type StyleSourceGuardHandle<'a> = RwLockReadGuard<'a, StyleRule>, RwLockReadGuard<'a, PropertyDeclarationBlock>>; +/// A guard for a given style source. pub enum StyleSourceGuard<'a> { + /// A guard for a style rule. Style(StyleSourceGuardHandle<'a>), + /// A guard for a declaration block. Declarations(RwLockReadGuard<'a, PropertyDeclarationBlock>), } @@ -71,6 +102,8 @@ impl StyleSource { let _ = write!(writer, " -> {:?}", self.read().declarations); } + /// Read the style source guard, and obtain thus read access to the + /// underlying property declaration block. #[inline] pub fn read<'a>(&'a self) -> StyleSourceGuard<'a> { use self::StyleSource::*; @@ -87,15 +120,19 @@ impl StyleSource { /// This value exists here so a node that pushes itself to the list can know /// that is in the free list by looking at is next pointer, and comparing it /// with null. +/// +/// The root node doesn't have a null pointer in the free list, but this value. const FREE_LIST_SENTINEL: *mut RuleNode = 0x01 as *mut RuleNode; impl RuleTree { + /// Construct a new rule tree. pub fn new() -> Self { RuleTree { root: StrongRuleNode::new(Box::new(RuleNode::root())), } } + /// Get the root rule node. pub fn root(&self) -> StrongRuleNode { self.root.clone() } @@ -105,13 +142,16 @@ impl RuleTree { self.root.get().dump(writer, 0); } + /// Dump the rule tree to stdout. pub fn dump_stdout(&self) { let mut stdout = io::stdout(); self.dump(&mut stdout); } + /// Insert the given rules, that must be in proper order by specifity, and + /// return the corresponding rule node representing the last inserted one. pub fn insert_ordered_rules<'a, I>(&self, iter: I) -> StrongRuleNode - where I: Iterator + where I: Iterator, { let mut current = self.root.clone(); for (source, importance) in iter { @@ -294,6 +334,7 @@ struct WeakRuleNode { ptr: *mut RuleNode, } +/// A strong reference to a rule node. #[derive(Debug)] pub struct StrongRuleNode { ptr: *mut RuleNode, @@ -412,14 +453,19 @@ impl StrongRuleNode { unsafe { &*self.ptr } } + /// Get the style source corresponding to this rule node. May return `None` + /// if it's the root node, which means that the node hasn't matched any + /// rules. pub fn style_source(&self) -> Option<&StyleSource> { self.get().source.as_ref() } + /// Get the importance that this rule node represents. pub fn importance(&self) -> Importance { self.get().importance } + /// Get an iterator for this rule node and its ancestors. pub fn self_and_ancestors(&self) -> SelfAndAncestors { SelfAndAncestors { current: Some(self) @@ -527,6 +573,7 @@ impl StrongRuleNode { } } +/// An iterator over a rule node and its ancestors. #[derive(Clone)] pub struct SelfAndAncestors<'a> { current: Option<&'a StrongRuleNode>, From a0d425e8cee39ae98940f3927721012964f9b643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 31 Dec 2016 03:32:04 +0100 Subject: [PATCH 07/19] style: Document and cleanup str.rs --- components/style/str.rs | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/components/style/str.rs b/components/style/str.rs index be763892118..e84394ece39 100644 --- a/components/style/str.rs +++ b/components/style/str.rs @@ -2,6 +2,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +//! String utils for attributes and similar stuff. + +#![deny(missing_docs)] + use num_traits::ToPrimitive; use std::ascii::AsciiExt; use std::borrow::Cow; @@ -9,7 +13,10 @@ use std::convert::AsRef; use std::iter::{Filter, Peekable}; use std::str::Split; +/// A static slice of characters. pub type StaticCharVec = &'static [char]; + +/// A static slice of `str`s. pub type StaticStringVec = &'static [&'static str]; /// A "space character" according to: @@ -23,23 +30,31 @@ pub static HTML_SPACE_CHARACTERS: StaticCharVec = &[ '\u{000d}', ]; +/// Whether a character is a HTML whitespace character. #[inline] pub fn char_is_whitespace(c: char) -> bool { HTML_SPACE_CHARACTERS.contains(&c) } +/// Whether all the string is HTML whitespace. +#[inline] pub fn is_whitespace(s: &str) -> bool { s.chars().all(char_is_whitespace) } +#[inline] +fn not_empty(&split: &&str) -> bool { !split.is_empty() } + +/// Split a string on HTML whitespace. +#[inline] pub fn split_html_space_chars<'a>(s: &'a str) -> Filter, fn(&&str) -> bool> { - fn not_empty(&split: &&str) -> bool { !split.is_empty() } s.split(HTML_SPACE_CHARACTERS).filter(not_empty as fn(&&str) -> bool) } +/// Split a string on commas. +#[inline] pub fn split_commas<'a>(s: &'a str) -> Filter, fn(&&str) -> bool> { - fn not_empty(&split: &&str) -> bool { !split.is_empty() } s.split(',').filter(not_empty as fn(&&str) -> bool) } @@ -61,6 +76,7 @@ fn is_exponent_char(c: char) -> bool { } } +/// Read a set of ascii digits and read them into a number. pub fn read_numbers>(mut iter: Peekable) -> (Option, usize) { match iter.peek() { Some(c) if is_ascii_digit(c) => (), @@ -79,6 +95,7 @@ pub fn read_numbers>(mut iter: Peekable) -> (Option>(mut iter: Peekable, mut divisor: f64, value: f64) -> (f64, usize) { @@ -92,11 +109,11 @@ pub fn read_fraction>(mut iter: Peekable, d as i64 - '0' as i64 ).fold((value, 1), |accumulator, d| { divisor *= 10f64; - (accumulator.0 + d as f64 / divisor, - accumulator.1 + 1) + (accumulator.0 + d as f64 / divisor, accumulator.1 + 1) }) } +/// Reads an exponent from an iterator over chars, for example `e100`. pub fn read_exponent>(mut iter: Peekable) -> Option { match iter.peek() { Some(c) if is_exponent_char(*c) => (), @@ -118,8 +135,10 @@ pub fn read_exponent>(mut iter: Peekable) -> Option(strs: I, join: &str) -> String - where I: IntoIterator, T: AsRef, + where I: IntoIterator, + T: AsRef, { strs.into_iter().enumerate().fold(String::new(), |mut acc, (i, s)| { if i > 0 { acc.push_str(join); } From f37aa1292706ebcf6727aea4ef30707d8e0e0569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 31 Dec 2016 03:34:59 +0100 Subject: [PATCH 08/19] style: Prevent more missing docs in the values module. --- .../style/values/computed/basic_shape.rs | 8 ++ components/style/values/computed/image.rs | 6 ++ components/style/values/computed/length.rs | 20 +++- components/style/values/computed/mod.rs | 32 ++++++- components/style/values/computed/position.rs | 3 + components/style/values/mod.rs | 15 ++- .../style/values/specified/basic_shape.rs | 16 ++++ components/style/values/specified/grid.rs | 5 +- components/style/values/specified/image.rs | 14 +++ components/style/values/specified/length.rs | 94 ++++++++++++++++++- components/style/values/specified/mod.rs | 51 +++++++--- components/style/values/specified/position.rs | 37 +++++--- components/style/values/specified/url.rs | 17 ++++ 13 files changed, 281 insertions(+), 37 deletions(-) diff --git a/components/style/values/computed/basic_shape.rs b/components/style/values/computed/basic_shape.rs index 6428022538f..a3848195e47 100644 --- a/components/style/values/computed/basic_shape.rs +++ b/components/style/values/computed/basic_shape.rs @@ -18,6 +18,7 @@ pub use values::specified::basic_shape::{FillRule, GeometryBox, ShapeBox}; #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum ShapeSource { Url(SpecifiedUrl), Shape(BasicShape, Option), @@ -51,6 +52,7 @@ impl ToCss for ShapeSource { #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum BasicShape { Inset(InsetRect), Circle(Circle), @@ -71,6 +73,7 @@ impl ToCss for BasicShape { #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub struct InsetRect { pub top: LengthOrPercentage, pub right: LengthOrPercentage, @@ -100,6 +103,7 @@ impl ToCss for InsetRect { #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub struct Circle { pub radius: ShapeRadius, pub position: Position, @@ -115,6 +119,7 @@ impl ToCss for Circle { #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub struct Ellipse { pub semiaxis_x: ShapeRadius, pub semiaxis_y: ShapeRadius, @@ -138,6 +143,7 @@ impl ToCss for Ellipse { #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] /// https://drafts.csswg.org/css-shapes/#funcdef-polygon pub struct Polygon { pub fill: FillRule, @@ -168,6 +174,7 @@ impl ToCss for Polygon { /// https://drafts.csswg.org/css-shapes/#typedef-shape-radius #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum ShapeRadius { Length(LengthOrPercentage), ClosestSide, @@ -193,6 +200,7 @@ impl ToCss for ShapeRadius { /// https://drafts.csswg.org/css-backgrounds-3/#border-radius #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub struct BorderRadius { pub top_left: BorderRadiusSize, pub top_right: BorderRadiusSize, diff --git a/components/style/values/computed/image.rs b/components/style/values/computed/image.rs index 5ddb28e1fc8..393253ce805 100644 --- a/components/style/values/computed/image.rs +++ b/components/style/values/computed/image.rs @@ -51,6 +51,7 @@ impl ToComputedValue for specified::Image { /// https://drafts.csswg.org/css-images/#image-values #[derive(Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum Image { Url(SpecifiedUrl), Gradient(Gradient), @@ -174,6 +175,7 @@ impl ToComputedValue for specified::Gradient { /// https://drafts.csswg.org/css-images/#gradients #[derive(Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum GradientKind { Linear(AngleOrCorner), Radial(EndingShape, Position), @@ -271,6 +273,7 @@ impl ToComputedValue for specified::ColorStop { /// https://drafts.csswg.org/css-images/#valdef-radial-gradient-ending-shape #[derive(Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum EndingShape { Circle(LengthOrKeyword), Ellipse(LengthOrPercentageOrKeyword), @@ -336,6 +339,7 @@ impl ToComputedValue for specified::GradientEndingShape { /// https://drafts.csswg.org/css-images/#valdef-radial-gradient-size #[derive(Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum LengthOrKeyword { Length(Length), Keyword(SizeKeyword), @@ -394,6 +398,7 @@ impl ToComputedValue for specified::LengthOrKeyword { /// https://drafts.csswg.org/css-images/#valdef-radial-gradient-size #[derive(Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum LengthOrPercentageOrKeyword { LengthOrPercentage(LengthOrPercentage, LengthOrPercentage), Keyword(SizeKeyword), @@ -458,6 +463,7 @@ impl ToComputedValue for specified::LengthOrPercentageOrKeyword { #[derive(Clone, Copy, Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum AngleOrCorner { Angle(Angle), Corner(HorizontalDirection, VerticalDirection) diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index a7ec7f5ba22..5ff6b5f0c46 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -2,6 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +//! `` computed values, and related ones. + use app_units::Au; use ordered_float::NotNaN; use std::fmt; @@ -16,6 +18,7 @@ pub use values::specified::{Angle, BorderStyle, Time, UrlOrNone}; #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub struct CalcLengthOrPercentage { pub length: Au, pub percentage: Option, @@ -23,11 +26,13 @@ pub struct CalcLengthOrPercentage { impl CalcLengthOrPercentage { #[inline] + #[allow(missing_docs)] pub fn length(&self) -> Au { self.length } #[inline] + #[allow(missing_docs)] pub fn percentage(&self) -> CSSFloat { self.percentage.unwrap_or(0.) } @@ -130,6 +135,7 @@ impl ToComputedValue for specified::CalcLengthOrPercentage { #[derive(PartialEq, Clone, Copy)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum LengthOrPercentage { Length(Au), Percentage(CSSFloat), @@ -138,6 +144,7 @@ pub enum LengthOrPercentage { impl LengthOrPercentage { #[inline] + #[allow(missing_docs)] pub fn zero() -> LengthOrPercentage { LengthOrPercentage::Length(Au(0)) } @@ -154,6 +161,7 @@ impl LengthOrPercentage { } } + #[allow(missing_docs)] pub fn to_hash_key(&self) -> (Au, NotNaN) { use self::LengthOrPercentage::*; match *self { @@ -223,6 +231,7 @@ impl ToCss for LengthOrPercentage { #[derive(PartialEq, Clone, Copy)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum LengthOrPercentageOrAuto { Length(Au), Percentage(CSSFloat), @@ -311,6 +320,7 @@ impl ToCss for LengthOrPercentageOrAuto { #[derive(PartialEq, Clone, Copy)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum LengthOrPercentageOrAutoOrContent { Length(Au), Percentage(CSSFloat), @@ -397,6 +407,7 @@ impl ToCss for LengthOrPercentageOrAutoOrContent { #[derive(PartialEq, Clone, Copy)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum LengthOrPercentageOrNone { Length(Au), Percentage(CSSFloat), @@ -469,12 +480,17 @@ impl ToCss for LengthOrPercentageOrNone { } } +/// A computed `` value. +pub type Length = Au; + +/// Either a computed `` or the `none` keyword. pub type LengthOrNone = Either; +/// Either a computed `` or the `auto` keyword. pub type LengthOrAuto = Either; +/// Either a computed `` or a `` value. pub type LengthOrNumber = Either; +/// Either a computed `` or the `normal` keyword. pub type LengthOrNormal = Either; - -pub type Length = Au; diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 84743325d12..2f8ca20fd42 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -2,6 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +//! Computed values. + use app_units::Au; use euclid::size::Size2D; use font_metrics::FontMetricsProvider; @@ -24,23 +26,41 @@ pub mod image; pub mod length; pub mod position; +/// A `Context` is all the data a specified value could ever need to compute +/// itself and be transformed to a computed value. pub struct Context<'a> { + /// Whether the current element is the root element. pub is_root_element: bool, + + /// The current viewport size. pub viewport_size: Size2D, + + /// The style we're inheriting from. pub inherited_style: &'a ComputedValues, /// Values access through this need to be in the properties "computed /// early": color, text-decoration, font-size, display, position, float, /// border-*-style, outline-style, font-family, writing-mode... pub style: ComputedValues, + + /// A font metrics provider, used to access font metrics to implement + /// font-relative units. + /// + /// TODO(emilio): This should be required, see #14079. pub font_metrics_provider: Option<&'a FontMetricsProvider>, } impl<'a> Context<'a> { + /// Whether the current element is the root element. pub fn is_root_element(&self) -> bool { self.is_root_element } + /// The current viewport size. pub fn viewport_size(&self) -> Size2D { self.viewport_size } + /// The style we're inheriting from. pub fn inherited_style(&self) -> &ComputedValues { &self.inherited_style } + /// The current style. Note that only "eager" properties should be accessed + /// from here, see the comment in the member. pub fn style(&self) -> &ComputedValues { &self.style } + /// A mutable reference to the current style. pub fn mutate_style(&mut self) -> &mut ComputedValues { &mut self.style } /// Creates a dummy computed context for use in multiple places, like @@ -58,11 +78,15 @@ impl<'a> Context<'a> { } } +/// A trait to represent the conversion between computed and specified values. pub trait ToComputedValue { + /// The computed value type we're going to be converted to. type ComputedValue; + /// Convert a specified value to a computed value, using itself and the data + /// inside the `Context`. #[inline] - fn to_computed_value(&self, _context: &Context) -> Self::ComputedValue; + fn to_computed_value(&self, context: &Context) -> Self::ComputedValue; #[inline] /// Convert a computed value to specified value form. @@ -137,9 +161,11 @@ impl ToComputedValue for specified::Length { #[derive(Debug, PartialEq, Clone, Copy)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub struct BorderRadiusSize(pub Size2D); impl BorderRadiusSize { + #[allow(missing_docs)] pub fn zero() -> BorderRadiusSize { BorderRadiusSize(Size2D::new(LengthOrPercentage::Length(Au(0)), LengthOrPercentage::Length(Au(0)))) } @@ -173,6 +199,7 @@ impl ToCss for BorderRadiusSize { #[derive(Debug, PartialEq, Clone, Copy)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub struct Shadow { pub offset_x: Au, pub offset_y: Au, @@ -182,5 +209,8 @@ pub struct Shadow { pub inset: bool, } +/// A `` value. pub type Number = CSSFloat; + +/// A type used for opacity. pub type Opacity = CSSFloat; diff --git a/components/style/values/computed/position.rs b/components/style/values/computed/position.rs index f93d59db99c..a9b51953810 100644 --- a/components/style/values/computed/position.rs +++ b/components/style/values/computed/position.rs @@ -13,6 +13,7 @@ use values::computed::LengthOrPercentage; #[derive(Debug, Clone, PartialEq, Copy)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub struct Position { pub horizontal: LengthOrPercentage, pub vertical: LengthOrPercentage, @@ -29,6 +30,7 @@ impl ToCss for Position { #[derive(Debug, Clone, PartialEq, Copy)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub struct HorizontalPosition(pub LengthOrPercentage); impl ToCss for HorizontalPosition { @@ -39,6 +41,7 @@ impl ToCss for HorizontalPosition { #[derive(Debug, Clone, PartialEq, Copy)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub struct VerticalPosition(pub LengthOrPercentage); impl ToCss for VerticalPosition { diff --git a/components/style/values/mod.rs b/components/style/values/mod.rs index ea073b86f11..9a49fa9b73c 100644 --- a/components/style/values/mod.rs +++ b/components/style/values/mod.rs @@ -6,6 +6,8 @@ //! //! [values]: https://drafts.csswg.org/css-values/ +#![deny(missing_docs)] + pub use cssparser::{RGBA, Parser}; use parser::{Parse, ParserContext}; use std::fmt::{self, Debug}; @@ -16,7 +18,7 @@ macro_rules! define_numbered_css_keyword_enum { define_numbered_css_keyword_enum!($name: $( $css => $variant = $value ),+); }; ($name: ident: $( $css: expr => $variant: ident = $value: expr ),+) => { - #[allow(non_camel_case_types)] + #[allow(non_camel_case_types, missing_docs)] #[derive(Clone, Eq, PartialEq, PartialOrd, Ord, Copy, RustcEncodable, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))] pub enum $name { @@ -24,6 +26,7 @@ macro_rules! define_numbered_css_keyword_enum { } impl $name { + #[allow(missing_docs)] pub fn parse(input: &mut ::cssparser::Parser) -> Result<$name, ()> { match_ignore_ascii_case! { try!(input.expect_ident()), $( $css => Ok($name::$variant), )+ @@ -53,14 +56,14 @@ pub type CSSFloat = f32; /// The default font size. pub const FONT_MEDIUM_PX: i32 = 16; -/// A trait used to represent whether this value has viewport units. +/// A trait used to query whether this value has viewport units. pub trait HasViewportPercentage { /// Returns true if this value has viewport units. fn has_viewport_percentage(&self) -> bool; } -/// A trait used as a marker to represent that a given value has no viewport -/// units. +/// A trait used as a marker to represent that a given type may never contain +/// viewport units. pub trait NoViewportPercentage {} impl HasViewportPercentage for T @@ -78,6 +81,7 @@ macro_rules! define_keyword_type { ($name: ident, $css: expr) => { #[derive(Clone, PartialEq, Copy)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + #[allow(missing_docs)] pub struct $name; impl ::style_traits::ToCss for $name { @@ -109,8 +113,11 @@ define_keyword_type!(Normal, "normal"); #[derive(Clone, PartialEq, Copy)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +/// A struct representing one of two kinds of values. pub enum Either { + /// The first value. First(A), + /// The second kind of value. Second(B), } diff --git a/components/style/values/specified/basic_shape.rs b/components/style/values/specified/basic_shape.rs index a943d4ec7da..1d2ebd6c0ea 100644 --- a/components/style/values/specified/basic_shape.rs +++ b/components/style/values/specified/basic_shape.rs @@ -24,6 +24,7 @@ use values::specified::url::SpecifiedUrl; /// shape-outside uses ShapeSource #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum ShapeSource { Url(SpecifiedUrl), Shape(BasicShape, Option), @@ -55,6 +56,7 @@ impl ToCss for ShapeSource { } impl ShapeSource { + #[allow(missing_docs)] pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { if let Ok(_) = input.try(|input| input.expect_ident_matching("none")) { Ok(ShapeSource::None) @@ -129,6 +131,7 @@ impl ToComputedValue for ShapeSource { #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum BasicShape { Inset(InsetRect), Circle(Circle), @@ -205,6 +208,7 @@ impl ToComputedValue for BasicShape { #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] /// https://drafts.csswg.org/css-shapes/#funcdef-inset +#[allow(missing_docs)] pub struct InsetRect { pub top: LengthOrPercentage, pub right: LengthOrPercentage, @@ -214,6 +218,7 @@ pub struct InsetRect { } impl InsetRect { + #[allow(missing_docs)] pub fn parse_function_arguments(context: &ParserContext, input: &mut Parser) -> Result { let (t, r, b, l) = try!(parse_four_sides(input, |i| LengthOrPercentage::parse(context, i))); let mut rect = InsetRect { @@ -373,12 +378,14 @@ fn serialize_basicshape_position(position: &Position, dest: &mut W) #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] /// https://drafts.csswg.org/css-shapes/#funcdef-circle +#[allow(missing_docs)] pub struct Circle { pub radius: ShapeRadius, pub position: Position, } impl Circle { + #[allow(missing_docs)] pub fn parse_function_arguments(context: &ParserContext, input: &mut Parser) -> Result { let radius = input.try(|i| ShapeRadius::parse(context, i)).ok().unwrap_or_else(Default::default); let position = if let Ok(_) = input.try(|input| input.expect_ident_matching("at")) { @@ -450,6 +457,7 @@ impl ToComputedValue for Circle { #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] /// https://drafts.csswg.org/css-shapes/#funcdef-ellipse +#[allow(missing_docs)] pub struct Ellipse { pub semiaxis_x: ShapeRadius, pub semiaxis_y: ShapeRadius, @@ -458,6 +466,7 @@ pub struct Ellipse { impl Ellipse { + #[allow(missing_docs)] pub fn parse_function_arguments(context: &ParserContext, input: &mut Parser) -> Result { let (a, b) = input.try(|input| -> Result<_, ()> { Ok((try!(ShapeRadius::parse(context, input)), try!(ShapeRadius::parse(context, input)))) @@ -537,12 +546,14 @@ impl ToComputedValue for Ellipse { #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] /// https://drafts.csswg.org/css-shapes/#funcdef-polygon +#[allow(missing_docs)] pub struct Polygon { pub fill: FillRule, pub coordinates: Vec<(LengthOrPercentage, LengthOrPercentage)>, } impl Polygon { + #[allow(missing_docs)] pub fn parse_function_arguments(context: &ParserContext, input: &mut Parser) -> Result { let fill = input.try(|input| { let fill = FillRule::parse(context, input); @@ -626,6 +637,7 @@ impl ToComputedValue for Polygon { /// https://drafts.csswg.org/css-shapes/#typedef-shape-radius #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum ShapeRadius { Length(LengthOrPercentage), ClosestSide, @@ -690,6 +702,7 @@ impl ToComputedValue for ShapeRadius { /// https://drafts.csswg.org/css-backgrounds-3/#border-radius #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub struct BorderRadius { pub top_left: BorderRadiusSize, pub top_right: BorderRadiusSize, @@ -792,6 +805,7 @@ impl ToComputedValue for BorderRadius { /// https://drafts.csswg.org/css-shapes/#typedef-fill-rule #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum FillRule { NonZero, EvenOdd, @@ -830,6 +844,7 @@ impl ToCss for FillRule { /// https://drafts.fxtf.org/css-masking-1/#typedef-geometry-box #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum GeometryBox { Fill, Stroke, @@ -868,6 +883,7 @@ impl ComputedValueAsSpecified for GeometryBox {} // https://drafts.csswg.org/css-shapes-1/#typedef-shape-box #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum ShapeBox { Margin, // https://drafts.csswg.org/css-backgrounds-3/#box diff --git a/components/style/values/specified/grid.rs b/components/style/values/specified/grid.rs index 8e6eca56372..1e414799ed9 100644 --- a/components/style/values/specified/grid.rs +++ b/components/style/values/specified/grid.rs @@ -2,6 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +//! A grid line type. + use cssparser::Parser; use parser::{Parse, ParserContext}; use std::fmt; @@ -9,9 +11,10 @@ use style_traits::ToCss; use values::NoViewportPercentage; use values::computed::ComputedValueAsSpecified; -// https://drafts.csswg.org/css-grid/#typedef-grid-row-start-grid-line #[derive(PartialEq, Clone, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +/// https://drafts.csswg.org/css-grid/#typedef-grid-row-start-grid-line +#[allow(missing_docs)] pub struct GridLine { pub is_span: bool, pub ident: Option, diff --git a/components/style/values/specified/image.rs b/components/style/values/specified/image.rs index af0ed3a2baf..9bf908a2ee5 100644 --- a/components/style/values/specified/image.rs +++ b/components/style/values/specified/image.rs @@ -21,7 +21,9 @@ use values::specified::url::{SpecifiedUrl, UrlExtraData}; #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum Image { + /// A `` image. Url(SpecifiedUrl), + /// A `` image. Gradient(Gradient), } @@ -35,6 +37,7 @@ impl ToCss for Image { } impl Image { + #[allow(missing_docs)] pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { if let Ok(url) = input.try(|input| SpecifiedUrl::parse(context, input)) { return Ok(Image::Url(url)); @@ -151,7 +154,14 @@ impl Gradient { #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum GradientKind { + /// A ``: + /// + /// https://drafts.csswg.org/css-images/#funcdef-linear-gradient Linear(AngleOrCorner), + + /// A ``: + /// + /// https://drafts.csswg.org/css-images/#radial-gradients Radial(EndingShape, Position), } @@ -234,6 +244,7 @@ fn parse_position(context: &ParserContext, input: &mut Parser) -> Result, Option), @@ -327,6 +338,7 @@ impl Parse for ColorStop { /// https://drafts.csswg.org/css-images/#valdef-radial-gradient-ending-shape #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum EndingShape { Circle(LengthOrKeyword), Ellipse(LengthOrPercentageOrKeyword), @@ -351,6 +363,7 @@ impl ToCss for EndingShape { /// https://drafts.csswg.org/css-images/#valdef-radial-gradient-size #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum LengthOrKeyword { Length(Length), Keyword(SizeKeyword), @@ -378,6 +391,7 @@ impl ToCss for LengthOrKeyword { /// https://drafts.csswg.org/css-images/#valdef-radial-gradient-size #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum LengthOrPercentageOrKeyword { LengthOrPercentage(LengthOrPercentage, LengthOrPercentage), Keyword(SizeKeyword), diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index e20b79ad82f..b86038eb19a 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -2,6 +2,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +//! [Length values][length]. +//! +//! [length]: https://drafts.csswg.org/css-values/#lengths + use app_units::Au; use cssparser::{Parser, Token}; use euclid::size::Size2D; @@ -49,6 +53,8 @@ impl ToCss for FontRelativeLength { } impl FontRelativeLength { + /// Gets the first available font metrics from the current context's + /// font-family list. pub fn find_first_available_font_metrics(context: &Context) -> Option { use font_metrics::FontMetricsQueryResult::*; if let Some(ref metrics_provider) = context.font_metrics_provider { @@ -62,8 +68,8 @@ impl FontRelativeLength { None } - // NB: The use_inherited flag is used to special-case the computation of - // font-family. + /// Computes the font-relative length. We use the use_inherited flag to + /// special-case the computation of font-size. pub fn to_computed_value(&self, context: &Context, use_inherited: bool) -> Au { let reference_font_size = if use_inherited { context.inherited_style().get_font().clone_font_size() @@ -128,10 +134,17 @@ impl FontRelativeLength { #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +/// A viewport-relative length. +/// +/// https://drafts.csswg.org/css-values/#viewport-relative-lengths pub enum ViewportPercentageLength { + /// A vw unit: https://drafts.csswg.org/css-values/#vw Vw(CSSFloat), + /// A vh unit: https://drafts.csswg.org/css-values/#vh Vh(CSSFloat), + /// https://drafts.csswg.org/css-values/#vmin Vmin(CSSFloat), + /// https://drafts.csswg.org/css-values/#vmax Vmax(CSSFloat) } @@ -153,6 +166,7 @@ impl ToCss for ViewportPercentageLength { } impl ViewportPercentageLength { + /// Computes the given viewport-relative length for the given viewport size. pub fn to_computed_value(&self, viewport_size: Size2D) -> Au { macro_rules! to_unit { ($viewport_dimension:expr) => { @@ -174,11 +188,13 @@ impl ViewportPercentageLength { } } +/// HTML5 "character width", as defined in HTML5 ยง 14.5.4. #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct CharacterWidth(pub i32); impl CharacterWidth { + /// Computes the given character width. pub fn to_computed_value(&self, reference_font_size: Au) -> Au { // This applies the *converting a character width to pixels* algorithm as specified // in HTML5 ยง 14.5.4. @@ -190,11 +206,23 @@ impl CharacterWidth { } } +/// A length. +/// +/// https://drafts.csswg.org/css-values/#lengths #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum Length { + /// An absolute length: https://drafts.csswg.org/css-values/#absolute-length Absolute(Au), // application units + + /// A font-relative length: + /// + /// https://drafts.csswg.org/css-values/#font-relative-lengths FontRelative(FontRelativeLength), + + /// A viewport-relative length. + /// + /// https://drafts.csswg.org/css-values/#viewport-relative-lengths ViewportPercentage(ViewportPercentageLength), /// HTML5 "character width", as defined in HTML5 ยง 14.5.4. @@ -203,6 +231,12 @@ pub enum Length { /// `Stylist::synthesize_rules_for_legacy_attributes()`. ServoCharacterWidth(CharacterWidth), + /// A calc expression. + /// + /// https://drafts.csswg.org/css-values/#calc-notation + /// + /// TODO(emilio): We have more `Calc` variants around, we should only use + /// one. Calc(CalcLengthOrPercentage, AllowedNumericType), } @@ -281,7 +315,7 @@ const AU_PER_PT: CSSFloat = AU_PER_IN / 72.; const AU_PER_PC: CSSFloat = AU_PER_PT * 12.; impl Length { - // https://drafts.csswg.org/css-fonts-3/#font-size-prop + /// https://drafts.csswg.org/css-fonts-3/#font-size-prop pub fn from_str(s: &str) -> Option { Some(match_ignore_ascii_case! { s, "xx-small" => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 3 / 5), @@ -313,9 +347,13 @@ impl Length { _ => Err(()) } } + + /// Parse a non-negative length pub fn parse_non_negative(input: &mut Parser) -> Result { Length::parse_internal(input, AllowedNumericType::NonNegative) } + + /// Parse a given absolute or relative dimension. pub fn parse_dimension(value: CSSFloat, unit: &str) -> Result { match_ignore_ascii_case! { unit, "px" => Ok(Length::from_px(value)), @@ -338,6 +376,8 @@ impl Length { _ => Err(()) } } + + /// Get an absolute length from a px values. #[inline] pub fn from_px(px_value: CSSFloat) -> Length { Length::Absolute(Au((px_value * AU_PER_PX) as i32)) @@ -352,22 +392,29 @@ impl Parse for Length { impl Either { #[inline] + #[allow(missing_docs)] pub fn parse_non_negative_length(_context: &ParserContext, input: &mut Parser) -> Result { Length::parse_internal(input, AllowedNumericType::NonNegative).map(Either::First) } } +/// A calc sum expression node. #[derive(Clone, Debug)] pub struct CalcSumNode { + /// The products of this node. pub products: Vec, } +/// A calc product expression node. #[derive(Clone, Debug)] pub struct CalcProductNode { + /// The values inside this product node. values: Vec } +/// A value inside a `Calc` expression. #[derive(Clone, Debug)] +#[allow(missing_docs)] pub enum CalcValueNode { Length(Length), Angle(Angle), @@ -378,6 +425,7 @@ pub enum CalcValueNode { } #[derive(Clone, Copy, PartialEq)] +#[allow(missing_docs)] pub enum CalcUnit { Number, Integer, @@ -389,6 +437,7 @@ pub enum CalcUnit { #[derive(Clone, PartialEq, Copy, Debug, Default)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub struct CalcLengthOrPercentage { pub absolute: Option, pub vw: Option, @@ -403,6 +452,7 @@ pub struct CalcLengthOrPercentage { } impl CalcLengthOrPercentage { + /// Parse a calc sum node. pub fn parse_sum(input: &mut Parser, expected_unit: CalcUnit) -> Result { let mut products = Vec::new(); products.push(try!(CalcLengthOrPercentage::parse_product(input, expected_unit))); @@ -523,6 +573,7 @@ impl CalcLengthOrPercentage { } } + #[allow(missing_docs)] pub fn simplify_product(node: &CalcProductNode) -> Result { let mut multiplier = 1.; let mut node_with_unit = None; @@ -561,6 +612,7 @@ impl CalcLengthOrPercentage { CalcLengthOrPercentage::parse(input, CalcUnit::LengthOrPercentage) } + #[allow(missing_docs)] pub fn parse(input: &mut Parser, expected_unit: CalcUnit) -> Result { let ast = try!(CalcLengthOrPercentage::parse_sum(input, expected_unit)); @@ -631,6 +683,7 @@ impl CalcLengthOrPercentage { }) } + #[allow(missing_docs)] pub fn parse_time(input: &mut Parser) -> Result { let ast = try!(CalcLengthOrPercentage::parse_sum(input, CalcUnit::Time)); @@ -658,6 +711,7 @@ impl CalcLengthOrPercentage { } } + #[allow(missing_docs)] pub fn parse_angle(input: &mut Parser) -> Result { let ast = try!(CalcLengthOrPercentage::parse_sum(input, CalcUnit::Angle)); @@ -747,9 +801,12 @@ impl ToCss for CalcLengthOrPercentage { } } +/// A percentage value. +/// +/// [0 .. 100%] maps to [0.0 .. 1.0] #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -pub struct Percentage(pub CSSFloat); // [0 .. 100%] maps to [0.0 .. 1.0] +pub struct Percentage(pub CSSFloat); impl ToCss for Percentage { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { @@ -769,8 +826,12 @@ impl Parse for Percentage { } } +/// A length or a percentage value. +/// +/// TODO(emilio): Does this make any sense vs. CalcLengthOrPercentage? #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum LengthOrPercentage { Length(Length), Percentage(Percentage), @@ -797,6 +858,7 @@ impl ToCss for LengthOrPercentage { } } impl LengthOrPercentage { + /// Returns a `zero` length. pub fn zero() -> LengthOrPercentage { LengthOrPercentage::Length(Length::Absolute(Au(0))) } @@ -819,6 +881,7 @@ impl LengthOrPercentage { } } + /// Parse a non-negative length. #[inline] pub fn parse_non_negative(input: &mut Parser) -> Result { LengthOrPercentage::parse_internal(input, AllowedNumericType::NonNegative) @@ -832,8 +895,11 @@ impl Parse for LengthOrPercentage { } } +/// TODO(emilio): Do the Length and Percentage variants make any sense with +/// CalcLengthOrPercentage? #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum LengthOrPercentageOrAuto { Length(Length), Percentage(Percentage), @@ -882,6 +948,8 @@ impl LengthOrPercentageOrAuto { _ => Err(()) } } + + /// Parse a non-negative length, percentage, or auto. #[inline] pub fn parse_non_negative(input: &mut Parser) -> Result { LengthOrPercentageOrAuto::parse_internal(input, AllowedNumericType::NonNegative) @@ -895,8 +963,11 @@ impl Parse for LengthOrPercentageOrAuto { } } +/// TODO(emilio): Do the Length and Percentage variants make any sense with +/// CalcLengthOrPercentage? #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum LengthOrPercentageOrNone { Length(Length), Percentage(Percentage), @@ -944,6 +1015,7 @@ impl LengthOrPercentageOrNone { _ => Err(()) } } + /// Parse a non-negative LengthOrPercentageOrNone. #[inline] pub fn parse_non_negative(input: &mut Parser) -> Result { LengthOrPercentageOrNone::parse_internal(input, AllowedNumericType::NonNegative) @@ -957,19 +1029,31 @@ impl Parse for LengthOrPercentageOrNone { } } +/// Either a `` or the `none` keyword. pub type LengthOrNone = Either; +/// Either a `` or the `normal` keyword. pub type LengthOrNormal = Either; +/// Either a `` or the `auto` keyword. pub type LengthOrAuto = Either; +/// Either a `` or a `` or the `auto` keyword or the +/// `content` keyword. +/// +/// TODO(emilio): Do the Length and Percentage variants make any sense with #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum LengthOrPercentageOrAutoOrContent { + /// A ``. Length(Length), + /// A percentage. Percentage(Percentage), + /// A `calc` node. Calc(CalcLengthOrPercentage), + /// The `auto` keyword. Auto, + /// The `content` keyword. Content } @@ -1018,9 +1102,11 @@ impl Parse for LengthOrPercentageOrAutoOrContent { } } +/// Either a `` or a ``. pub type LengthOrNumber = Either; impl LengthOrNumber { + /// Parse a non-negative LengthOrNumber. pub fn parse_non_negative(input: &mut Parser) -> Result { if let Ok(v) = input.try(Length::parse_non_negative) { Ok(Either::First(v)) diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 3b0dd2011b3..5ef9a1a9335 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -2,6 +2,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +//! Specified values. +//! +//! TODO(emilio): Enhance docs. + use app_units::Au; use cssparser::{self, Parser, Token}; use euclid::size::Size2D; @@ -35,6 +39,7 @@ impl NoViewportPercentage for i32 {} // For PropertyDeclaration::Order #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub struct CSSColor { pub parsed: cssparser::Color, pub authored: Option, @@ -68,6 +73,7 @@ impl ToCss for CSSColor { #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub struct CSSRGBA { pub parsed: cssparser::RGBA, pub authored: Option, @@ -85,6 +91,7 @@ impl ToCss for CSSRGBA { } #[derive(Clone, Debug)] +#[allow(missing_docs)] pub struct SimplifiedSumNode { values: Vec, } @@ -100,6 +107,7 @@ impl<'a> Mul for &'a SimplifiedSumNode { } #[derive(Clone, Debug)] +#[allow(missing_docs)] pub enum SimplifiedValueNode { Length(Length), Angle(Angle), @@ -127,6 +135,7 @@ impl<'a> Mul for &'a SimplifiedValueNode { } } +#[allow(missing_docs)] pub fn parse_integer(input: &mut Parser) -> Result { match try!(input.next()) { Token::Number(ref value) => value.int_value.ok_or(()), @@ -152,6 +161,7 @@ pub fn parse_integer(input: &mut Parser) -> Result { } } +#[allow(missing_docs)] pub fn parse_number(input: &mut Parser) -> Result { match try!(input.next()) { Token::Number(ref value) => Ok(value.value), @@ -179,20 +189,24 @@ pub fn parse_number(input: &mut Parser) -> Result { #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub struct BorderRadiusSize(pub Size2D); impl NoViewportPercentage for BorderRadiusSize {} impl BorderRadiusSize { + #[allow(missing_docs)] pub fn zero() -> BorderRadiusSize { let zero = LengthOrPercentage::Length(Length::Absolute(Au(0))); BorderRadiusSize(Size2D::new(zero, zero)) } + #[allow(missing_docs)] pub fn new(width: LengthOrPercentage, height: LengthOrPercentage) -> BorderRadiusSize { BorderRadiusSize(Size2D::new(width, height)) } + #[allow(missing_docs)] pub fn circle(radius: LengthOrPercentage) -> BorderRadiusSize { BorderRadiusSize(Size2D::new(radius, radius)) } @@ -228,11 +242,13 @@ impl ToCss for Angle { impl Angle { #[inline] + #[allow(missing_docs)] pub fn radians(self) -> f32 { self.0 } #[inline] + #[allow(missing_docs)] pub fn from_radians(r: f32) -> Self { Angle(r) } @@ -257,6 +273,7 @@ impl Parse for Angle { } impl Angle { + #[allow(missing_docs)] pub fn parse_dimension(value: CSSFloat, unit: &str) -> Result { match_ignore_ascii_case! { unit, "deg" => Ok(Angle(value * RAD_PER_DEG)), @@ -268,20 +285,22 @@ impl Angle { } } +#[allow(missing_docs)] pub fn parse_border_radius(context: &ParserContext, input: &mut Parser) -> Result { - input.try(|i| BorderRadiusSize::parse(context, i)).or_else(|()| { - match_ignore_ascii_case! { try!(input.expect_ident()), - "thin" => Ok(BorderRadiusSize::circle( - LengthOrPercentage::Length(Length::from_px(1.)))), - "medium" => Ok(BorderRadiusSize::circle( - LengthOrPercentage::Length(Length::from_px(3.)))), - "thick" => Ok(BorderRadiusSize::circle( - LengthOrPercentage::Length(Length::from_px(5.)))), - _ => Err(()) - } - }) + input.try(|i| BorderRadiusSize::parse(context, i)).or_else(|_| { + match_ignore_ascii_case! { try!(input.expect_ident()), + "thin" => Ok(BorderRadiusSize::circle( + LengthOrPercentage::Length(Length::from_px(1.)))), + "medium" => Ok(BorderRadiusSize::circle( + LengthOrPercentage::Length(Length::from_px(3.)))), + "thick" => Ok(BorderRadiusSize::circle( + LengthOrPercentage::Length(Length::from_px(5.)))), + _ => Err(()) + } + }) } +#[allow(missing_docs)] pub fn parse_border_width(input: &mut Parser) -> Result { input.try(Length::parse_non_negative).or_else(|()| { match_ignore_ascii_case! { try!(input.expect_ident()), @@ -295,6 +314,7 @@ pub fn parse_border_width(input: &mut Parser) -> Result { #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum BorderWidth { Thin, Medium, @@ -317,6 +337,7 @@ impl Parse for BorderWidth { } impl BorderWidth { + #[allow(missing_docs)] pub fn from_length(length: Length) -> Self { BorderWidth::Width(length) } @@ -382,6 +403,7 @@ define_numbered_css_keyword_enum! { BorderStyle: impl NoViewportPercentage for BorderStyle {} impl BorderStyle { + /// Whether this border style is either none or hidden. pub fn none_or_hidden(&self) -> bool { matches!(*self, BorderStyle::none | BorderStyle::hidden) } @@ -435,6 +457,7 @@ impl ToCss for Time { #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub struct Number(pub CSSFloat); impl NoViewportPercentage for Number {} @@ -453,10 +476,12 @@ impl Number { } } + #[allow(missing_docs)] pub fn parse_non_negative(input: &mut Parser) -> Result { Number::parse_with_minimum(input, 0.0) } + #[allow(missing_docs)] pub fn parse_at_least_one(input: &mut Parser) -> Result { Number::parse_with_minimum(input, 1.0) } @@ -482,6 +507,7 @@ impl ToCss for Number { #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub struct Opacity(pub CSSFloat); impl NoViewportPercentage for Opacity {} @@ -518,10 +544,12 @@ impl ToCss for Opacity { } } +#[allow(missing_docs)] pub type UrlOrNone = Either; #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub struct Shadow { pub offset_x: Length, pub offset_y: Length, @@ -573,6 +601,7 @@ impl ToComputedValue for Shadow { impl Shadow { // disable_spread_and_inset is for filter: drop-shadow(...) + #[allow(missing_docs)] pub fn parse(context: &ParserContext, input: &mut Parser, disable_spread_and_inset: bool) -> Result { use app_units::Au; let length_count = if disable_spread_and_inset { 3 } else { 4 }; diff --git a/components/style/values/specified/position.rs b/components/style/values/specified/position.rs index d572e076f6f..44dcc391933 100644 --- a/components/style/values/specified/position.rs +++ b/components/style/values/specified/position.rs @@ -20,8 +20,13 @@ use values::specified::{LengthOrPercentage, Percentage}; #[derive(Debug, Clone, PartialEq, Copy)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +/// A [position][pos]. +/// +/// [pos]: https://drafts.csswg.org/css-values/#position pub struct Position { + /// The horizontal component. pub horizontal: HorizontalPosition, + /// The vertical component. pub vertical: VerticalPosition, } @@ -59,9 +64,12 @@ impl HasViewportPercentage for Position { } impl Position { - pub fn new(mut first_position: Option, mut second_position: Option, - first_keyword: Option, second_keyword: Option) - -> Result { + /// Create a new position value. + pub fn new(mut first_position: Option, + mut second_position: Option, + first_keyword: Option, + second_keyword: Option) + -> Result { // Unwrap for checking if values are at right place. let first_key = first_keyword.unwrap_or(PositionComponent::Keyword(Keyword::Left)); let second_key = second_keyword.unwrap_or(PositionComponent::Keyword(Keyword::Top)); @@ -150,6 +158,7 @@ impl Position { }) } + /// Returns a "centered" position, as in "center center". pub fn center() -> Position { Position { horizontal: HorizontalPosition { @@ -242,6 +251,7 @@ impl ToComputedValue for Position { #[derive(Debug, Clone, PartialEq, Copy)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub struct HorizontalPosition { pub keyword: Option, pub position: Option, @@ -249,11 +259,7 @@ pub struct HorizontalPosition { impl HasViewportPercentage for HorizontalPosition { fn has_viewport_percentage(&self) -> bool { - if let Some(pos) = self.position { - pos.has_viewport_percentage() - } else { - false - } + self.position.map_or(false, |pos| pos.has_viewport_percentage()) } } @@ -371,6 +377,7 @@ impl ToComputedValue for HorizontalPosition { #[derive(Debug, Clone, PartialEq, Copy)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub struct VerticalPosition { pub keyword: Option, pub position: Option, @@ -378,11 +385,7 @@ pub struct VerticalPosition { impl HasViewportPercentage for VerticalPosition { fn has_viewport_percentage(&self) -> bool { - if let Some(pos) = self.position { - pos.has_viewport_percentage() - } else { - false - } + self.position.map_or(false, |pos| pos.has_viewport_percentage()) } } @@ -510,6 +513,7 @@ define_css_keyword_enum!(Keyword: "y-end" => YEnd); impl Keyword { + /// Convert the given keyword to a length or a percentage. pub fn to_length_or_percentage(self) -> LengthOrPercentage { match self { Keyword::Center => LengthOrPercentage::Percentage(Percentage(0.5)), @@ -532,10 +536,14 @@ enum PositionCategory { LengthOrPercentage, } -// http://dev.w3.org/csswg/css2/colors.html#propdef-background-position +/// A position component. +/// +/// http://dev.w3.org/csswg/css2/colors.html#propdef-background-position #[derive(Clone, PartialEq, Copy)] pub enum PositionComponent { + /// A `` Length(LengthOrPercentage), + /// A position keyword. Keyword(Keyword), } @@ -568,6 +576,7 @@ impl HasViewportPercentage for PositionComponent { } impl PositionComponent { + /// Convert the given position component to a length or a percentage. #[inline] pub fn to_length_or_percentage(self) -> LengthOrPercentage { match self { diff --git a/components/style/values/specified/url.rs b/components/style/values/specified/url.rs index d856aac924a..de58714c74f 100644 --- a/components/style/values/specified/url.rs +++ b/components/style/values/specified/url.rs @@ -18,23 +18,29 @@ use style_traits::ToCss; use values::NoViewportPercentage; use values::computed::ComputedValueAsSpecified; +/// A set of data needed in Gecko to represent a URL. #[derive(PartialEq, Clone, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf, Serialize, Deserialize, Eq))] pub struct UrlExtraData { + /// The base URI. #[cfg(feature = "gecko")] pub base: GeckoArcURI, + /// The referrer. #[cfg(feature = "gecko")] pub referrer: GeckoArcURI, + /// The principal that originated this URI. #[cfg(feature = "gecko")] pub principal: GeckoArcPrincipal, } impl UrlExtraData { + /// Constructs a `UrlExtraData`. #[cfg(feature = "servo")] pub fn make_from(_: &ParserContext) -> Option { Some(UrlExtraData { }) } + /// Constructs a `UrlExtraData`. #[cfg(feature = "gecko")] pub fn make_from(context: &ParserContext) -> Option { match context.extra_data { @@ -81,6 +87,11 @@ impl Parse for SpecifiedUrl { } impl SpecifiedUrl { + /// Try to parse a URL from a string value that is a valid CSS token for a + /// URL. + /// + /// Only returns `Err` for Gecko, in the case we can't construct a + /// `URLExtraData`. pub fn parse_from_string<'a>(url: Cow<'a, str>, context: &ParserContext) -> Result { @@ -104,14 +115,19 @@ impl SpecifiedUrl { }) } + /// Get this URL's extra data. pub fn extra_data(&self) -> &UrlExtraData { &self.extra_data } + /// Returns the resolved url if it was valid. pub fn url(&self) -> Option<&ServoUrl> { self.resolved.as_ref() } + /// Return the resolved url as string, or the empty string if it's invalid. + /// + /// TODO(emilio): Should we return the original one if needed? pub fn as_str(&self) -> &str { match self.resolved { Some(ref url) => url.as_str(), @@ -142,6 +158,7 @@ impl SpecifiedUrl { } } + /// Gets a new url from a string for unit tests. #[cfg(feature = "servo")] pub fn new_for_testing(url: &str) -> Self { SpecifiedUrl { From 5e521842784eed961ecc3ba8cce81ee104e445cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 31 Dec 2016 03:37:36 +0100 Subject: [PATCH 09/19] style: Make the viewport module deny new undocumented code. --- components/style/viewport.rs | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/components/style/viewport.rs b/components/style/viewport.rs index 646a80398a4..d8d45016b25 100644 --- a/components/style/viewport.rs +++ b/components/style/viewport.rs @@ -7,6 +7,8 @@ //! [at]: https://drafts.csswg.org/css-device-adapt/#atviewport-rule //! [meta]: https://drafts.csswg.org/css-device-adapt/#viewport-meta +#![deny(missing_docs)] + use app_units::Au; use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser, parse_important}; use cssparser::ToCss as ParserToCss; @@ -60,6 +62,7 @@ macro_rules! declare_viewport_descriptor_inner { ) => { #[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + #[allow(missing_docs)] pub enum ViewportDescriptor { $( $assigned_variant($assigned_data), @@ -69,6 +72,7 @@ macro_rules! declare_viewport_descriptor_inner { const VIEWPORT_DESCRIPTOR_VARIANTS: usize = $number_of_variants; impl ViewportDescriptor { + #[allow(missing_docs)] pub fn discriminant_value(&self) -> usize { match *self { $( @@ -114,12 +118,13 @@ trait FromMeta: Sized { fn from_meta(value: &str) -> Option; } -// ViewportLength is a length | percentage | auto | extend-to-zoom -// See: -// * http://dev.w3.org/csswg/css-device-adapt/#min-max-width-desc -// * http://dev.w3.org/csswg/css-device-adapt/#extend-to-zoom +/// ViewportLength is a length | percentage | auto | extend-to-zoom +/// See: +/// * http://dev.w3.org/csswg/css-device-adapt/#min-max-width-desc +/// * http://dev.w3.org/csswg/css-device-adapt/#extend-to-zoom #[derive(Copy, Clone, Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum ViewportLength { Specified(LengthOrPercentageOrAuto), ExtendToZoom @@ -209,6 +214,7 @@ struct ViewportRuleParser<'a, 'b: 'a> { #[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub struct ViewportDescriptorDeclaration { pub origin: Origin, pub descriptor: ViewportDescriptor, @@ -216,6 +222,7 @@ pub struct ViewportDescriptorDeclaration { } impl ViewportDescriptorDeclaration { + #[allow(missing_docs)] pub fn new(origin: Origin, descriptor: ViewportDescriptor, important: bool) -> ViewportDescriptorDeclaration @@ -313,9 +320,11 @@ impl<'a, 'b> DeclarationParser for ViewportRuleParser<'a, 'b> { } } +/// A `@viewport` rule. #[derive(Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct ViewportRule { + /// The declarations contained in this @viewport rule. pub declarations: Vec } @@ -333,6 +342,7 @@ fn is_whitespace_separator_or_equals(c: &char) -> bool { } impl ViewportRule { + #[allow(missing_docs)] pub fn parse(input: &mut Parser, context: &ParserContext) -> Result { @@ -358,6 +368,7 @@ impl ViewportRule { Ok(ViewportRule { declarations: cascade.finish() }) } + #[allow(missing_docs)] pub fn from_meta(content: &str) -> Option { let mut declarations = vec![None; VIEWPORT_DESCRIPTOR_VARIANTS]; macro_rules! push_descriptor { @@ -531,11 +542,13 @@ impl ViewportDescriptorDeclaration { } } +#[allow(missing_docs)] pub struct Cascade { declarations: Vec>, count_so_far: usize, } +#[allow(missing_docs)] impl Cascade { pub fn new() -> Self { Cascade { From 5007e66043b2fbeffbd9da9c7880a93d599479e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 31 Dec 2016 03:38:23 +0100 Subject: [PATCH 10/19] style: Document the timer module. --- components/style/timer.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/components/style/timer.rs b/components/style/timer.rs index 619e93e80f1..b77563b5ffb 100644 --- a/components/style/timer.rs +++ b/components/style/timer.rs @@ -1,14 +1,19 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#![deny(missing_docs)] + +//! A timer module, used to define a `Timer` type, that is controlled by script. + use time; -/// The `TimerMode` is used to determine what time should the `Timer` return, -/// either a fixed value (in the `Test` mode), or the actual time (in the -/// `Current` mode). +/// The `TimerMode` is used to determine what time should the `Timer` return. #[derive(Debug, Clone)] enum TimerMode { + /// The timer should return a fixed value. Test(f64), + /// The timer should return the actual time. Current, } From d14290e3a5fea83be3e8a65a6625c184032b1362 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 31 Dec 2016 03:39:07 +0100 Subject: [PATCH 11/19] style: Document traversal.rs --- components/style/traversal.rs | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/components/style/traversal.rs b/components/style/traversal.rs index 1053db613c6..7ecc1170313 100644 --- a/components/style/traversal.rs +++ b/components/style/traversal.rs @@ -4,6 +4,8 @@ //! Traversing the DOM tree; the bloom filter. +#![deny(missing_docs)] + use atomic_refcell::{AtomicRefCell, AtomicRefMut}; use context::{SharedStyleContext, StyleContext}; use data::{ElementData, ElementStyles, StoredRestyleHint}; @@ -18,14 +20,23 @@ use std::mem; use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; use stylist::Stylist; -/// Style sharing candidate cache stats. These are only used when +/// Style sharing candidate cache hits. These are only used when /// `-Z style-sharing-stats` is given. pub static STYLE_SHARING_CACHE_HITS: AtomicUsize = ATOMIC_USIZE_INIT; + +/// Style sharing candidate cache misses. pub static STYLE_SHARING_CACHE_MISSES: AtomicUsize = ATOMIC_USIZE_INIT; -// NB: Keep this as small as possible, please! +/// A per-traversal-level chunk of data. This is sent down by the traversal, and +/// currently only holds the dom depth for the bloom filter. +/// +/// NB: Keep this as small as possible, please! #[derive(Clone, Debug)] pub struct PerLevelTraversalData { + /// The current dom depth, if known, or `None` otherwise. + /// + /// This is kept with cooperation from the traversal code and the bloom + /// filter. pub current_dom_depth: Option, } @@ -37,10 +48,12 @@ pub struct PreTraverseToken { } impl PreTraverseToken { + /// Whether we should traverse children. pub fn should_traverse(&self) -> bool { self.traverse } + /// Whether we should traverse only unstyled children. pub fn traverse_unstyled_children_only(&self) -> bool { self.unstyled_children_only } @@ -48,15 +61,22 @@ impl PreTraverseToken { /// Enum to prevent duplicate logging. pub enum LogBehavior { + /// We should log. MayLog, + /// We shouldn't log. DontLog, } use self::LogBehavior::*; impl LogBehavior { - fn allow(&self) -> bool { match *self { MayLog => true, DontLog => false, } } + fn allow(&self) -> bool { matches!(*self, MayLog) } } +/// A DOM Traversal trait, that is used to generically implement styling for +/// Gecko and Servo. pub trait DomTraversal : Sync { + /// The thread-local context, used to store non-thread-safe stuff that needs + /// to be used in the traversal, and of which we use one per worker, like + /// the bloom filter, for example. type ThreadLocalContext: Send; /// Process `node` on the way down, before its children have been processed. @@ -249,8 +269,10 @@ pub trait DomTraversal : Sync { /// children of |element|. unsafe fn clear_element_data(element: &N::ConcreteElement); + /// Return the shared style context common to all worker threads. fn shared_context(&self) -> &SharedStyleContext; + /// Create a thread-local context. fn create_thread_local_context(&self) -> Self::ThreadLocalContext; } @@ -529,6 +551,7 @@ fn preprocess_children(traversal: &D, } } +/// Clear style data for all the subtree under `el`. pub fn clear_descendant_data(el: E, clear_data: &F) { for kid in el.as_node().children() { if let Some(kid) = kid.as_element() { From 6dd9c9ecfa098fa6a04c0b000f42bc0ecb87a26d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 31 Dec 2016 03:39:44 +0100 Subject: [PATCH 12/19] style: Document stylesheets.rs --- components/style/stylesheets.rs | 69 +++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 8 deletions(-) diff --git a/components/style/stylesheets.rs b/components/style/stylesheets.rs index dcfa897bfde..f6ed4ec618e 100644 --- a/components/style/stylesheets.rs +++ b/components/style/stylesheets.rs @@ -4,6 +4,8 @@ //! Style sheets and their CSS rules. +#![deny(missing_docs)] + use {Atom, Prefix, Namespace}; use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, decode_stylesheet_bytes}; use cssparser::{AtRuleType, RuleListParser, SourcePosition, Token, parse_one_rule}; @@ -46,22 +48,27 @@ pub enum Origin { User, } +/// A set of namespaces applying to a given stylesheet. #[derive(Default, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub struct Namespaces { pub default: Option, pub prefixes: FnvHashMap, } +/// A list of CSS rules. #[derive(Debug)] pub struct CssRules(pub Vec); impl CssRules { + /// Whether this CSS rules is empty. pub fn is_empty(&self) -> bool { self.0.is_empty() } } +#[allow(missing_docs)] pub enum RulesMutateError { Syntax, IndexSize, @@ -79,6 +86,7 @@ impl From for RulesMutateError { } impl CssRules { + #[allow(missing_docs)] pub fn new(rules: Vec) -> Arc> { Arc::new(RwLock::new(CssRules(rules))) } @@ -93,7 +101,7 @@ impl CssRules { }) } - // https://drafts.csswg.org/cssom/#insert-a-css-rule + /// https://drafts.csswg.org/cssom/#insert-a-css-rule pub fn insert_rule(&mut self, rule: &str, parent_stylesheet: &Stylesheet, index: usize, nested: bool) -> Result { // Step 1, 2 @@ -136,7 +144,7 @@ impl CssRules { Ok(new_rule) } - // https://drafts.csswg.org/cssom/#remove-a-css-rule + /// https://drafts.csswg.org/cssom/#remove-a-css-rule pub fn remove_rule(&mut self, index: usize) -> Result<(), RulesMutateError> { // Step 1, 2 if index >= self.0.len() { @@ -161,6 +169,7 @@ impl CssRules { } } +/// The structure servo uses to represent a stylesheet. #[derive(Debug)] pub struct Stylesheet { /// List of rules in the order they were found (important for @@ -168,22 +177,33 @@ pub struct Stylesheet { pub rules: Arc>, /// List of media associated with the Stylesheet. pub media: Arc>, + /// The origin of this stylesheet. pub origin: Origin, + /// The base url this stylesheet should use. pub base_url: ServoUrl, + /// The namespaces that apply to this stylesheet. pub namespaces: RwLock, + /// Whether this stylesheet would be dirty when the viewport size changes. pub dirty_on_viewport_size_change: AtomicBool, + /// Whether this stylesheet should be disabled. pub disabled: AtomicBool, } /// This structure holds the user-agent and user stylesheets. pub struct UserAgentStylesheets { + /// The user or user agent stylesheets. pub user_or_user_agent_stylesheets: Vec, + /// The quirks mode stylesheet. pub quirks_mode_stylesheet: Stylesheet, } +/// A CSS rule. +/// +/// TODO(emilio): Lots of spec links should be around. #[derive(Debug, Clone)] +#[allow(missing_docs)] pub enum CssRule { // No Charset here, CSSCharsetRule has been removed from CSSOM // https://drafts.csswg.org/cssom/#changes-from-5-december-2013 @@ -197,6 +217,7 @@ pub enum CssRule { Keyframes(Arc>), } +#[allow(missing_docs)] pub enum CssRuleType { // https://drafts.csswg.org/cssom/#the-cssrule-interface Style = 1, @@ -236,12 +257,14 @@ impl ParseErrorReporter for MemoryHoleReporter { } } +#[allow(missing_docs)] pub enum SingleRuleParseError { Syntax, Hierarchy, } impl CssRule { + #[allow(missing_docs)] pub fn rule_type(&self) -> CssRuleType { match *self { CssRule::Style(_) => CssRuleType::Style, @@ -297,6 +320,7 @@ impl CssRule { // input state is None for a nested rule // Returns a parsed CSS rule and the final state of the parser + #[allow(missing_docs)] pub fn parse(css: &str, parent_stylesheet: &Stylesheet, extra_data: ParserContextExtraData, @@ -349,6 +373,7 @@ impl ToCss for CssRule { #[derive(Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub struct NamespaceRule { /// `None` for the default Namespace pub prefix: Option, @@ -375,6 +400,7 @@ impl ToCss for NamespaceRule { /// [import]: https://drafts.csswg.org/css-cascade-3/#at-import #[derive(Debug)] pub struct ImportRule { + /// The `` this `@import` rule is loading. pub url: SpecifiedUrl, /// The stylesheet is always present. @@ -397,9 +423,14 @@ impl ToCss for ImportRule { } } +/// A [`@keyframes`][keyframes] rule. +/// +/// [keyframes]: https://drafts.csswg.org/css-animations/#keyframes #[derive(Debug)] pub struct KeyframesRule { + /// The name of the current animation. pub name: Atom, + /// The keyframes specified for this CSS rule. pub keyframes: Vec>>, } @@ -418,6 +449,7 @@ impl ToCss for KeyframesRule { } } +#[allow(missing_docs)] #[derive(Debug)] pub struct MediaRule { pub media_queries: Arc>, @@ -439,6 +471,7 @@ impl ToCss for MediaRule { } } +#[allow(missing_docs)] #[derive(Debug)] pub struct StyleRule { pub selectors: SelectorList, @@ -466,6 +499,11 @@ impl ToCss for StyleRule { } impl Stylesheet { + /// Parse a stylesheet from a set of bytes, potentially received over the + /// network. + /// + /// Takes care of decoding the network bytes and forwards the resulting + /// string to `Stylesheet::from_str`. pub fn from_bytes(bytes: &[u8], base_url: ServoUrl, protocol_encoding_label: Option<&str>, @@ -487,6 +525,8 @@ impl Stylesheet { extra_data) } + /// Updates an empty stylesheet with a set of bytes that reached over the + /// network. pub fn update_from_bytes(existing: &Stylesheet, bytes: &[u8], protocol_encoding_label: Option<&str>, @@ -494,7 +534,6 @@ impl Stylesheet { stylesheet_loader: Option<&StylesheetLoader>, error_reporter: Box, extra_data: ParserContextExtraData) { - assert!(existing.rules.read().is_empty()); let (string, _) = decode_stylesheet_bytes( bytes, protocol_encoding_label, environment_encoding); Self::update_from_str(existing, @@ -504,6 +543,7 @@ impl Stylesheet { extra_data) } + /// Updates an empty stylesheet from a given string of text. pub fn update_from_str(existing: &Stylesheet, css: &str, stylesheet_loader: Option<&StylesheetLoader>, @@ -546,7 +586,14 @@ impl Stylesheet { .store(input.seen_viewport_percentages(), Ordering::Release); } - pub fn from_str(css: &str, base_url: ServoUrl, origin: Origin, + /// Creates an empty stylesheet and parses it with a given base url, origin + /// and media. + /// + /// Effectively creates a new stylesheet and forwards the hard work to + /// `Stylesheet::update_from_str`. + pub fn from_str(css: &str, + base_url: ServoUrl, + origin: Origin, media: MediaList, stylesheet_loader: Option<&StylesheetLoader>, error_reporter: Box, @@ -570,6 +617,7 @@ impl Stylesheet { s } + /// Whether this stylesheet can be dirty on viewport size change. pub fn dirty_on_viewport_size_change(&self) -> bool { self.dirty_on_viewport_size_change.load(Ordering::SeqCst) } @@ -608,16 +656,19 @@ impl Stylesheet { effective_rules(&self.rules.read().0, device, &mut f); } - /// Returns whether the stylesheet has been explicitly disabled through the CSSOM. + /// Returns whether the stylesheet has been explicitly disabled through the + /// CSSOM. pub fn disabled(&self) -> bool { self.disabled.load(Ordering::SeqCst) } - /// Records that the stylesheet has been explicitly disabled through the CSSOM. + /// Records that the stylesheet has been explicitly disabled through the + /// CSSOM. + /// /// Returns whether the the call resulted in a change in disabled state. /// - /// Disabled stylesheets remain in the document, but their rules are not added to - /// the Stylist. + /// Disabled stylesheets remain in the document, but their rules are not + /// added to the Stylist. pub fn set_disabled(&self, disabled: bool) -> bool { self.disabled.swap(disabled, Ordering::SeqCst) != disabled } @@ -641,6 +692,7 @@ macro_rules! rule_filter { ($( $method: ident($variant:ident => $rule_type: ident), )+) => { impl Stylesheet { $( + #[allow(missing_docs)] pub fn $method(&self, device: &Device, mut f: F) where F: FnMut(&$rule_type) { self.effective_rules(device, |rule| { if let CssRule::$variant(ref lock) = *rule { @@ -691,6 +743,7 @@ impl<'b> TopLevelRuleParser<'b> { } #[derive(Eq, PartialEq, Ord, PartialOrd, Copy, Clone)] +#[allow(missing_docs)] pub enum State { Start = 1, Imports = 2, From 40a6a1f97134d4705837dfde4b5c460eb380105c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 31 Dec 2016 03:41:39 +0100 Subject: [PATCH 13/19] style: Cleanup and document thread_state.rs --- components/style/thread_state.rs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/components/style/thread_state.rs b/components/style/thread_state.rs index 9f6dc5df8e8..c06a5833a7d 100644 --- a/components/style/thread_state.rs +++ b/components/style/thread_state.rs @@ -8,32 +8,42 @@ //! In release builds, `get` returns 0. All of the other functions inline //! away to nothing. +#![deny(missing_docs)] + pub use self::imp::{enter, exit, get, initialize}; bitflags! { + /// A thread state flag, used for multiple assertions. pub flags ThreadState: u32 { + /// Whether we're in a script thread. const SCRIPT = 0x01, + /// Whether we're in a layout thread. const LAYOUT = 0x02, - const PAINT = 0x04, + /// Whether we're in a script worker thread (actual web workers), or in + /// a layout worker thread. const IN_WORKER = 0x0100, + + /// Whether the current thread is going through a GC. const IN_GC = 0x0200, - const IN_HTML_PARSER = 0x0400, } } macro_rules! thread_types ( ( $( $fun:ident = $flag:ident ; )* ) => ( impl ThreadState { + /// Whether the current thread is a worker thread. pub fn is_worker(self) -> bool { self.contains(IN_WORKER) } $( #[cfg(debug_assertions)] + #[allow(missing_docs)] pub fn $fun(self) -> bool { self.contains($flag) } #[cfg(not(debug_assertions))] + #[allow(missing_docs)] pub fn $fun(self) -> bool { true } @@ -48,7 +58,6 @@ macro_rules! thread_types ( ( $( $fun:ident = $flag:ident ; )* ) => ( thread_types! { is_script = SCRIPT; is_layout = LAYOUT; - is_paint = PAINT; } #[cfg(debug_assertions)] @@ -58,6 +67,7 @@ mod imp { thread_local!(static STATE: RefCell> = RefCell::new(None)); + /// Initialize the current thread state. pub fn initialize(x: ThreadState) { STATE.with(|ref k| { if let Some(ref s) = *k.borrow() { @@ -68,6 +78,7 @@ mod imp { get(); // check the assertion below } + /// Get the current thread state. pub fn get() -> ThreadState { let state = STATE.with(|ref k| { match *k.borrow() { @@ -82,6 +93,7 @@ mod imp { state } + /// Enter into a given temporary state. Panics if re-entring. pub fn enter(x: ThreadState) { let state = get(); assert!(!state.intersects(x)); @@ -90,6 +102,7 @@ mod imp { }) } + /// Exit a given temporary state. pub fn exit(x: ThreadState) { let state = get(); assert!(state.contains(x)); @@ -100,6 +113,7 @@ mod imp { } #[cfg(not(debug_assertions))] +#[allow(missing_docs)] mod imp { use super::ThreadState; #[inline(always)] pub fn initialize(_: ThreadState) { } From 82b6825a868593e9a8f3f2f8ea501443ecbd8b46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 31 Dec 2016 03:54:53 +0100 Subject: [PATCH 14/19] style: Document style_traits and deny missing docs on it. --- components/style_traits/cursor.rs | 3 +++ components/style_traits/lib.rs | 2 +- components/style_traits/values.rs | 11 ++++++++++- components/style_traits/viewport.rs | 28 +++++++++++++++++++++++----- 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/components/style_traits/cursor.rs b/components/style_traits/cursor.rs index 8c1d35463f8..aefd562cc32 100644 --- a/components/style_traits/cursor.rs +++ b/components/style_traits/cursor.rs @@ -8,14 +8,17 @@ use super::ToCss; macro_rules! define_cursor { ($( $css: expr => $variant: ident = $value: expr, )+) => { + /// https://drafts.csswg.org/css-ui/#cursor #[derive(Clone, Copy, Debug, Eq, PartialEq)] #[cfg_attr(feature = "servo", derive(Deserialize, Serialize, HeapSizeOf))] #[repr(u8)] + #[allow(missing_docs)] pub enum Cursor { $( $variant = $value ),+ } impl Cursor { + /// Given a CSS keyword, get the corresponding cursor enum. pub fn from_css_keyword(keyword: &str) -> Result { match_ignore_ascii_case! { keyword, $( concat!($css) => Ok(Cursor::$variant), )+ diff --git a/components/style_traits/lib.rs b/components/style_traits/lib.rs index f75747c0f69..0a24b517138 100644 --- a/components/style_traits/lib.rs +++ b/components/style_traits/lib.rs @@ -9,7 +9,7 @@ #![crate_name = "style_traits"] #![crate_type = "rlib"] -#![deny(unsafe_code)] +#![deny(unsafe_code, missing_docs)] #![cfg_attr(feature = "servo", feature(plugin))] #![cfg_attr(feature = "servo", feature(proc_macro))] diff --git a/components/style_traits/values.rs b/components/style_traits/values.rs index f89f442df57..59be4900523 100644 --- a/components/style_traits/values.rs +++ b/components/style_traits/values.rs @@ -2,6 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +//! Helper types and traits for the handling of CSS values. + use app_units::Au; use std::fmt; @@ -78,13 +80,14 @@ macro_rules! __define_css_keyword_enum__add_optional_traits { #[macro_export] macro_rules! __define_css_keyword_enum__actual { ($name: ident [ $( $derived_trait: ident),* ] [ $( $css: expr => $variant: ident ),+ ]) => { - #[allow(non_camel_case_types)] + #[allow(non_camel_case_types, missing_docs)] #[derive(Clone, Eq, PartialEq, Copy, Hash, RustcEncodable, Debug $(, $derived_trait )* )] pub enum $name { $( $variant ),+ } impl $name { + /// Parse this property from a CSS input stream. pub fn parse(input: &mut ::cssparser::Parser) -> Result<$name, ()> { match_ignore_ascii_case! { try!(input.expect_ident()), $( $css => Ok($name::$variant), )+ @@ -105,18 +108,23 @@ macro_rules! __define_css_keyword_enum__actual { } } +/// Helper types for the handling of specified values. pub mod specified { use app_units::Au; + /// Whether to allow negative values or not. #[repr(u8)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum AllowedNumericType { + /// Allow all kind of numeric values. All, + /// Allow only non-negative values. NonNegative } impl AllowedNumericType { + /// Whether value is valid for this allowed numeric type. #[inline] pub fn is_ok(&self, value: f32) -> bool { match *self { @@ -125,6 +133,7 @@ pub mod specified { } } + /// Clamp the value following the rules of this numeric type. #[inline] pub fn clamp(&self, val: Au) -> Au { use std::cmp; diff --git a/components/style_traits/viewport.rs b/components/style_traits/viewport.rs index 22c21afcecc..42083546ac1 100644 --- a/components/style_traits/viewport.rs +++ b/components/style_traits/viewport.rs @@ -2,6 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +//! Helper types for the `@viewport` rule. + use {PagePx, ViewportPx}; use cssparser::{Parser, ToCss}; use euclid::scale_factor::ScaleFactor; @@ -20,16 +22,25 @@ define_css_keyword_enum!(Orientation: "landscape" => Landscape); +/// A set of viewport descriptors: +/// +/// https://drafts.csswg.org/css-device-adapt/#viewport-desc #[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(Deserialize, Serialize, HeapSizeOf))] pub struct ViewportConstraints { + /// Width and height: + /// * https://drafts.csswg.org/css-device-adapt/#width-desc + /// * https://drafts.csswg.org/css-device-adapt/#height-desc pub size: TypedSize2D, - + /// https://drafts.csswg.org/css-device-adapt/#zoom-desc pub initial_zoom: ScaleFactor, + /// https://drafts.csswg.org/css-device-adapt/#min-max-width-desc pub min_zoom: Option>, + /// https://drafts.csswg.org/css-device-adapt/#min-max-width-desc pub max_zoom: Option>, - + /// https://drafts.csswg.org/css-device-adapt/#user-zoom-desc pub user_zoom: UserZoom, + /// https://drafts.csswg.org/css-device-adapt/#orientation-desc pub orientation: Orientation } @@ -53,19 +64,21 @@ impl ToCss for ViewportConstraints { } } -/// Zoom is a number | percentage | auto -/// See http://dev.w3.org/csswg/css-device-adapt/#descdef-viewport-zoom +/// https://drafts.csswg.org/css-device-adapt/#descdef-viewport-zoom #[derive(Copy, Clone, Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum Zoom { + /// A number value. Number(f32), + /// A percentage value. Percentage(f32), + /// The `auto` keyword. Auto, } impl ToCss for Zoom { fn to_css(&self, dest: &mut W) -> fmt::Result - where W: fmt::Write + where W: fmt::Write, { match *self { Zoom::Number(number) => write!(dest, "{}", number), @@ -76,6 +89,9 @@ impl ToCss for Zoom { } impl Zoom { + /// Parse a zoom value per: + /// + /// https://drafts.csswg.org/css-device-adapt/#descdef-viewport-zoom pub fn parse(input: &mut Parser) -> Result { use cssparser::Token; @@ -90,6 +106,8 @@ impl Zoom { } } + /// Get this zoom value as a float value. Returns `None` if the value is the + /// `auto` keyword. #[inline] pub fn to_f32(&self) -> Option { match *self { From 14596609e3e684fb205266e4416b2088712e11bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 31 Dec 2016 04:08:30 +0100 Subject: [PATCH 15/19] style: Document Servo's SelectorImpl and deny missing docs. --- components/style/servo/selector_parser.rs | 31 +++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/components/style/servo/selector_parser.rs b/components/style/servo/selector_parser.rs index 2403e702063..9da80b05253 100644 --- a/components/style/servo/selector_parser.rs +++ b/components/style/servo/selector_parser.rs @@ -2,6 +2,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#![deny(missing_docs)] + +//! Servo's selector parser. + use {Atom, Prefix, Namespace, LocalName}; use attr::{AttrIdentifier, AttrValue}; use cssparser::ToCss; @@ -15,9 +19,12 @@ use std::borrow::Cow; use std::fmt; use std::fmt::Debug; +/// A pseudo-element, both public and private. +/// /// NB: If you add to this list, be sure to update `each_pseudo_element` too. #[derive(Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum PseudoElement { Before, After, @@ -55,6 +62,7 @@ impl ToCss for PseudoElement { impl PseudoElement { + /// Whether the current pseudo element is :before or :after. #[inline] pub fn is_before_or_after(&self) -> bool { match *self { @@ -64,6 +72,9 @@ impl PseudoElement { } } + /// Returns which kind of cascade type has this pseudo. + /// + /// For more info on cascade types, see docs/components/style.md #[inline] pub fn cascade_type(&self) -> PseudoElementCascadeType { match *self { @@ -83,8 +94,11 @@ impl PseudoElement { } } +/// A non tree-structural pseudo-class. +/// See https://drafts.csswg.org/selectors-4/#structural-pseudos #[derive(Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] pub enum NonTSPseudoClass { AnyLink, Link, @@ -129,6 +143,8 @@ impl ToCss for NonTSPseudoClass { } impl NonTSPseudoClass { + /// Gets a given state flag for this pseudo-class. This is used to do + /// selector matching, and it's set from the DOM. pub fn state_flag(&self) -> ElementState { use element_state::*; use self::NonTSPseudoClass::*; @@ -153,6 +169,8 @@ impl NonTSPseudoClass { } } +/// The abstract struct we implement the selector parser implementation on top +/// of. #[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SelectorImpl; @@ -289,14 +307,17 @@ impl<'a> ::selectors::Parser for SelectorParser<'a> { } impl SelectorImpl { + /// Returns the pseudo-element cascade type of the given `pseudo`. #[inline] pub fn pseudo_element_cascade_type(pseudo: &PseudoElement) -> PseudoElementCascadeType { pseudo.cascade_type() } + /// Executes `fun` for each pseudo-element. #[inline] pub fn each_pseudo_element(mut fun: F) - where F: FnMut(PseudoElement) { + where F: FnMut(PseudoElement), + { fun(PseudoElement::Before); fun(PseudoElement::After); fun(PseudoElement::DetailsContent); @@ -311,11 +332,13 @@ impl SelectorImpl { fun(PseudoElement::ServoAnonymousBlock); } + /// Returns the pseudo-class state flag for selector matching. #[inline] pub fn pseudo_class_state_flag(pc: &NonTSPseudoClass) -> ElementState { pc.state_flag() } + /// Returns whether this pseudo is either :before or :after. #[inline] pub fn pseudo_is_before_or_after(pseudo: &PseudoElement) -> bool { pseudo.is_before_or_after() @@ -326,12 +349,16 @@ impl SelectorImpl { #[derive(Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct ServoElementSnapshot { + /// The stored state of the element. pub state: Option, + /// The set of stored attributes and its values. pub attrs: Option>, + /// Whether this element is an HTML element in an HTML document. pub is_html_element_in_html_document: bool, } impl ServoElementSnapshot { + /// Create an empty element snapshot. pub fn new(is_html_element_in_html_document: bool) -> Self { ServoElementSnapshot { state: None, @@ -373,7 +400,7 @@ impl ElementSnapshot for ServoElementSnapshot { } fn each_class(&self, mut callback: F) - where F: FnMut(&Atom) + where F: FnMut(&Atom), { if let Some(v) = self.get_attr(&ns!(), &local_name!("class")) { for class in v.as_tokens() { From 84361d2f0f025776398f5ebd68c9117cf74fbd1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 31 Dec 2016 04:09:20 +0100 Subject: [PATCH 16/19] style: Do the proper thing for the sequential traversal. --- components/style/sequential.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/components/style/sequential.rs b/components/style/sequential.rs index b47d95a8517..68a57215612 100644 --- a/components/style/sequential.rs +++ b/components/style/sequential.rs @@ -4,14 +4,17 @@ //! Implements sequential traversal over the DOM tree. +#![deny(missing_docs)] + use dom::{TElement, TNode}; use traversal::{DomTraversal, PerLevelTraversalData, PreTraverseToken}; +/// Do a sequential DOM traversal for layout or styling, generic over `D`. pub fn traverse_dom(traversal: &D, root: N::ConcreteElement, token: PreTraverseToken) where N: TNode, - D: DomTraversal + D: DomTraversal, { debug_assert!(token.should_traverse()); From e03ef33f580c524c9074592cfdf683f013fd2c5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 31 Dec 2016 04:15:17 +0100 Subject: [PATCH 17/19] style: Document the parallel traversal. --- components/style/parallel.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/components/style/parallel.rs b/components/style/parallel.rs index badd0b9f40a..a05b8185b73 100644 --- a/components/style/parallel.rs +++ b/components/style/parallel.rs @@ -20,6 +20,8 @@ //! easy to grep for. At the time of this writing, there is no other unsafe //! code in the parallel traversal. +#![deny(missing_docs)] + use dom::{OpaqueNode, SendNode, TElement, TNode}; use rayon; use scoped_tls::ScopedTLS; @@ -28,8 +30,12 @@ use std::sync::atomic::Ordering; use traversal::{DomTraversal, PerLevelTraversalData, PreTraverseToken}; use traversal::{STYLE_SHARING_CACHE_HITS, STYLE_SHARING_CACHE_MISSES}; +/// The chunk size used to split the parallel traversal nodes. +/// +/// We send each `CHUNK_SIZE` nodes as a different work unit to the work queue. pub const CHUNK_SIZE: usize = 64; +/// A parallel top down traversal, generic over `D`. #[allow(unsafe_code)] pub fn traverse_dom(traversal: &D, root: N::ConcreteElement, @@ -37,7 +43,7 @@ pub fn traverse_dom(traversal: &D, token: PreTraverseToken, queue: &rayon::ThreadPool) where N: TNode, - D: DomTraversal + D: DomTraversal, { if opts::get().style_sharing_stats { STYLE_SHARING_CACHE_HITS.store(0, Ordering::SeqCst); @@ -181,7 +187,7 @@ fn bottom_up_dom(traversal: &D, root: OpaqueNode, mut node: N) where N: TNode, - D: DomTraversal + D: DomTraversal, { loop { // Perform the appropriate operation. From bc381ee945f96ee860dbf61eaed604a7e29ffd83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 31 Dec 2016 04:28:38 +0100 Subject: [PATCH 18/19] style: Fully document the dom module. --- components/style/dom.rs | 64 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/components/style/dom.rs b/components/style/dom.rs index 6f117259689..90eacdf22bd 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -5,6 +5,7 @@ //! Types and traits used to access the DOM from style calculation. #![allow(unsafe_code)] +#![deny(missing_docs)] use {Atom, Namespace, LocalName}; use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut}; @@ -48,15 +49,24 @@ impl OpaqueNode { /// We avoid exposing the full type id, since computing it in the general case /// would be difficult for Gecko nodes. pub trait NodeInfo { + /// Whether this node is an element. fn is_element(&self) -> bool; + /// Whether this node is a text node. fn is_text_node(&self) -> bool; - // Comments, doctypes, etc are ignored by layout algorithms. + /// Whether this node needs layout. + /// + /// Comments, doctypes, etc are ignored by layout algorithms. fn needs_layout(&self) -> bool { self.is_element() || self.is_text_node() } } +/// A node iterator that only returns node that don't need layout. pub struct LayoutIterator(pub T); -impl Iterator for LayoutIterator where T: Iterator, I: NodeInfo { + +impl Iterator for LayoutIterator + where T: Iterator, + I: NodeInfo, +{ type Item = I; fn next(&mut self) -> Option { loop { @@ -69,11 +79,22 @@ impl Iterator for LayoutIterator where T: Iterator, I: NodeInfo } } +/// The `TNode` trait. This is the main generic trait over which the style +/// system can be implemented. pub trait TNode : Sized + Copy + Clone + Debug + NodeInfo { + /// The concrete `TElement` type. type ConcreteElement: TElement; + + /// A concrete children iterator type in order to iterate over the `Node`s. + /// + /// TODO(emilio): We should eventually replace this with the `impl Trait` + /// syntax. type ConcreteChildrenIterator: Iterator; + /// Convert this node in an `UnsafeNode`. fn to_unsafe(&self) -> UnsafeNode; + + /// Get a node back from an `UnsafeNode`. unsafe fn from_unsafe(n: &UnsafeNode) -> Self; /// Returns an iterator over this node's children. @@ -82,24 +103,35 @@ pub trait TNode : Sized + Copy + Clone + Debug + NodeInfo { /// Converts self into an `OpaqueNode`. fn opaque(&self) -> OpaqueNode; + /// Get this node's parent element if present. fn parent_element(&self) -> Option { self.parent_node().and_then(|n| n.as_element()) } + /// A debug id, only useful, mm... for debugging. fn debug_id(self) -> usize; + /// Get this node as an element, if it's one. fn as_element(&self) -> Option; + /// Whether this node needs to be laid out on viewport size change. fn needs_dirty_on_viewport_size_changed(&self) -> bool; + /// Mark this node as needing layout on viewport size change. unsafe fn set_dirty_on_viewport_size_changed(&self); + /// Whether this node can be fragmented. This is used for multicol, and only + /// for Servo. fn can_be_fragmented(&self) -> bool; + /// Set whether this node can be fragmented. unsafe fn set_can_be_fragmented(&self, value: bool); + /// Get this node's parent node. fn parent_node(&self) -> Option; + /// Whether this node is in the document right now needed to clear the + /// restyle data appropriately on some forced restyles. fn is_in_doc(&self) -> bool; } @@ -187,14 +219,20 @@ fn fmt_subtree(f: &mut fmt::Formatter, stringify: &F, n: N, indent: Ok(()) } +/// A trait used to synthesize presentational hints for HTML element attributes. pub trait PresentationalHintsSynthetizer { + /// Generate the proper applicable declarations due to presentational hints, + /// and insert them into `hints`. fn synthesize_presentational_hints_for_legacy_attributes(&self, hints: &mut V) where V: Push; } +/// The element trait, the main abstraction the style crate acts over. pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + PresentationalHintsSynthetizer { + /// The concrete node type. type ConcreteNode: TNode; + /// Get this element as a node. fn as_node(&self) -> Self::ConcreteNode; /// While doing a reflow, the element at the root has no parent, as far as we're @@ -207,16 +245,25 @@ pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + Pre } } + /// Get this element's style attribute. fn style_attribute(&self) -> Option<&Arc>>; + /// Get this element's state, for non-tree-structural pseudos. fn get_state(&self) -> ElementState; + /// Whether this element has an attribute with a given namespace. fn has_attr(&self, namespace: &Namespace, attr: &LocalName) -> bool; + + /// Whether an attribute value equals `value`. fn attr_equals(&self, namespace: &Namespace, attr: &LocalName, value: &Atom) -> bool; - /// XXX: It's a bit unfortunate we need to pass the current computed values - /// as an argument here, but otherwise Servo would crash due to double - /// borrows to return it. + /// Get the pre-existing style to calculate restyle damage (change hints). + /// + /// This needs to be generic since it varies between Servo and Gecko. + /// + /// XXX(emilio): It's a bit unfortunate we need to pass the current computed + /// values as an argument here, but otherwise Servo would crash due to + /// double borrows to return it. fn existing_style_for_restyle_damage<'a>(&'a self, current_computed_values: Option<&'a Arc>, pseudo: Option<&PseudoElement>) @@ -270,11 +317,13 @@ pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + Pre /// about our parallel traversal. However, there are certain situations /// (including but not limited to the traversal) where we need to send DOM /// objects to other threads. - +/// +/// That's the reason why `SendNode` exists. #[derive(Clone, Debug, PartialEq)] pub struct SendNode(N); unsafe impl Send for SendNode {} impl SendNode { + /// Unsafely construct a SendNode. pub unsafe fn new(node: N) -> Self { SendNode(node) } @@ -286,10 +335,13 @@ impl Deref for SendNode { } } +/// Same reason as for the existence of SendNode, SendElement does the proper +/// things for a given `TElement`. #[derive(Debug, PartialEq)] pub struct SendElement(E); unsafe impl Send for SendElement {} impl SendElement { + /// Unsafely construct a SendElement. pub unsafe fn new(el: E) -> Self { SendElement(el) } From a847f26e84148fde3fb75537575f7efb768901ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 31 Dec 2016 04:47:33 +0100 Subject: [PATCH 19/19] style: Document the `data` module. --- components/style/data.rs | 73 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 66 insertions(+), 7 deletions(-) diff --git a/components/style/data.rs b/components/style/data.rs index 6aa68dc4ef2..e499c5262aa 100644 --- a/components/style/data.rs +++ b/components/style/data.rs @@ -4,6 +4,8 @@ //! Per-node data used in style calculation. +#![deny(missing_docs)] + use dom::TElement; use properties::ComputedValues; use properties::longhands::display::computed_value as display; @@ -19,6 +21,9 @@ use std::sync::Arc; use stylist::Stylist; use thread_state; +/// The structure that represents the result of style computation. This is +/// effectively a tuple of rules and computed values, that is, the rule node, +/// and the result of computing that rule node's rules, the `ComputedValues`. #[derive(Clone)] pub struct ComputedStyle { /// The rule node representing the ordered list of rules matched for this @@ -31,6 +36,7 @@ pub struct ComputedStyle { } impl ComputedStyle { + /// Trivially construct a new `ComputedStyle`. pub fn new(rules: StrongRuleNode, values: Arc) -> Self { ComputedStyle { rules: rules, @@ -49,10 +55,18 @@ impl fmt::Debug for ComputedStyle { type PseudoStylesInner = HashMap>; + +/// A set of styles for a given element's pseudo-elements. +/// +/// This is a map from pseudo-element to `ComputedStyle`. +/// +/// TODO(emilio): This should probably be a small array by default instead of a +/// full-blown `HashMap`. #[derive(Clone, Debug)] pub struct PseudoStyles(PseudoStylesInner); impl PseudoStyles { + /// Construct an empty set of `PseudoStyles`. pub fn empty() -> Self { PseudoStyles(HashMap::with_hasher(Default::default())) } @@ -71,11 +85,14 @@ impl DerefMut for PseudoStyles { /// pseudo-elements. #[derive(Clone, Debug)] pub struct ElementStyles { + /// The element's style. pub primary: ComputedStyle, + /// The map of styles for the element's pseudos. pub pseudos: PseudoStyles, } impl ElementStyles { + /// Trivially construct a new `ElementStyles`. pub fn new(primary: ComputedStyle) -> Self { ElementStyles { primary: primary, @@ -83,6 +100,7 @@ impl ElementStyles { } } + /// Whether this element `display` value is `none`. pub fn is_display_none(&self) -> bool { self.primary.values.get_box().clone_display() == display::T::none } @@ -127,7 +145,9 @@ impl DescendantRestyleHint { /// to provide more type safety while propagating restyle hints down the tree. #[derive(Clone, Debug)] pub struct StoredRestyleHint { + /// Whether this element should be restyled during the traversal. pub restyle_self: bool, + /// Whether the descendants of this element need to be restyled. pub descendants: DescendantRestyleHint, } @@ -140,6 +160,7 @@ impl StoredRestyleHint { } } + /// Creates an empty `StoredRestyleHint`. pub fn empty() -> Self { StoredRestyleHint { restyle_self: false, @@ -147,6 +168,8 @@ impl StoredRestyleHint { } } + /// Creates a restyle hint that forces the whole subtree to be restyled, + /// including the element. pub fn subtree() -> Self { StoredRestyleHint { restyle_self: true, @@ -154,10 +177,12 @@ impl StoredRestyleHint { } } + /// Whether the restyle hint is empty (nothing requires to be restyled). pub fn is_empty(&self) -> bool { !self.restyle_self && self.descendants == DescendantRestyleHint::Empty } + /// Insert another restyle hint, effectively resulting in the union of both. pub fn insert(&mut self, other: &Self) { self.restyle_self = self.restyle_self || other.restyle_self; self.descendants = self.descendants.union(other.descendants); @@ -185,11 +210,11 @@ impl From for StoredRestyleHint { } } -// We really want to store an Option here, but we can't drop Gecko -// Snapshots off-main-thread. So we make a convenient little wrapper to provide -// the semantics of Option, while deferring the actual drop. static NO_SNAPSHOT: Option = None; +/// We really want to store an Option here, but we can't drop Gecko +/// Snapshots off-main-thread. So we make a convenient little wrapper to provide +/// the semantics of Option, while deferring the actual drop. #[derive(Debug)] pub struct SnapshotOption { snapshot: Option, @@ -197,6 +222,7 @@ pub struct SnapshotOption { } impl SnapshotOption { + /// An empty snapshot. pub fn empty() -> Self { SnapshotOption { snapshot: None, @@ -204,11 +230,13 @@ impl SnapshotOption { } } + /// Destroy this snapshot. pub fn destroy(&mut self) { self.destroyed = true; debug_assert!(self.is_none()); } + /// Ensure a snapshot is available and return a mutable reference to it. pub fn ensure Snapshot>(&mut self, create: F) -> &mut Snapshot { debug_assert!(thread_state::get().is_layout()); if self.is_none() { @@ -234,7 +262,12 @@ impl Deref for SnapshotOption { /// Transient data used by the restyle algorithm. This structure is instantiated /// either before or during restyle traversal, and is cleared at the end of node /// processing. +/// +/// TODO(emilio): Tell bholley to document this more accurately. I can try (and +/// the fields are certainly mostly self-explanatory), but it's better if he +/// does, to avoid any misconception. #[derive(Debug)] +#[allow(missing_docs)] pub struct RestyleData { pub styles: ElementStyles, pub hint: StoredRestyleHint, @@ -254,8 +287,8 @@ impl RestyleData { } } - /// Expands the snapshot (if any) into a restyle hint. Returns true if later siblings - /// must be restyled. + /// Expands the snapshot (if any) into a restyle hint. Returns true if later + /// siblings must be restyled. pub fn expand_snapshot(&mut self, element: E, stylist: &Stylist) -> bool { if self.snapshot.is_none() { return false; @@ -281,14 +314,17 @@ impl RestyleData { later_siblings } + /// Return if the element style's are up to date. pub fn has_current_styles(&self) -> bool { !(self.hint.restyle_self || self.recascade || self.snapshot.is_some()) } + /// Returns the element styles. pub fn styles(&self) -> &ElementStyles { &self.styles } + /// Returns a mutable reference to the element styles. pub fn styles_mut(&mut self) -> &mut ElementStyles { &mut self.styles } @@ -317,12 +353,18 @@ impl RestyleData { /// safety. #[derive(Debug)] pub enum ElementData { + /// This is the first styling for this element. Initial(Option), + /// This element has been restyled already, and all the relevant data is + /// inside the `RestyleData`. Restyle(RestyleData), + /// This element has already been restyled, and only keeps its styles + /// around. Persistent(ElementStyles), } impl ElementData { + /// Trivially construct an ElementData. pub fn new(existing: Option) -> Self { if let Some(s) = existing { ElementData::Persistent(s) @@ -331,6 +373,7 @@ impl ElementData { } } + /// Return whether this data is from an initial restyle. pub fn is_initial(&self) -> bool { match *self { ElementData::Initial(_) => true, @@ -338,6 +381,7 @@ impl ElementData { } } + /// Return whether this data is from an element that hasn't been restyled. pub fn is_unstyled_initial(&self) -> bool { match *self { ElementData::Initial(None) => true, @@ -345,6 +389,8 @@ impl ElementData { } } + /// Return whether this data is from an element whose first restyle has just + /// been done. pub fn is_styled_initial(&self) -> bool { match *self { ElementData::Initial(Some(_)) => true, @@ -352,6 +398,8 @@ impl ElementData { } } + /// Returns true if this element is being restyled and has been styled + /// before. pub fn is_restyle(&self) -> bool { match *self { ElementData::Restyle(_) => true, @@ -359,6 +407,7 @@ impl ElementData { } } + /// Returns the `RestyleData` if it exists. pub fn as_restyle(&self) -> Option<&RestyleData> { match *self { ElementData::Restyle(ref x) => Some(x), @@ -366,6 +415,7 @@ impl ElementData { } } + /// Returns a mutable reference to the RestyleData, if it exists. pub fn as_restyle_mut(&mut self) -> Option<&mut RestyleData> { match *self { ElementData::Restyle(ref mut x) => Some(x), @@ -373,6 +423,7 @@ impl ElementData { } } + /// Returns whether this element's style is persistent. pub fn is_persistent(&self) -> bool { match *self { ElementData::Persistent(_) => true, @@ -428,6 +479,7 @@ impl ElementData { *self = ElementData::Persistent(styles); } + /// Return the restyle damage (if any). pub fn damage(&self) -> RestyleDamage { use self::ElementData::*; match *self { @@ -443,8 +495,8 @@ impl ElementData { } } - // A version of the above, with the assertions replaced with warnings to - // be more robust in corner-cases. This will go away soon. + /// A version of the above, with the assertions replaced with warnings to + /// be more robust in corner-cases. This will go away soon. #[cfg(feature = "gecko")] pub fn damage_sloppy(&self) -> RestyleDamage { use self::ElementData::*; @@ -476,6 +528,7 @@ impl ElementData { } } + /// Get the element styles, if any. pub fn get_styles(&self) -> Option<&ElementStyles> { use self::ElementData::*; match *self { @@ -485,10 +538,12 @@ impl ElementData { } } + /// Get the element styles. Panic if the element has never been styled. pub fn styles(&self) -> &ElementStyles { self.get_styles().expect("Calling styles() on unstyled ElementData") } + /// Get a mutable reference to the element styles, if any. pub fn get_styles_mut(&mut self) -> Option<&mut ElementStyles> { use self::ElementData::*; match *self { @@ -498,10 +553,14 @@ impl ElementData { } } + /// Get a mutable reference to the element styles. Panic if the element has + /// never been styled. pub fn styles_mut(&mut self) -> &mut ElementStyles { self.get_styles_mut().expect("Calling styles_mut() on unstyled ElementData") } + /// Finishes the styling of the element, effectively setting the style in + /// the data. pub fn finish_styling(&mut self, styles: ElementStyles, damage: RestyleDamage) { use self::ElementData::*; match *self {