style: Rustfmt declaration_block.rs.

Differential Revision: https://phabricator.services.mozilla.com/D43400
This commit is contained in:
Emilio Cobos Álvarez 2019-08-26 09:58:53 +00:00
parent ee106992e1
commit b0f3a68a6c

View file

@ -6,34 +6,36 @@
#![deny(missing_docs)] #![deny(missing_docs)]
use super::*;
use crate::context::QuirksMode; use crate::context::QuirksMode;
use cssparser::{DeclarationListParser, parse_important, ParserInput, CowRcStr}; use crate::custom_properties::{CssEnvironment, CustomPropertiesBuilder};
use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter, ParseErrorKind}; use crate::error_reporting::{ContextualParseError, ParseErrorReporter};
use crate::custom_properties::{CustomPropertiesBuilder, CssEnvironment};
use crate::error_reporting::{ParseErrorReporter, ContextualParseError};
use itertools::Itertools;
use crate::parser::ParserContext; use crate::parser::ParserContext;
use crate::properties::animated_properties::{AnimationValue, AnimationValueMap}; use crate::properties::animated_properties::{AnimationValue, AnimationValueMap};
use crate::selector_parser::SelectorImpl;
use crate::shared_lock::Locked; use crate::shared_lock::Locked;
use crate::str::{CssString, CssStringBorrow, CssStringWriter};
use crate::stylesheets::{CssRuleType, Origin, UrlExtraData};
use crate::values::computed::Context;
use cssparser::{parse_important, CowRcStr, DeclarationListParser, ParserInput};
use cssparser::{AtRuleParser, DeclarationParser, Delimiter, ParseErrorKind, Parser};
use itertools::Itertools;
use selectors::SelectorList;
use smallbitvec::{self, SmallBitVec}; use smallbitvec::{self, SmallBitVec};
use smallvec::SmallVec; use smallvec::SmallVec;
use std::fmt::{self, Write}; use std::fmt::{self, Write};
use std::iter::{DoubleEndedIterator, Zip}; use std::iter::{DoubleEndedIterator, Zip};
use std::slice::Iter; use std::slice::Iter;
use crate::str::{CssString, CssStringBorrow, CssStringWriter};
use style_traits::{CssWriter, ParseError, ParsingMode, StyleParseErrorKind, ToCss}; use style_traits::{CssWriter, ParseError, ParsingMode, StyleParseErrorKind, ToCss};
use crate::stylesheets::{CssRuleType, Origin, UrlExtraData};
use super::*;
use crate::values::computed::Context;
use crate::selector_parser::SelectorImpl;
use selectors::SelectorList;
/// The animation rules. /// The animation rules.
/// ///
/// The first one is for Animation cascade level, and the second one is for /// The first one is for Animation cascade level, and the second one is for
/// Transition cascade level. /// Transition cascade level.
pub struct AnimationRules(pub Option<Arc<Locked<PropertyDeclarationBlock>>>, pub struct AnimationRules(
pub Option<Arc<Locked<PropertyDeclarationBlock>>>); pub Option<Arc<Locked<PropertyDeclarationBlock>>>,
pub Option<Arc<Locked<PropertyDeclarationBlock>>>,
);
impl AnimationRules { impl AnimationRules {
/// Returns whether these animation rules represents an actual rule or not. /// Returns whether these animation rules represents an actual rule or not.
@ -122,8 +124,16 @@ impl<'a> Iterator for DeclarationImportanceIterator<'a> {
#[inline] #[inline]
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(decl, important)| self.iter.next().map(|(decl, important)| {
(decl, if important { Importance::Important } else { Importance::Normal })) (
decl,
if important {
Importance::Important
} else {
Importance::Normal
},
)
})
} }
#[inline] #[inline]
@ -135,13 +145,21 @@ impl<'a> Iterator for DeclarationImportanceIterator<'a> {
impl<'a> DoubleEndedIterator for DeclarationImportanceIterator<'a> { impl<'a> DoubleEndedIterator for DeclarationImportanceIterator<'a> {
#[inline(always)] #[inline(always)]
fn next_back(&mut self) -> Option<Self::Item> { fn next_back(&mut self) -> Option<Self::Item> {
self.iter.next_back().map(|(decl, important)| self.iter.next_back().map(|(decl, important)| {
(decl, if important { Importance::Important } else { Importance::Normal })) (
decl,
if important {
Importance::Important
} else {
Importance::Normal
},
)
})
} }
} }
/// Iterator for AnimationValue to be generated from PropertyDeclarationBlock. /// Iterator for AnimationValue to be generated from PropertyDeclarationBlock.
pub struct AnimationValueIterator<'a, 'cx, 'cx_a:'cx> { pub struct AnimationValueIterator<'a, 'cx, 'cx_a: 'cx> {
iter: DeclarationImportanceIterator<'a>, iter: DeclarationImportanceIterator<'a>,
context: &'cx mut Context<'cx_a>, context: &'cx mut Context<'cx_a>,
default_values: &'a ComputedValues, default_values: &'a ComputedValues,
@ -149,7 +167,7 @@ pub struct AnimationValueIterator<'a, 'cx, 'cx_a:'cx> {
extra_custom_properties: Option<&'a Arc<crate::custom_properties::CustomPropertiesMap>>, extra_custom_properties: Option<&'a Arc<crate::custom_properties::CustomPropertiesMap>>,
} }
impl<'a, 'cx, 'cx_a:'cx> AnimationValueIterator<'a, 'cx, 'cx_a> { impl<'a, 'cx, 'cx_a: 'cx> AnimationValueIterator<'a, 'cx, 'cx_a> {
fn new( fn new(
declarations: &'a PropertyDeclarationBlock, declarations: &'a PropertyDeclarationBlock,
context: &'cx mut Context<'cx_a>, context: &'cx mut Context<'cx_a>,
@ -165,7 +183,7 @@ impl<'a, 'cx, 'cx_a:'cx> AnimationValueIterator<'a, 'cx, 'cx_a> {
} }
} }
impl<'a, 'cx, 'cx_a:'cx> Iterator for AnimationValueIterator<'a, 'cx, 'cx_a> { impl<'a, 'cx, 'cx_a: 'cx> Iterator for AnimationValueIterator<'a, 'cx, 'cx_a> {
type Item = AnimationValue; type Item = AnimationValue;
#[inline] #[inline]
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
@ -256,7 +274,7 @@ impl PropertyDeclarationBlock {
/// Return an iterator of (AnimatableLonghand, AnimationValue). /// Return an iterator of (AnimatableLonghand, AnimationValue).
#[inline] #[inline]
pub fn to_animation_value_iter<'a, 'cx, 'cx_a:'cx>( pub fn to_animation_value_iter<'a, 'cx, 'cx_a: 'cx>(
&'a self, &'a self,
context: &'cx mut Context<'cx_a>, context: &'cx mut Context<'cx_a>,
default_values: &'a ComputedValues, default_values: &'a ComputedValues,
@ -300,7 +318,10 @@ impl PropertyDeclarationBlock {
/// NOTE: This is linear time in the case of custom properties or in the /// NOTE: This is linear time in the case of custom properties or in the
/// case the longhand is actually in the declaration block. /// case the longhand is actually in the declaration block.
#[inline] #[inline]
pub fn get(&self, property: PropertyDeclarationId) -> Option<(&PropertyDeclaration, Importance)> { pub fn get(
&self,
property: PropertyDeclarationId,
) -> Option<(&PropertyDeclaration, Importance)> {
if let PropertyDeclarationId::Longhand(id) = property { if let PropertyDeclarationId::Longhand(id) = property {
if !self.contains(id) { if !self.contains(id) {
return None; return None;
@ -350,9 +371,7 @@ impl PropertyDeclarationBlock {
// We don't print !important when serializing individual properties, // We don't print !important when serializing individual properties,
// so we treat this as a normal-importance property // so we treat this as a normal-importance property
match shorthand.get_shorthand_appendable_value(list.iter().cloned()) { match shorthand.get_shorthand_appendable_value(list.iter().cloned()) {
Some(appendable_value) => { Some(appendable_value) => append_declaration_value(dest, appendable_value),
append_declaration_value(dest, appendable_value)
}
None => return Ok(()), None => return Ok(()),
} }
} }
@ -360,7 +379,11 @@ impl PropertyDeclarationBlock {
/// Find the value of the given property in this block and serialize it /// Find the value of the given property in this block and serialize it
/// ///
/// <https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-getpropertyvalue> /// <https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-getpropertyvalue>
pub fn property_value_to_css(&self, property: &PropertyId, dest: &mut CssStringWriter) -> fmt::Result { pub fn property_value_to_css(
&self,
property: &PropertyId,
dest: &mut CssStringWriter,
) -> fmt::Result {
// Step 1.1: done when parsing a string to PropertyId // Step 1.1: done when parsing a string to PropertyId
// Step 1.2 // Step 1.2
@ -394,11 +417,12 @@ impl PropertyDeclarationBlock {
} else { } else {
Importance::Normal Importance::Normal
} }
} },
Err(longhand_or_custom) => { Err(longhand_or_custom) => {
// Step 3 // Step 3
self.get(longhand_or_custom).map_or(Importance::Normal, |(_, importance)| importance) self.get(longhand_or_custom)
} .map_or(Importance::Normal, |(_, importance)| importance)
},
} }
} }
@ -407,7 +431,9 @@ impl PropertyDeclarationBlock {
/// and it doesn't exist in the block, and returns false otherwise. /// and it doesn't exist in the block, and returns false otherwise.
#[inline] #[inline]
fn is_definitely_new(&self, decl: &PropertyDeclaration) -> bool { fn is_definitely_new(&self, decl: &PropertyDeclaration) -> bool {
decl.id().as_longhand().map_or(false, |id| !self.longhands.contains(id)) decl.id()
.as_longhand()
.map_or(false, |id| !self.longhands.contains(id))
} }
/// Adds or overrides the declaration for a given property in this block. /// Adds or overrides the declaration for a given property in this block.
@ -421,11 +447,11 @@ impl PropertyDeclarationBlock {
) -> bool { ) -> bool {
let all_shorthand_len = match drain.all_shorthand { let all_shorthand_len = match drain.all_shorthand {
AllShorthand::NotSet => 0, AllShorthand::NotSet => 0,
AllShorthand::CSSWideKeyword(_) | AllShorthand::CSSWideKeyword(_) | AllShorthand::WithVariables(_) => {
AllShorthand::WithVariables(_) => shorthands::ALL_SHORTHAND_MAX_LEN, shorthands::ALL_SHORTHAND_MAX_LEN
},
}; };
let push_calls_count = let push_calls_count = drain.declarations.len() + all_shorthand_len;
drain.declarations.len() + all_shorthand_len;
// With deduplication the actual length increase may be less than this. // With deduplication the actual length increase may be less than this.
self.declarations.reserve(push_calls_count); self.declarations.reserve(push_calls_count);
@ -434,7 +460,10 @@ impl PropertyDeclarationBlock {
for decl in &mut drain.declarations { for decl in &mut drain.declarations {
changed |= self.push(decl, importance); changed |= self.push(decl, importance);
} }
drain.all_shorthand.declarations().fold(changed, |changed, decl| { drain
.all_shorthand
.declarations()
.fold(changed, |changed, decl| {
changed | self.push(decl, importance) changed | self.push(decl, importance)
}) })
} }
@ -444,11 +473,7 @@ impl PropertyDeclarationBlock {
/// Returns whether the declaration has changed. /// Returns whether the declaration has changed.
/// ///
/// This is only used for parsing and internal use. /// This is only used for parsing and internal use.
pub fn push( pub fn push(&mut self, declaration: PropertyDeclaration, importance: Importance) -> bool {
&mut self,
declaration: PropertyDeclaration,
importance: Importance,
) -> bool {
if !self.is_definitely_new(&declaration) { if !self.is_definitely_new(&declaration) {
let mut index_to_remove = None; let mut index_to_remove = None;
for (i, slot) in self.declarations.iter_mut().enumerate() { for (i, slot) in self.declarations.iter_mut().enumerate() {
@ -498,9 +523,14 @@ impl PropertyDeclarationBlock {
// Check whether we are updating for an all shorthand change. // Check whether we are updating for an all shorthand change.
if !matches!(source_declarations.all_shorthand, AllShorthand::NotSet) { if !matches!(source_declarations.all_shorthand, AllShorthand::NotSet) {
debug_assert!(source_declarations.declarations.is_empty()); debug_assert!(source_declarations.declarations.is_empty());
return source_declarations.all_shorthand.declarations().any(|decl| { return source_declarations
.all_shorthand
.declarations()
.any(|decl| {
self.is_definitely_new(&decl) || self.is_definitely_new(&decl) ||
self.declarations.iter().enumerate() self.declarations
.iter()
.enumerate()
.find(|&(_, ref d)| d.id() == decl.id()) .find(|&(_, ref d)| d.id() == decl.id())
.map_or(true, |(i, d)| { .map_or(true, |(i, d)| {
let important = self.declarations_importance[i]; let important = self.declarations_importance[i];
@ -513,7 +543,11 @@ impl PropertyDeclarationBlock {
let new_count = &mut updates.new_count; let new_count = &mut updates.new_count;
let any_removal = &mut updates.any_removal; let any_removal = &mut updates.any_removal;
let updates = &mut updates.updates; let updates = &mut updates.updates;
updates.extend(source_declarations.declarations.iter().map(|declaration| { updates.extend(
source_declarations
.declarations
.iter()
.map(|declaration| {
if self.is_definitely_new(declaration) { if self.is_definitely_new(declaration) {
return DeclarationUpdate::Append; return DeclarationUpdate::Append;
} }
@ -538,14 +572,17 @@ impl PropertyDeclarationBlock {
} }
if !needs_append && if !needs_append &&
id.logical_group() == Some(logical_group) && id.logical_group() == Some(logical_group) &&
id.is_logical() != longhand_id.is_logical() { id.is_logical() != longhand_id.is_logical()
{
needs_append = true; needs_append = true;
} }
} }
unreachable!("Longhand should be found in loop above"); unreachable!("Longhand should be found in loop above");
} }
} }
self.declarations.iter().enumerate() self.declarations
.iter()
.enumerate()
.find(|&(_, ref decl)| decl.id() == declaration.id()) .find(|&(_, ref decl)| decl.id() == declaration.id())
.map_or(DeclarationUpdate::Append, |(pos, decl)| { .map_or(DeclarationUpdate::Append, |(pos, decl)| {
let important = self.declarations_importance[pos]; let important = self.declarations_importance[pos];
@ -555,7 +592,8 @@ impl PropertyDeclarationBlock {
DeclarationUpdate::UpdateInPlace { pos } DeclarationUpdate::UpdateInPlace { pos }
} }
}) })
}).inspect(|update| { })
.inspect(|update| {
if matches!(update, DeclarationUpdate::None) { if matches!(update, DeclarationUpdate::None) {
return; return;
} }
@ -563,13 +601,14 @@ impl PropertyDeclarationBlock {
match update { match update {
DeclarationUpdate::Append => { DeclarationUpdate::Append => {
*new_count += 1; *new_count += 1;
} },
DeclarationUpdate::AppendAndRemove { .. } => { DeclarationUpdate::AppendAndRemove { .. } => {
*any_removal = true; *any_removal = true;
},
_ => {},
} }
_ => {} }),
} );
}));
any_update any_update
} }
@ -590,8 +629,12 @@ impl PropertyDeclarationBlock {
self.declarations_importance.push(important); self.declarations_importance.push(important);
self.longhands.insert(longhand_id); self.longhands.insert(longhand_id);
} else { } else {
let (idx, slot) = self.declarations.iter_mut() let (idx, slot) = self
.enumerate().find(|&(_, ref d)| d.id() == decl.id()).unwrap(); .declarations
.iter_mut()
.enumerate()
.find(|&(_, ref d)| d.id() == decl.id())
.unwrap();
*slot = decl; *slot = decl;
self.declarations_importance.set(idx, important); self.declarations_importance.set(idx, important);
} }
@ -607,19 +650,24 @@ impl PropertyDeclarationBlock {
pos: usize, pos: usize,
remove: bool, remove: bool,
} }
let mut updates_and_removals: SubpropertiesVec<UpdateOrRemoval> = let mut updates_and_removals: SubpropertiesVec<UpdateOrRemoval> = updates
updates.updates.iter_mut().filter_map(|item| { .updates
.iter_mut()
.filter_map(|item| {
let (pos, remove) = match *item { let (pos, remove) = match *item {
DeclarationUpdate::UpdateInPlace { pos } => (pos, false), DeclarationUpdate::UpdateInPlace { pos } => (pos, false),
DeclarationUpdate::AppendAndRemove { pos } => (pos, true), DeclarationUpdate::AppendAndRemove { pos } => (pos, true),
_ => return None, _ => return None,
}; };
Some(UpdateOrRemoval { item, pos, remove }) Some(UpdateOrRemoval { item, pos, remove })
}).collect(); })
.collect();
// Execute removals. It's important to do it in reverse index order, // Execute removals. It's important to do it in reverse index order,
// so that removing doesn't invalidate following positions. // so that removing doesn't invalidate following positions.
updates_and_removals.sort_unstable_by_key(|update| update.pos); updates_and_removals.sort_unstable_by_key(|update| update.pos);
updates_and_removals.iter().rev() updates_and_removals
.iter()
.rev()
.filter(|update| update.remove) .filter(|update| update.remove)
.for_each(|update| { .for_each(|update| {
self.declarations.remove(update.pos); self.declarations.remove(update.pos);
@ -637,7 +685,7 @@ impl PropertyDeclarationBlock {
DeclarationUpdate::UpdateInPlace { pos: update.pos } DeclarationUpdate::UpdateInPlace { pos: update.pos }
); );
*update.item = DeclarationUpdate::UpdateInPlace { *update.item = DeclarationUpdate::UpdateInPlace {
pos: update.pos - removed_count pos: update.pos - removed_count,
}; };
} }
} }
@ -645,18 +693,17 @@ impl PropertyDeclarationBlock {
for (decl, update) in drain.declarations.zip_eq(updates.updates.iter()) { for (decl, update) in drain.declarations.zip_eq(updates.updates.iter()) {
match *update { match *update {
DeclarationUpdate::None => {}, DeclarationUpdate::None => {},
DeclarationUpdate::Append | DeclarationUpdate::Append | DeclarationUpdate::AppendAndRemove { .. } => {
DeclarationUpdate::AppendAndRemove { .. } => {
if let Some(id) = decl.id().as_longhand() { if let Some(id) = decl.id().as_longhand() {
self.longhands.insert(id); self.longhands.insert(id);
} }
self.declarations.push(decl); self.declarations.push(decl);
self.declarations_importance.push(important); self.declarations_importance.push(important);
} },
DeclarationUpdate::UpdateInPlace { pos } => { DeclarationUpdate::UpdateInPlace { pos } => {
self.declarations[pos] = decl; self.declarations[pos] = decl;
self.declarations_importance.set(pos, important); self.declarations_importance.set(pos, important);
} },
} }
} }
updates.updates.clear(); updates.updates.clear();
@ -665,19 +712,16 @@ impl PropertyDeclarationBlock {
/// Returns the first declaration that would be removed by removing /// Returns the first declaration that would be removed by removing
/// `property`. /// `property`.
#[inline] #[inline]
pub fn first_declaration_to_remove( pub fn first_declaration_to_remove(&self, property: &PropertyId) -> Option<usize> {
&self,
property: &PropertyId,
) -> Option<usize> {
if let Some(id) = property.longhand_id() { if let Some(id) = property.longhand_id() {
if !self.longhands.contains(id) { if !self.longhands.contains(id) {
return None; return None;
} }
} }
self.declarations.iter().position(|declaration| { self.declarations
declaration.id().is_or_is_longhand_of(property) .iter()
}) .position(|declaration| declaration.id().is_or_is_longhand_of(property))
} }
/// Removes a given declaration at a given index. /// Removes a given declaration at a given index.
@ -698,16 +742,14 @@ impl PropertyDeclarationBlock {
/// `first_declaration` needs to be the result of /// `first_declaration` needs to be the result of
/// `first_declaration_to_remove`. /// `first_declaration_to_remove`.
#[inline] #[inline]
pub fn remove_property( pub fn remove_property(&mut self, property: &PropertyId, first_declaration: usize) {
&mut self,
property: &PropertyId,
first_declaration: usize,
) {
debug_assert_eq!( debug_assert_eq!(
Some(first_declaration), Some(first_declaration),
self.first_declaration_to_remove(property) self.first_declaration_to_remove(property)
); );
debug_assert!(self.declarations[first_declaration].id().is_or_is_longhand_of(property)); debug_assert!(self.declarations[first_declaration]
.id()
.is_or_is_longhand_of(property));
self.remove_declaration_at(first_declaration); self.remove_declaration_at(first_declaration);
@ -776,16 +818,16 @@ impl PropertyDeclarationBlock {
// getKeyframes() implementation for CSS animations, if // getKeyframes() implementation for CSS animations, if
// |computed_values| is supplied, we use it to expand such variable // |computed_values| is supplied, we use it to expand such variable
// declarations. This will be fixed properly in Gecko bug 1391537. // declarations. This will be fixed properly in Gecko bug 1391537.
( (&PropertyDeclaration::WithVariables(ref declaration), Some(ref _computed_values)) => {
&PropertyDeclaration::WithVariables(ref declaration), declaration
Some(ref _computed_values), .value
) => { .substitute_variables(
declaration.value.substitute_variables(
declaration.id, declaration.id,
custom_properties.as_ref(), custom_properties.as_ref(),
QuirksMode::NoQuirks, QuirksMode::NoQuirks,
&env, &env,
).to_css(dest) )
.to_css(dest)
}, },
(ref d, _) => d.to_css(dest), (ref d, _) => d.to_css(dest),
} }
@ -814,13 +856,12 @@ impl PropertyDeclarationBlock {
pub fn has_css_wide_keyword(&self, property: &PropertyId) -> bool { pub fn has_css_wide_keyword(&self, property: &PropertyId) -> bool {
if let Some(id) = property.longhand_id() { if let Some(id) = property.longhand_id() {
if !self.longhands.contains(id) { if !self.longhands.contains(id) {
return false return false;
} }
} }
self.declarations.iter().any(|decl| self.declarations.iter().any(|decl| {
decl.id().is_or_is_longhand_of(property) && decl.id().is_or_is_longhand_of(property) && decl.get_css_wide_keyword().is_some()
decl.get_css_wide_keyword().is_some() })
)
} }
/// Returns a custom properties map which is the result of cascading custom /// Returns a custom properties map which is the result of cascading custom
@ -844,10 +885,7 @@ impl PropertyDeclarationBlock {
inherited_custom_properties: Option<&Arc<crate::custom_properties::CustomPropertiesMap>>, inherited_custom_properties: Option<&Arc<crate::custom_properties::CustomPropertiesMap>>,
environment: &CssEnvironment, environment: &CssEnvironment,
) -> Option<Arc<crate::custom_properties::CustomPropertiesMap>> { ) -> Option<Arc<crate::custom_properties::CustomPropertiesMap>> {
let mut builder = CustomPropertiesBuilder::new( let mut builder = CustomPropertiesBuilder::new(inherited_custom_properties, environment);
inherited_custom_properties,
environment,
);
for declaration in self.normal_declaration_iter() { for declaration in self.normal_declaration_iter() {
if let PropertyDeclaration::Custom(ref declaration) = *declaration { if let PropertyDeclaration::Custom(ref declaration) = *declaration {
@ -899,7 +937,7 @@ impl PropertyDeclarationBlock {
&mut is_first_serialization, &mut is_first_serialization,
)?; )?;
continue; continue;
} },
}; };
// Step 3.2 // Step 3.2
@ -928,22 +966,19 @@ impl PropertyDeclarationBlock {
let mut important_count = 0; let mut important_count = 0;
let mut found_system = None; let mut found_system = None;
let is_system_font = let is_system_font = shorthand == ShorthandId::Font &&
shorthand == ShorthandId::Font && self.declarations.iter().any(|l| match l.id() {
self.declarations.iter().any(|l| {
match l.id() {
PropertyDeclarationId::Longhand(id) => { PropertyDeclarationId::Longhand(id) => {
if already_serialized.contains(id.into()) { if already_serialized.contains(id.into()) {
return false; return false;
} }
l.get_system().is_some() l.get_system().is_some()
} },
PropertyDeclarationId::Custom(..) => { PropertyDeclarationId::Custom(..) => {
debug_assert!(l.get_system().is_none()); debug_assert!(l.get_system().is_none());
false false
} },
}
}); });
if is_system_font { if is_system_font {
@ -967,11 +1002,11 @@ impl PropertyDeclarationBlock {
if importance.important() { if importance.important() {
important_count += 1; important_count += 1;
} }
} },
None => { None => {
contains_all_longhands = false; contains_all_longhands = false;
break; break;
} },
} }
} }
@ -994,8 +1029,9 @@ impl PropertyDeclarationBlock {
// Substep 5 - Let value be the result of invoking serialize // Substep 5 - Let value be the result of invoking serialize
// a CSS value of current longhands. // a CSS value of current longhands.
let appendable_value = let appendable_value = match shorthand
match shorthand.get_shorthand_appendable_value(current_longhands.iter().cloned()) { .get_shorthand_appendable_value(current_longhands.iter().cloned())
{
None => continue, None => continue,
Some(appendable_value) => appendable_value, Some(appendable_value) => appendable_value,
}; };
@ -1004,13 +1040,19 @@ impl PropertyDeclarationBlock {
// AppendableValue::Css. // AppendableValue::Css.
let mut v = CssString::new(); let mut v = CssString::new();
let value = match (appendable_value, found_system) { let value = match (appendable_value, found_system) {
(AppendableValue::Css { css, with_variables }, _) => { (
AppendableValue::Css {
css,
with_variables,
},
_,
) => {
debug_assert!(!css.is_empty()); debug_assert!(!css.is_empty());
AppendableValue::Css { AppendableValue::Css {
css: css, css: css,
with_variables: with_variables, with_variables: with_variables,
} }
} },
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
(_, Some(sys)) => { (_, Some(sys)) => {
sys.to_css(&mut CssWriter::new(&mut v))?; sys.to_css(&mut CssWriter::new(&mut v))?;
@ -1018,7 +1060,7 @@ impl PropertyDeclarationBlock {
css: CssStringBorrow::from(&v), css: CssStringBorrow::from(&v),
with_variables: false, with_variables: false,
} }
} },
(other, _) => { (other, _) => {
append_declaration_value(&mut v, other)?; append_declaration_value(&mut v, other)?;
@ -1031,7 +1073,7 @@ impl PropertyDeclarationBlock {
css: CssStringBorrow::from(&v), css: CssStringBorrow::from(&v),
with_variables: false, with_variables: false,
} }
} },
}; };
// Substeps 7 and 8 // Substeps 7 and 8
@ -1091,7 +1133,8 @@ impl PropertyDeclarationBlock {
/// A convenient enum to represent different kinds of stuff that can represent a /// A convenient enum to represent different kinds of stuff that can represent a
/// _value_ in the serialization of a property declaration. /// _value_ in the serialization of a property declaration.
pub enum AppendableValue<'a, I> pub enum AppendableValue<'a, I>
where I: Iterator<Item=&'a PropertyDeclaration>, where
I: Iterator<Item = &'a PropertyDeclaration>,
{ {
/// A given declaration, of which we'll serialize just the value. /// A given declaration, of which we'll serialize just the value.
Declaration(&'a PropertyDeclaration), Declaration(&'a PropertyDeclaration),
@ -1107,14 +1150,11 @@ pub enum AppendableValue<'a, I>
css: CssStringBorrow<'a>, css: CssStringBorrow<'a>,
/// Whether the original serialization contained variables or not. /// Whether the original serialization contained variables or not.
with_variables: bool, with_variables: bool,
} },
} }
/// Potentially appends whitespace after the first (property: value;) pair. /// Potentially appends whitespace after the first (property: value;) pair.
fn handle_first_serialization<W>( fn handle_first_serialization<W>(dest: &mut W, is_first_serialization: &mut bool) -> fmt::Result
dest: &mut W,
is_first_serialization: &mut bool,
) -> fmt::Result
where where
W: Write, W: Write,
{ {
@ -1132,18 +1172,14 @@ pub fn append_declaration_value<'a, I>(
appendable_value: AppendableValue<'a, I>, appendable_value: AppendableValue<'a, I>,
) -> fmt::Result ) -> fmt::Result
where where
I: Iterator<Item=&'a PropertyDeclaration>, I: Iterator<Item = &'a PropertyDeclaration>,
{ {
match appendable_value { match appendable_value {
AppendableValue::Css { css, .. } => { AppendableValue::Css { css, .. } => css.append_to(dest),
css.append_to(dest) AppendableValue::Declaration(decl) => decl.to_css(dest),
},
AppendableValue::Declaration(decl) => {
decl.to_css(dest)
},
AppendableValue::DeclarationsForShorthand(shorthand, decls) => { AppendableValue::DeclarationsForShorthand(shorthand, decls) => {
shorthand.longhands_to_css(decls, &mut CssWriter::new(dest)) shorthand.longhands_to_css(decls, &mut CssWriter::new(dest))
} },
} }
} }
@ -1153,10 +1189,10 @@ pub fn append_serialization<'a, I, N>(
property_name: &N, property_name: &N,
appendable_value: AppendableValue<'a, I>, appendable_value: AppendableValue<'a, I>,
importance: Importance, importance: Importance,
is_first_serialization: &mut bool is_first_serialization: &mut bool,
) -> fmt::Result ) -> fmt::Result
where where
I: Iterator<Item=&'a PropertyDeclaration>, I: Iterator<Item = &'a PropertyDeclaration>,
N: ToCss, N: ToCss,
{ {
handle_first_serialization(dest, is_first_serialization)?; handle_first_serialization(dest, is_first_serialization)?;
@ -1176,7 +1212,7 @@ where
if !with_variables { if !with_variables {
dest.write_str(" ")? dest.write_str(" ")?
} }
} },
// Currently append_serialization is only called with a Css or // Currently append_serialization is only called with a Css or
// a Declaration AppendableValue. // a Declaration AppendableValue.
AppendableValue::DeclarationsForShorthand(..) => unreachable!(), AppendableValue::DeclarationsForShorthand(..) => unreachable!(),
@ -1228,7 +1264,7 @@ pub fn parse_one_declaration_into(
url_data: &UrlExtraData, url_data: &UrlExtraData,
error_reporter: Option<&dyn ParseErrorReporter>, error_reporter: Option<&dyn ParseErrorReporter>,
parsing_mode: ParsingMode, parsing_mode: ParsingMode,
quirks_mode: QuirksMode quirks_mode: QuirksMode,
) -> Result<(), ()> { ) -> Result<(), ()> {
let context = ParserContext::new( let context = ParserContext::new(
Origin::Author, Origin::Author,
@ -1249,9 +1285,11 @@ pub fn parse_one_declaration_into(
let mut input = ParserInput::new(input); let mut input = ParserInput::new(input);
let mut parser = Parser::new(&mut input); let mut parser = Parser::new(&mut input);
let start_position = parser.position(); let start_position = parser.position();
parser.parse_entirely(|parser| { parser
.parse_entirely(|parser| {
PropertyDeclaration::parse_into(declarations, id, &context, parser) PropertyDeclaration::parse_into(declarations, id, &context, parser)
}).map_err(|err| { })
.map_err(|err| {
if context.error_reporting_enabled() { if context.error_reporting_enabled() {
report_one_css_error( report_one_css_error(
&context, &context,
@ -1273,7 +1311,6 @@ struct PropertyDeclarationParser<'a, 'b: 'a> {
last_parsed_property_id: Option<PropertyId>, last_parsed_property_id: Option<PropertyId>,
} }
/// Default methods reject all at rules. /// Default methods reject all at rules.
impl<'a, 'b, 'i> AtRuleParser<'i> for PropertyDeclarationParser<'a, 'b> { impl<'a, 'b, 'i> AtRuleParser<'i> for PropertyDeclarationParser<'a, 'b> {
type PreludeNoBlock = (); type PreludeNoBlock = ();
@ -1284,8 +1321,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for PropertyDeclarationParser<'a, 'b> {
/// Based on NonMozillaVendorIdentifier from Gecko's CSS parser. /// Based on NonMozillaVendorIdentifier from Gecko's CSS parser.
fn is_non_mozilla_vendor_identifier(name: &str) -> bool { fn is_non_mozilla_vendor_identifier(name: &str) -> bool {
(name.starts_with("-") && !name.starts_with("-moz-")) || (name.starts_with("-") && !name.starts_with("-moz-")) || name.starts_with("_")
name.starts_with("_")
} }
impl<'a, 'b, 'i> DeclarationParser<'i> for PropertyDeclarationParser<'a, 'b> { impl<'a, 'b, 'i> DeclarationParser<'i> for PropertyDeclarationParser<'a, 'b> {
@ -1301,10 +1337,8 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for PropertyDeclarationParser<'a, 'b> {
Ok(id) => id, Ok(id) => id,
Err(..) => { Err(..) => {
self.last_parsed_property_id = None; self.last_parsed_property_id = None;
return Err(input.new_custom_error( return Err(input.new_custom_error(StyleParseErrorKind::UnknownProperty(name)));
StyleParseErrorKind::UnknownProperty(name) },
));
}
}; };
if self.context.error_reporting_enabled() { if self.context.error_reporting_enabled() {
self.last_parsed_property_id = Some(id.clone()); self.last_parsed_property_id = Some(id.clone());
@ -1344,10 +1378,8 @@ fn report_one_css_error<'i>(
fn all_properties_in_block(block: &PropertyDeclarationBlock, property: &PropertyId) -> bool { fn all_properties_in_block(block: &PropertyDeclarationBlock, property: &PropertyId) -> bool {
match *property { match *property {
PropertyId::LonghandAlias(id, _) | PropertyId::LonghandAlias(id, _) | PropertyId::Longhand(id) => block.contains(id),
PropertyId::Longhand(id) => block.contains(id), PropertyId::ShorthandAlias(id, _) | PropertyId::Shorthand(id) => {
PropertyId::ShorthandAlias(id, _) |
PropertyId::Shorthand(id) => {
id.longhands().all(|longhand| block.contains(longhand)) id.longhands().all(|longhand| block.contains(longhand))
}, },
// NOTE(emilio): We could do this, but it seems of limited utility, // NOTE(emilio): We could do this, but it seems of limited utility,
@ -1382,7 +1414,9 @@ fn report_one_css_error<'i>(
} }
} }
error = match *property { error = match *property {
PropertyId::Custom(ref c) => StyleParseErrorKind::new_invalid(format!("--{}", c), error), PropertyId::Custom(ref c) => {
StyleParseErrorKind::new_invalid(format!("--{}", c), error)
},
_ => StyleParseErrorKind::new_invalid(property.non_custom_id().unwrap().name(), error), _ => StyleParseErrorKind::new_invalid(property.non_custom_id().unwrap().name(), error),
}; };
} }
@ -1409,7 +1443,7 @@ fn report_css_errors(
pub fn parse_property_declaration_list( pub fn parse_property_declaration_list(
context: &ParserContext, context: &ParserContext,
input: &mut Parser, input: &mut Parser,
selectors: Option<&SelectorList<SelectorImpl>> selectors: Option<&SelectorList<SelectorImpl>>,
) -> PropertyDeclarationBlock { ) -> PropertyDeclarationBlock {
let mut declarations = SourcePropertyDeclaration::new(); let mut declarations = SourcePropertyDeclaration::new();
let mut block = PropertyDeclarationBlock::new(); let mut block = PropertyDeclarationBlock::new();
@ -1423,11 +1457,8 @@ pub fn parse_property_declaration_list(
while let Some(declaration) = iter.next() { while let Some(declaration) = iter.next() {
match declaration { match declaration {
Ok(importance) => { Ok(importance) => {
block.extend( block.extend(iter.parser.declarations.drain(), importance);
iter.parser.declarations.drain(), },
importance,
);
}
Err((error, slice)) => { Err((error, slice)) => {
iter.parser.declarations.clear(); iter.parser.declarations.clear();
@ -1435,7 +1466,7 @@ pub fn parse_property_declaration_list(
let property = iter.parser.last_parsed_property_id.take(); let property = iter.parser.last_parsed_property_id.take();
errors.push((error, slice, property)); errors.push((error, slice, property));
} }
} },
} }
} }