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