Skip to content

Commit

Permalink
Filter out non-applying properties when cascading style for ::first-l…
Browse files Browse the repository at this point in the history
…etter/::first-line/::placeholder. r=emilio

Part 3 of the fix for Gecko bug 1382786 <https://bugzilla.mozilla.org/show_bug.cgi?id=1382786>.
  • Loading branch information
bzbarsky committed Jul 21, 2017
1 parent 592a96f commit 86b3b6a
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 0 deletions.
13 changes: 13 additions & 0 deletions components/style/gecko/pseudo_element.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
}
}
}
15 changes: 15 additions & 0 deletions components/style/properties/properties.mako.rs
Expand Up @@ -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 {
Expand Down
13 changes: 13 additions & 0 deletions components/style/servo/selector_parser.rs
Expand Up @@ -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};
Expand All @@ -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,
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit 86b3b6a

Please sign in to comment.