mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
Adding more efficient way of determining if PropertyDeclaration is important
This commit is contained in:
parent
51e642e875
commit
be2f70393f
1 changed files with 31 additions and 16 deletions
|
@ -254,9 +254,10 @@ mod property_bit_field {
|
||||||
% endif
|
% endif
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
/// Declarations are stored in reverse order.
|
|
||||||
/// Overridden declarations are skipped.
|
|
||||||
|
|
||||||
|
use std::iter::{Iterator, Chain, Zip, Rev, Repeat, repeat};
|
||||||
|
use std::slice;
|
||||||
|
/// Overridden declarations are skipped.
|
||||||
|
|
||||||
// FIXME (https://github.com/servo/servo/issues/3426)
|
// FIXME (https://github.com/servo/servo/issues/3426)
|
||||||
#[derive(Debug, PartialEq, HeapSizeOf)]
|
#[derive(Debug, PartialEq, HeapSizeOf)]
|
||||||
|
@ -267,6 +268,19 @@ pub struct PropertyDeclarationBlock {
|
||||||
pub normal: Arc<Vec<PropertyDeclaration>>,
|
pub normal: Arc<Vec<PropertyDeclaration>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PropertyDeclarationBlock {
|
||||||
|
/// Provides an iterator of all declarations, with indication of !important value
|
||||||
|
pub fn declarations(&self) -> Chain<
|
||||||
|
Zip<Rev<slice::Iter<PropertyDeclaration>>, Repeat<bool>>,
|
||||||
|
Zip<Rev<slice::Iter<PropertyDeclaration>>, Repeat<bool>>
|
||||||
|
> {
|
||||||
|
// Declarations are stored in reverse order.
|
||||||
|
let normal = self.normal.iter().rev().zip(repeat(false));
|
||||||
|
let important = self.important.iter().rev().zip(repeat(true));
|
||||||
|
normal.chain(important)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ToCss for PropertyDeclarationBlock {
|
impl ToCss for PropertyDeclarationBlock {
|
||||||
// https://drafts.csswg.org/cssom/#serialize-a-css-declaration-block
|
// https://drafts.csswg.org/cssom/#serialize-a-css-declaration-block
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
|
@ -278,8 +292,7 @@ impl ToCss for PropertyDeclarationBlock {
|
||||||
let mut already_serialized = Vec::new();
|
let mut already_serialized = Vec::new();
|
||||||
|
|
||||||
// Step 3
|
// Step 3
|
||||||
// restore order of declarations since PropertyDeclarationBlock is stored in reverse order
|
for (declaration, important) in self.declarations() {
|
||||||
for declaration in self.important.iter().chain(self.normal.iter()).rev() {
|
|
||||||
// Step 3.1
|
// Step 3.1
|
||||||
let property = declaration.name();
|
let property = declaration.name();
|
||||||
|
|
||||||
|
@ -293,8 +306,8 @@ impl ToCss for PropertyDeclarationBlock {
|
||||||
if !shorthands.is_empty() {
|
if !shorthands.is_empty() {
|
||||||
|
|
||||||
// Step 3.3.1
|
// Step 3.3.1
|
||||||
let mut longhands = self.important.iter().chain(self.normal.iter()).rev()
|
let mut longhands = self.declarations()
|
||||||
.filter(|d| !already_serialized.contains(&d.name()))
|
.filter(|d| !already_serialized.contains(&d.0.name()))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
// Step 3.3.2
|
// Step 3.3.2
|
||||||
|
@ -303,24 +316,27 @@ impl ToCss for PropertyDeclarationBlock {
|
||||||
|
|
||||||
// Substep 2 & 3
|
// Substep 2 & 3
|
||||||
let mut current_longhands = Vec::new();
|
let mut current_longhands = Vec::new();
|
||||||
|
let mut important_count = 0;
|
||||||
|
|
||||||
for longhand in longhands.iter() {
|
for longhand in longhands.iter() {
|
||||||
let longhand_name = longhand.name();
|
let longhand_name = longhand.0.name();
|
||||||
if properties.iter().any(|p| &longhand_name == *p) {
|
if properties.iter().any(|p| &longhand_name == *p) {
|
||||||
current_longhands.push(*longhand);
|
current_longhands.push(longhand.0);
|
||||||
|
if longhand.1 == true {
|
||||||
|
important_count += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Substep 1
|
// Substep 1
|
||||||
|
/* Assuming that the PropertyDeclarationBlock contains no duplicate entries,
|
||||||
|
if the current_longhands length is equal to the properties length, it means
|
||||||
|
that the properties that map to shorthand are present in longhands */
|
||||||
if current_longhands.is_empty() || current_longhands.len() != properties.len() {
|
if current_longhands.is_empty() || current_longhands.len() != properties.len() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Substep 4
|
// Substep 4
|
||||||
let important_count = current_longhands.iter()
|
|
||||||
.filter(|l| self.important.contains(l))
|
|
||||||
.count();
|
|
||||||
|
|
||||||
let is_important = important_count > 0;
|
let is_important = important_count > 0;
|
||||||
if is_important && important_count != current_longhands.len() {
|
if is_important && important_count != current_longhands.len() {
|
||||||
continue;
|
continue;
|
||||||
|
@ -340,7 +356,7 @@ impl ToCss for PropertyDeclarationBlock {
|
||||||
for current_longhand in current_longhands {
|
for current_longhand in current_longhands {
|
||||||
// Substep 9
|
// Substep 9
|
||||||
already_serialized.push(current_longhand.name());
|
already_serialized.push(current_longhand.name());
|
||||||
let index_to_remove = longhands.iter().position(|l| l == ¤t_longhand);
|
let index_to_remove = longhands.iter().position(|l| l.0 == current_longhand);
|
||||||
if let Some(index) = index_to_remove {
|
if let Some(index) = index_to_remove {
|
||||||
// Substep 10
|
// Substep 10
|
||||||
longhands.remove(index);
|
longhands.remove(index);
|
||||||
|
@ -355,11 +371,10 @@ impl ToCss for PropertyDeclarationBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Steps 3.3.5, 3.3.6 & 3.3.7
|
// Steps 3.3.5, 3.3.6 & 3.3.7
|
||||||
let append_important = self.important.contains(declaration);
|
|
||||||
try!(append_serialization(dest,
|
try!(append_serialization(dest,
|
||||||
&property.to_string(),
|
&property.to_string(),
|
||||||
AppendableValue::Declaration(declaration),
|
AppendableValue::Declaration(declaration),
|
||||||
append_important,
|
important,
|
||||||
&mut is_first_serialization));
|
&mut is_first_serialization));
|
||||||
|
|
||||||
// Step 3.3.8
|
// Step 3.3.8
|
||||||
|
@ -380,7 +395,7 @@ fn append_serialization<W>(dest: &mut W,
|
||||||
property_name: &str,
|
property_name: &str,
|
||||||
appendable_value: AppendableValue,
|
appendable_value: AppendableValue,
|
||||||
is_important: bool,
|
is_important: bool,
|
||||||
is_first_serialization: &mut bool) -> fmt::Result where W: fmt::Write
|
is_first_serialization: &mut bool) -> fmt::Result where W: fmt::Write {
|
||||||
|
|
||||||
// after first serialization(key: value;) add whitespace between the pairs
|
// after first serialization(key: value;) add whitespace between the pairs
|
||||||
if !*is_first_serialization {
|
if !*is_first_serialization {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue