Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding sync method to update atrr from inline style updates #9410

Closed
wants to merge 15 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Adding more efficient way of determining if PropertyDeclaration is im…

…portant
  • Loading branch information
craftytrickster committed May 19, 2016
commit d4234f4a84876260d690481583f358550333908b
@@ -247,9 +247,10 @@ mod property_bit_field {
% endif
% 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)
#[derive(Debug, PartialEq, HeapSizeOf)]
@@ -260,6 +261,19 @@ pub struct PropertyDeclarationBlock {
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 {
// https://drafts.csswg.org/cssom/#serialize-a-css-declaration-block
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
@@ -271,8 +285,7 @@ impl ToCss for PropertyDeclarationBlock {
let mut already_serialized = Vec::new();

// Step 3
// restore order of declarations since PropertyDeclarationBlock is stored in reverse order
for declaration in self.important.iter().chain(self.normal.iter()).rev() {
for (declaration, important) in self.declarations() {
// Step 3.1
let property = declaration.name();

@@ -286,8 +299,8 @@ impl ToCss for PropertyDeclarationBlock {
if !shorthands.is_empty() {

// Step 3.3.1
let mut longhands = self.important.iter().chain(self.normal.iter()).rev()
.filter(|d| !already_serialized.contains(&d.name()))
let mut longhands = self.declarations()
.filter(|d| !already_serialized.contains(&d.0.name()))
.collect::<Vec<_>>();

// Step 3.3.2
@@ -296,24 +309,27 @@ impl ToCss for PropertyDeclarationBlock {

// Substep 2 & 3
let mut current_longhands = Vec::new();
let mut important_count = 0;

for longhand in longhands.iter() {
let longhand_name = longhand.name();
let longhand_name = longhand.0.name();
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
/* 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() {
continue;
}

// Substep 4
let important_count = current_longhands.iter()
.filter(|l| self.important.contains(l))
.count();

let is_important = important_count > 0;
if is_important && important_count != current_longhands.len() {
continue;
@@ -333,7 +349,7 @@ impl ToCss for PropertyDeclarationBlock {
for current_longhand in current_longhands {
// Substep 9
already_serialized.push(current_longhand.name());
let index_to_remove = longhands.iter().position(|l| l == &current_longhand);
let index_to_remove = longhands.iter().position(|l| l.0 == current_longhand);
if let Some(index) = index_to_remove {
// Substep 10
longhands.remove(index);
@@ -348,11 +364,10 @@ impl ToCss for PropertyDeclarationBlock {
}

// Steps 3.3.5, 3.3.6 & 3.3.7
let append_important = self.important.contains(declaration);
try!(append_serialization(dest,
&property.to_string(),
AppendableValue::Declaration(declaration),
append_important,
important,
&mut is_first_serialization));

// Step 3.3.8
@@ -373,7 +388,7 @@ fn append_serialization<W>(dest: &mut W,
property_name: &str,
appendable_value: AppendableValue,
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
if !*is_first_serialization {
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.