mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Filter out non-applying properties when cascading style for ::first-letter/::first-line/::placeholder. r=emilio
Part 3 of the fix for Gecko bug 1382786 <https://bugzilla.mozilla.org/show_bug.cgi?id=1382786>.
This commit is contained in:
parent
592a96fc06
commit
86b3b6a32f
3 changed files with 41 additions and 0 deletions
|
@ -10,6 +10,8 @@
|
|||
|
||||
use cssparser::{ToCss, serialize_identifier};
|
||||
use gecko_bindings::structs::{self, CSSPseudoElementType};
|
||||
use properties::{PropertyFlags, APPLIES_TO_FIRST_LETTER, APPLIES_TO_FIRST_LINE};
|
||||
use properties::APPLIES_TO_PLACEHOLDER;
|
||||
use selector_parser::{NonTSPseudoClass, PseudoElementCascadeType, SelectorImpl};
|
||||
use std::fmt;
|
||||
use string_cache::Atom;
|
||||
|
@ -119,4 +121,15 @@ impl PseudoElement {
|
|||
_ => self.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Property flag that properties must have to apply to this pseudo-element.
|
||||
#[inline]
|
||||
pub fn property_restriction(&self) -> Option<PropertyFlags> {
|
||||
match *self {
|
||||
PseudoElement::FirstLetter => Some(APPLIES_TO_FIRST_LETTER),
|
||||
PseudoElement::FirstLine => Some(APPLIES_TO_FIRST_LINE),
|
||||
PseudoElement::Placeholder => Some(APPLIES_TO_PLACEHOLDER),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2872,11 +2872,26 @@ pub fn cascade(
|
|||
&[]
|
||||
};
|
||||
let node_importance = node.importance();
|
||||
|
||||
let property_restriction = pseudo.and_then(|p| p.property_restriction());
|
||||
|
||||
declarations
|
||||
.iter()
|
||||
// Yield declarations later in source order (with more precedence) first.
|
||||
.rev()
|
||||
.filter_map(move |&(ref declaration, declaration_importance)| {
|
||||
if let Some(property_restriction) = property_restriction {
|
||||
// declaration.id() is either a longhand or a custom
|
||||
// property. Custom properties are always allowed, but
|
||||
// longhands are only allowed if they have our
|
||||
// property_restriction flag set.
|
||||
if let PropertyDeclarationId::Longhand(id) = declaration.id() {
|
||||
if !id.flags().contains(property_restriction) {
|
||||
return None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if declaration_importance == node_importance {
|
||||
Some((declaration, cascade_level))
|
||||
} else {
|
||||
|
|
|
@ -13,6 +13,7 @@ use dom::{OpaqueNode, TElement, TNode};
|
|||
use element_state::ElementState;
|
||||
use fnv::FnvHashMap;
|
||||
use invalidation::element::element_wrapper::ElementSnapshot;
|
||||
use properties::PropertyFlags;
|
||||
use selector_parser::{AttrValue as SelectorAttrValue, ElementExt, PseudoElementCascadeType, SelectorParser};
|
||||
use selectors::Element;
|
||||
use selectors::attr::{AttrSelectorOperation, NamespaceConstraint, CaseSensitivity};
|
||||
|
@ -39,6 +40,12 @@ pub enum PseudoElement {
|
|||
Before,
|
||||
Selection,
|
||||
// If/when :first-letter is added, update is_first_letter accordingly.
|
||||
|
||||
// If/when ::first-letter, ::first-line, or ::placeholder are added, adjust
|
||||
// our property_restriction implementation to do property filtering for
|
||||
// them. Also, make sure the UA sheet has the !important rules some of the
|
||||
// APPLIES_TO_PLACEHOLDER properties expect!
|
||||
|
||||
// Non-eager pseudos.
|
||||
DetailsSummary,
|
||||
DetailsContent,
|
||||
|
@ -169,6 +176,12 @@ impl PseudoElement {
|
|||
|
||||
/// Stub, only Gecko needs this
|
||||
pub fn pseudo_info(&self) { () }
|
||||
|
||||
/// Property flag that properties must have to apply to this pseudo-element.
|
||||
#[inline]
|
||||
pub fn property_restriction(&self) -> Option<PropertyFlags> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// The type used for storing pseudo-class string arguments.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue