mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Add an Importance enum replacing booleans to indicate !important
.
This commit is contained in:
parent
8218b463fb
commit
24fbb26475
3 changed files with 64 additions and 48 deletions
|
@ -10,7 +10,7 @@ use dom::bindings::inheritance::Castable;
|
|||
use dom::bindings::js::{JS, Root};
|
||||
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||
use dom::bindings::str::DOMString;
|
||||
use dom::element::{Element, StylePriority};
|
||||
use dom::element::Element;
|
||||
use dom::node::{Node, NodeDamage, window_from_node};
|
||||
use dom::window::Window;
|
||||
use std::ascii::AsciiExt;
|
||||
|
@ -18,7 +18,7 @@ use std::cell::Ref;
|
|||
use std::slice;
|
||||
use string_cache::Atom;
|
||||
use style::parser::ParserContextExtraData;
|
||||
use style::properties::{PropertyDeclaration, Shorthand};
|
||||
use style::properties::{PropertyDeclaration, Shorthand, Importance};
|
||||
use style::properties::{is_supported_property, parse_one_declaration, parse_style_attribute};
|
||||
use style::selector_impl::PseudoElement;
|
||||
|
||||
|
@ -160,7 +160,8 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
|||
}
|
||||
|
||||
// TODO: important is hardcoded to false because method does not implement it yet
|
||||
let serialized_value = shorthand.serialize_shorthand_value_to_string(Map(list.iter()), false);
|
||||
let serialized_value = shorthand.serialize_shorthand_value_to_string(
|
||||
Map(list.iter()), Importance::Normal);
|
||||
return DOMString::from(serialized_value);
|
||||
}
|
||||
|
||||
|
@ -222,8 +223,8 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
|||
|
||||
// Step 5
|
||||
let priority = match &*priority {
|
||||
"" => StylePriority::Normal,
|
||||
p if p.eq_ignore_ascii_case("important") => StylePriority::Important,
|
||||
"" => Importance::Normal,
|
||||
p if p.eq_ignore_ascii_case("important") => Importance::Important,
|
||||
_ => return Ok(()),
|
||||
};
|
||||
|
||||
|
@ -265,8 +266,8 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
|||
|
||||
// Step 4
|
||||
let priority = match &*priority {
|
||||
"" => StylePriority::Normal,
|
||||
p if p.eq_ignore_ascii_case("important") => StylePriority::Important,
|
||||
"" => Importance::Normal,
|
||||
p if p.eq_ignore_ascii_case("important") => Importance::Important,
|
||||
_ => return Ok(()),
|
||||
};
|
||||
|
||||
|
|
|
@ -87,8 +87,8 @@ use style::attr::{AttrValue, LengthOrPercentageOrAuto};
|
|||
use style::element_state::*;
|
||||
use style::matching::{common_style_affecting_attributes, rare_style_affecting_attributes};
|
||||
use style::parser::ParserContextExtraData;
|
||||
use style::properties::DeclaredValue;
|
||||
use style::properties::longhands::{self, background_image, border_spacing, font_family, overflow_x, font_size};
|
||||
use style::properties::{DeclaredValue, Importance};
|
||||
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute};
|
||||
use style::selector_impl::{NonTSPseudoClass, ServoSelectorImpl};
|
||||
use style::sink::Push;
|
||||
|
@ -660,13 +660,6 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Copy, Clone, HeapSizeOf)]
|
||||
pub enum StylePriority {
|
||||
Important,
|
||||
Normal,
|
||||
}
|
||||
|
||||
|
||||
impl Element {
|
||||
pub fn html_element_in_html_document(&self) -> bool {
|
||||
self.namespace == ns!(html) && self.upcast::<Node>().is_in_html_doc()
|
||||
|
@ -780,11 +773,12 @@ impl Element {
|
|||
|
||||
pub fn update_inline_style(&self,
|
||||
declarations: Vec<PropertyDeclaration>,
|
||||
style_priority: StylePriority) {
|
||||
fn update(element: &Element, mut declarations: Vec<PropertyDeclaration>, style_priority: StylePriority) {
|
||||
importance: Importance) {
|
||||
fn update(element: &Element, mut declarations: Vec<PropertyDeclaration>,
|
||||
importance: Importance) {
|
||||
let mut inline_declarations = element.style_attribute().borrow_mut();
|
||||
if let &mut Some(ref mut existing_declarations) = &mut *inline_declarations {
|
||||
let existing_declarations = if style_priority == StylePriority::Important {
|
||||
let existing_declarations = if importance.important() {
|
||||
&mut existing_declarations.important
|
||||
} else {
|
||||
&mut existing_declarations.normal
|
||||
|
@ -813,7 +807,7 @@ impl Element {
|
|||
return;
|
||||
}
|
||||
|
||||
let (important, normal) = if style_priority == StylePriority::Important {
|
||||
let (important, normal) = if importance.important() {
|
||||
(declarations, vec![])
|
||||
} else {
|
||||
(vec![], declarations)
|
||||
|
@ -825,17 +819,17 @@ impl Element {
|
|||
});
|
||||
}
|
||||
|
||||
update(self, declarations, style_priority);
|
||||
update(self, declarations, importance);
|
||||
self.sync_property_with_attrs_style();
|
||||
}
|
||||
|
||||
pub fn set_inline_style_property_priority(&self,
|
||||
properties: &[&str],
|
||||
style_priority: StylePriority) {
|
||||
importance: Importance) {
|
||||
{
|
||||
let mut inline_declarations = self.style_attribute().borrow_mut();
|
||||
if let &mut Some(ref mut declarations) = &mut *inline_declarations {
|
||||
let (from, to) = if style_priority == StylePriority::Important {
|
||||
let (from, to) = if importance == Importance::Important {
|
||||
(&mut declarations.normal, &mut declarations.important)
|
||||
} else {
|
||||
(&mut declarations.important, &mut declarations.normal)
|
||||
|
|
|
@ -14,6 +14,8 @@ use std::ascii::AsciiExt;
|
|||
use std::boxed::Box as StdBox;
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::{self, Write};
|
||||
use std::iter::{Iterator, Chain, Zip, Rev, Repeat, repeat};
|
||||
use std::slice;
|
||||
use std::sync::Arc;
|
||||
|
||||
use app_units::Au;
|
||||
|
@ -261,11 +263,26 @@ mod property_bit_field {
|
|||
% endif
|
||||
% endfor
|
||||
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum Importance {
|
||||
/// Indicates a declaration without `!important`.
|
||||
Normal,
|
||||
|
||||
/// Indicates a declaration with `!important`.
|
||||
Important,
|
||||
}
|
||||
|
||||
impl Importance {
|
||||
pub fn important(self) -> bool {
|
||||
match self {
|
||||
Importance::Normal => false,
|
||||
Importance::Important => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
|
@ -279,12 +296,12 @@ pub struct PropertyDeclarationBlock {
|
|||
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>>
|
||||
Zip<Rev<slice::Iter<PropertyDeclaration>>, Repeat<Importance>>,
|
||||
Zip<Rev<slice::Iter<PropertyDeclaration>>, Repeat<Importance>>
|
||||
> {
|
||||
// Declarations are stored in reverse order.
|
||||
let normal = self.normal.iter().rev().zip(repeat(false));
|
||||
let important = self.important.iter().rev().zip(repeat(true));
|
||||
let normal = self.normal.iter().rev().zip(repeat(Importance::Normal));
|
||||
let important = self.important.iter().rev().zip(repeat(Importance::Important));
|
||||
normal.chain(important)
|
||||
}
|
||||
}
|
||||
|
@ -300,7 +317,7 @@ impl ToCss for PropertyDeclarationBlock {
|
|||
let mut already_serialized = Vec::new();
|
||||
|
||||
// Step 3
|
||||
for (declaration, important) in self.declarations() {
|
||||
for (declaration, importance) in self.declarations() {
|
||||
// Step 3.1
|
||||
let property = declaration.name();
|
||||
|
||||
|
@ -326,11 +343,11 @@ impl ToCss for PropertyDeclarationBlock {
|
|||
let mut current_longhands = Vec::new();
|
||||
let mut important_count = 0;
|
||||
|
||||
for &(longhand, longhand_important) in longhands.iter() {
|
||||
for &(longhand, longhand_importance) in longhands.iter() {
|
||||
let longhand_name = longhand.name();
|
||||
if properties.iter().any(|p| &longhand_name == *p) {
|
||||
current_longhands.push(longhand);
|
||||
if longhand_important {
|
||||
if longhand_importance.important() {
|
||||
important_count += 1;
|
||||
}
|
||||
}
|
||||
|
@ -396,7 +413,7 @@ impl ToCss for PropertyDeclarationBlock {
|
|||
dest,
|
||||
&property.to_string(),
|
||||
AppendableValue::Declaration(declaration),
|
||||
important,
|
||||
importance,
|
||||
&mut is_first_serialization));
|
||||
|
||||
// Step 3.3.8
|
||||
|
@ -430,7 +447,7 @@ fn handle_first_serialization<W>(dest: &mut W, is_first_serialization: &mut bool
|
|||
fn append_declaration_value<'a, W, I>
|
||||
(dest: &mut W,
|
||||
appendable_value: AppendableValue<'a, I>,
|
||||
is_important: bool)
|
||||
importance: Importance)
|
||||
-> fmt::Result
|
||||
where W: fmt::Write, I: Iterator<Item=&'a PropertyDeclaration> {
|
||||
match appendable_value {
|
||||
|
@ -445,7 +462,7 @@ fn append_declaration_value<'a, W, I>
|
|||
}
|
||||
}
|
||||
|
||||
if is_important {
|
||||
if importance.important() {
|
||||
try!(write!(dest, " !important"));
|
||||
}
|
||||
|
||||
|
@ -455,7 +472,7 @@ fn append_declaration_value<'a, W, I>
|
|||
fn append_serialization<'a, W, I>(dest: &mut W,
|
||||
property_name: &str,
|
||||
appendable_value: AppendableValue<'a, I>,
|
||||
is_important: bool,
|
||||
importance: Importance,
|
||||
is_first_serialization: &mut bool)
|
||||
-> fmt::Result
|
||||
where W: fmt::Write, I: Iterator<Item=&'a PropertyDeclaration> {
|
||||
|
@ -465,7 +482,7 @@ fn append_serialization<'a, W, I>(dest: &mut W,
|
|||
// Overflow does not behave like a normal shorthand. When overflow-x and overflow-y are not of equal
|
||||
// values, they no longer use the shared property name "overflow" and must be handled differently
|
||||
if shorthands::is_overflow_shorthand(&appendable_value) {
|
||||
return append_declaration_value(dest, appendable_value, is_important);
|
||||
return append_declaration_value(dest, appendable_value, importance);
|
||||
}
|
||||
|
||||
try!(write!(dest, "{}:", property_name));
|
||||
|
@ -484,7 +501,7 @@ fn append_serialization<'a, W, I>(dest: &mut W,
|
|||
&AppendableValue::DeclarationsForShorthand(..) => try!(write!(dest, " "))
|
||||
}
|
||||
|
||||
try!(append_declaration_value(dest, appendable_value, is_important));
|
||||
try!(append_declaration_value(dest, appendable_value, importance));
|
||||
write!(dest, ";")
|
||||
}
|
||||
|
||||
|
@ -514,14 +531,15 @@ struct PropertyDeclarationParser<'a, 'b: 'a> {
|
|||
/// Default methods reject all at rules.
|
||||
impl<'a, 'b> AtRuleParser for PropertyDeclarationParser<'a, 'b> {
|
||||
type Prelude = ();
|
||||
type AtRule = (Vec<PropertyDeclaration>, bool);
|
||||
type AtRule = (Vec<PropertyDeclaration>, Importance);
|
||||
}
|
||||
|
||||
|
||||
impl<'a, 'b> DeclarationParser for PropertyDeclarationParser<'a, 'b> {
|
||||
type Declaration = (Vec<PropertyDeclaration>, bool);
|
||||
type Declaration = (Vec<PropertyDeclaration>, Importance);
|
||||
|
||||
fn parse_value(&self, name: &str, input: &mut Parser) -> Result<(Vec<PropertyDeclaration>, bool), ()> {
|
||||
fn parse_value(&self, name: &str, input: &mut Parser)
|
||||
-> Result<(Vec<PropertyDeclaration>, Importance), ()> {
|
||||
let mut results = vec![];
|
||||
try!(input.parse_until_before(Delimiter::Bang, |input| {
|
||||
match PropertyDeclaration::parse(name, self.context, input, &mut results) {
|
||||
|
@ -529,8 +547,11 @@ impl<'a, 'b> DeclarationParser for PropertyDeclarationParser<'a, 'b> {
|
|||
_ => Err(())
|
||||
}
|
||||
}));
|
||||
let important = input.try(parse_important).is_ok();
|
||||
Ok((results, important))
|
||||
let importance = match input.try(parse_important) {
|
||||
Ok(()) => Importance::Important,
|
||||
Err(()) => Importance::Normal,
|
||||
};
|
||||
Ok((results, importance))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -545,8 +566,8 @@ pub fn parse_property_declaration_list(context: &ParserContext, input: &mut Pars
|
|||
let mut iter = DeclarationListParser::new(input, parser);
|
||||
while let Some(declaration) = iter.next() {
|
||||
match declaration {
|
||||
Ok((results, important)) => {
|
||||
if important {
|
||||
Ok((results, importance)) => {
|
||||
if importance.important() {
|
||||
important_declarations.extend(results);
|
||||
} else {
|
||||
normal_declarations.extend(results);
|
||||
|
@ -675,11 +696,11 @@ impl Shorthand {
|
|||
}
|
||||
|
||||
/// Serializes possible shorthand value to String.
|
||||
pub fn serialize_shorthand_value_to_string<'a, I>(self, declarations: I, is_important: bool) -> String
|
||||
pub fn serialize_shorthand_value_to_string<'a, I>(self, declarations: I, importance: Importance) -> String
|
||||
where I: Iterator<Item=&'a PropertyDeclaration> + Clone {
|
||||
let appendable_value = self.get_shorthand_appendable_value(declarations).unwrap();
|
||||
let mut result = String::new();
|
||||
append_declaration_value(&mut result, appendable_value, is_important).unwrap();
|
||||
append_declaration_value(&mut result, appendable_value, importance).unwrap();
|
||||
result
|
||||
}
|
||||
|
||||
|
@ -700,7 +721,7 @@ impl Shorthand {
|
|||
dest,
|
||||
property_name,
|
||||
appendable_value,
|
||||
false,
|
||||
Importance::Normal,
|
||||
is_first_serialization
|
||||
).and_then(|_| Ok(true))
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue