mirror of
https://github.com/servo/servo.git
synced 2025-08-18 03:45:33 +01:00
Auto merge of #13640 - servo:CSSStyleDeclaration_in_style, r=mbrubeck
Move some of the CSSStyleDeclaration logic to the style crate <!-- Please describe your changes on the following line: --> … so that Stylo can re-use it. Fixes https://bugzilla.mozilla.org/show_bug.cgi?id=1295865 --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [ ] These changes fix #__ (github issue number if applicable). <!-- Either: --> - [ ] There are tests for these changes OR - [x] These changes do not require tests because refator <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13640) <!-- Reviewable:end -->
This commit is contained in:
commit
626d093245
4 changed files with 271 additions and 285 deletions
|
@ -6,6 +6,7 @@ use cssparser::{DeclarationListParser, parse_important, ToCss};
|
|||
use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter};
|
||||
use error_reporting::ParseErrorReporter;
|
||||
use parser::{ParserContext, ParserContextExtraData, log_css_error};
|
||||
use std::ascii::AsciiExt;
|
||||
use std::boxed::Box as StdBox;
|
||||
use std::fmt;
|
||||
use stylesheets::Origin;
|
||||
|
@ -66,16 +67,140 @@ impl PropertyDeclarationBlock {
|
|||
pub fn get(&self, property_name: &str) -> Option< &(PropertyDeclaration, Importance)> {
|
||||
self.declarations.iter().find(|&&(ref decl, _)| decl.matches(property_name))
|
||||
}
|
||||
}
|
||||
|
||||
impl PropertyDeclarationBlock {
|
||||
// Take a declaration block known to contain a single property,
|
||||
// and serialize it
|
||||
pub fn to_css_single_value<W>(&self, dest: &mut W, name: &str)
|
||||
-> fmt::Result where W: fmt::Write {
|
||||
/// Find the value of the given property in this block and serialize it
|
||||
///
|
||||
/// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue
|
||||
pub fn property_value_to_css<W>(&self, property_name: &str, dest: &mut W) -> fmt::Result
|
||||
where W: fmt::Write {
|
||||
// Step 1
|
||||
let property = property_name.to_ascii_lowercase();
|
||||
|
||||
// Step 2
|
||||
if let Some(shorthand) = Shorthand::from_name(&property) {
|
||||
// Step 2.1
|
||||
let mut list = Vec::new();
|
||||
|
||||
// Step 2.2
|
||||
for longhand in shorthand.longhands() {
|
||||
// Step 2.2.1
|
||||
let declaration = self.get(longhand);
|
||||
|
||||
// Step 2.2.2 & 2.2.3
|
||||
match declaration {
|
||||
Some(&(ref declaration, _importance)) => list.push(declaration),
|
||||
None => return Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2.3
|
||||
// TODO: importance is hardcoded because method does not implement it yet
|
||||
let importance = Importance::Normal;
|
||||
let appendable_value = shorthand.get_shorthand_appendable_value(list).unwrap();
|
||||
return append_declaration_value(dest, appendable_value, importance)
|
||||
}
|
||||
|
||||
if let Some(&(ref value, _importance)) = self.get(property_name) {
|
||||
// Step 3
|
||||
value.to_css(dest)
|
||||
} else {
|
||||
// Step 4
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority
|
||||
pub fn property_priority(&self, property_name: &str) -> Importance {
|
||||
// Step 1
|
||||
let property = property_name.to_ascii_lowercase();
|
||||
|
||||
// Step 2
|
||||
if let Some(shorthand) = Shorthand::from_name(&property) {
|
||||
// Step 2.1 & 2.2 & 2.3
|
||||
if shorthand.longhands().iter().all(|l| {
|
||||
self.get(l).map_or(false, |&(_, importance)| importance.important())
|
||||
}) {
|
||||
Importance::Important
|
||||
} else {
|
||||
Importance::Normal
|
||||
}
|
||||
} else {
|
||||
// Step 3
|
||||
self.get(&property).map_or(Importance::Normal, |&(_, importance)| importance)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_parsed_declaration(&mut self, declaration: PropertyDeclaration,
|
||||
importance: Importance) {
|
||||
for slot in &mut *self.declarations {
|
||||
if slot.0.name() == declaration.name() {
|
||||
match (slot.1, importance) {
|
||||
(Importance::Normal, Importance::Important) => {
|
||||
self.important_count += 1;
|
||||
}
|
||||
(Importance::Important, Importance::Normal) => {
|
||||
self.important_count -= 1;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
*slot = (declaration, importance);
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
self.declarations.push((declaration, importance));
|
||||
if importance.important() {
|
||||
self.important_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_importance(&mut self, property_names: &[&str], new_importance: Importance) {
|
||||
for &mut (ref declaration, ref mut importance) in &mut self.declarations {
|
||||
if property_names.iter().any(|p| declaration.matches(p)) {
|
||||
match (*importance, new_importance) {
|
||||
(Importance::Normal, Importance::Important) => {
|
||||
self.important_count += 1;
|
||||
}
|
||||
(Importance::Important, Importance::Normal) => {
|
||||
self.important_count -= 1;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
*importance = new_importance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-removeproperty
|
||||
pub fn remove_property(&mut self, property_name: &str) {
|
||||
// Step 2
|
||||
let property = property_name.to_ascii_lowercase();
|
||||
|
||||
match Shorthand::from_name(&property) {
|
||||
// Step 4
|
||||
Some(shorthand) => self.remove_longhands(shorthand.longhands()),
|
||||
// Step 5
|
||||
None => self.remove_longhands(&[&*property]),
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_longhands(&mut self, names: &[&str]) {
|
||||
let important_count = &mut self.important_count;
|
||||
self.declarations.retain(|&(ref declaration, importance)| {
|
||||
let retain = !names.iter().any(|n| declaration.matches(n));
|
||||
if !retain && importance.important() {
|
||||
*important_count -= 1
|
||||
}
|
||||
retain
|
||||
})
|
||||
}
|
||||
|
||||
/// Take a declaration block known to contain a single property and serialize it.
|
||||
pub fn single_value_to_css<W>(&self, property_name: &str, dest: &mut W) -> fmt::Result
|
||||
where W: fmt::Write {
|
||||
match self.declarations.len() {
|
||||
0 => Err(fmt::Error),
|
||||
1 if self.declarations[0].0.name().eq_str_ignore_ascii_case(name) => {
|
||||
1 if self.declarations[0].0.name().eq_str_ignore_ascii_case(property_name) => {
|
||||
self.declarations[0].0.to_css(dest)
|
||||
}
|
||||
_ => {
|
||||
|
@ -84,7 +209,7 @@ impl PropertyDeclarationBlock {
|
|||
-> &PropertyDeclaration {
|
||||
&dec.0
|
||||
}
|
||||
let shorthand = try!(Shorthand::from_name(name).ok_or(fmt::Error));
|
||||
let shorthand = try!(Shorthand::from_name(property_name).ok_or(fmt::Error));
|
||||
if !self.declarations.iter().all(|decl| decl.0.shorthands().contains(&shorthand)) {
|
||||
return Err(fmt::Error)
|
||||
}
|
||||
|
|
|
@ -410,15 +410,6 @@ impl Shorthand {
|
|||
}
|
||||
}
|
||||
|
||||
/// Serializes possible shorthand value to String.
|
||||
pub fn serialize_shorthand_value_to_string<'a, I>(self, declarations: I, importance: Importance) -> String
|
||||
where I: IntoIterator<Item=&'a PropertyDeclaration>, I::IntoIter: Clone {
|
||||
let appendable_value = self.get_shorthand_appendable_value(declarations).unwrap();
|
||||
let mut result = String::new();
|
||||
append_declaration_value(&mut result, appendable_value, importance).unwrap();
|
||||
result
|
||||
}
|
||||
|
||||
/// Serializes possible shorthand name with value to input buffer given a list of longhand declarations.
|
||||
/// On success, returns true if shorthand value is written and false if no shorthand value is present.
|
||||
pub fn serialize_shorthand_to_buffer<'a, W, I>(self,
|
||||
|
@ -1983,6 +1974,8 @@ pub fn modify_style_for_inline_absolute_hypothetical_fragment(style: &mut Arc<Co
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// FIXME: https://github.com/w3c/csswg-drafts/issues/580
|
||||
pub fn is_supported_property(property: &str) -> bool {
|
||||
match_ignore_ascii_case! { property,
|
||||
% for property in data.shorthands + data.longhands:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue