Auto merge of #17128 - emilio:first-line-letter, r=bholley

stylo: Basic support for first-line/letter dynamic changes.
This commit is contained in:
bors-servo 2017-06-01 12:13:43 -07:00 committed by GitHub
commit 17e69af0c9
5 changed files with 29 additions and 6 deletions

View file

@ -4,6 +4,7 @@
//! Per-node data used in style calculation. //! Per-node data used in style calculation.
use arrayvec::ArrayVec;
use context::SharedStyleContext; use context::SharedStyleContext;
use dom::TElement; use dom::TElement;
use properties::{AnimationRules, ComputedValues, PropertyDeclarationBlock}; use properties::{AnimationRules, ComputedValues, PropertyDeclarationBlock};
@ -193,8 +194,8 @@ impl EagerPseudoStyles {
} }
/// Returns a list of the pseudo-elements. /// Returns a list of the pseudo-elements.
pub fn keys(&self) -> Vec<PseudoElement> { pub fn keys(&self) -> ArrayVec<[PseudoElement; EAGER_PSEUDO_COUNT]> {
let mut v = Vec::new(); let mut v = ArrayVec::new();
if let Some(ref arr) = self.0 { if let Some(ref arr) = self.0 {
for i in 0..EAGER_PSEUDO_COUNT { for i in 0..EAGER_PSEUDO_COUNT {
if arr[i].is_some() { if arr[i].is_some() {

View file

@ -382,6 +382,20 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone +
pseudo: Option<&PseudoElement>) pseudo: Option<&PseudoElement>)
-> Option<&'a PreExistingComputedValues>; -> Option<&'a PreExistingComputedValues>;
/// Whether a given element may generate a pseudo-element.
///
/// This is useful to avoid computing, for example, pseudo styles for
/// `::-first-line` or `::-first-letter`, when we know it won't affect us.
///
/// TODO(emilio, bz): actually implement the logic for it.
fn may_generate_pseudo(
&self,
_pseudo: &PseudoElement,
_primary_style: &ComputedValues,
) -> bool {
true
}
/// Returns true if this element may have a descendant needing style processing. /// Returns true if this element may have a descendant needing style processing.
/// ///
/// Note that we cannot guarantee the existence of such an element, because /// Note that we cannot guarantee the existence of such an element, because
@ -444,7 +458,8 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone +
false false
} }
/// Flag that this element has a descendant for animation-only restyle processing. /// Flag that this element has a descendant for animation-only restyle
/// processing.
/// ///
/// Only safe to call with exclusive access to the element. /// Only safe to call with exclusive access to the element.
unsafe fn set_animation_only_dirty_descendants(&self) { unsafe fn set_animation_only_dirty_descendants(&self) {

View file

@ -176,12 +176,14 @@ pub enum PseudoElement {
/// The number of eager pseudo-elements. /// The number of eager pseudo-elements.
pub const EAGER_PSEUDO_COUNT: usize = 2; pub const EAGER_PSEUDO_COUNT: usize = 4;
/// The list of eager pseudos. /// The list of eager pseudos.
pub const EAGER_PSEUDOS: [PseudoElement; EAGER_PSEUDO_COUNT] = [ pub const EAGER_PSEUDOS: [PseudoElement; EAGER_PSEUDO_COUNT] = [
PseudoElement::Before, PseudoElement::Before,
PseudoElement::After, PseudoElement::After,
PseudoElement::FirstLine,
PseudoElement::FirstLetter,
]; ];
impl PseudoElement { impl PseudoElement {
@ -458,7 +460,7 @@ impl PseudoElement {
#[inline] #[inline]
pub fn is_eager(&self) -> bool { pub fn is_eager(&self) -> bool {
matches!(*self, matches!(*self,
PseudoElement::Before | PseudoElement::After) PseudoElement::Before | PseudoElement::After | PseudoElement::FirstLine | PseudoElement::FirstLetter)
} }
/// Gets the flags associated to this pseudo-element, or 0 if it's an /// Gets the flags associated to this pseudo-element, or 0 if it's an

View file

@ -11,7 +11,7 @@ pub enum PseudoElement {
% endfor % endfor
} }
<% EAGER_PSEUDOS = ["Before", "After"] %> <% EAGER_PSEUDOS = ["Before", "After", "FirstLine", "FirstLetter"] %>
/// The number of eager pseudo-elements. /// The number of eager pseudo-elements.
pub const EAGER_PSEUDO_COUNT: usize = ${len(EAGER_PSEUDOS)}; pub const EAGER_PSEUDO_COUNT: usize = ${len(EAGER_PSEUDOS)};

View file

@ -357,6 +357,7 @@ trait PrivateMatchMethods: TElement {
// below like a lazy pseudo. // below like a lazy pseudo.
let only_default_rules = context.shared.traversal_flags.for_default_styles(); let only_default_rules = context.shared.traversal_flags.for_default_styles();
if pseudo.is_eager() && !only_default_rules { if pseudo.is_eager() && !only_default_rules {
debug_assert!(pseudo.is_before_or_after());
let parent = self.parent_element().unwrap(); let parent = self.parent_element().unwrap();
if !parent.may_have_animations() || if !parent.may_have_animations() ||
primary_style.rules.get_animation_rules().is_empty() { primary_style.rules.get_animation_rules().is_empty() {
@ -1106,6 +1107,10 @@ pub trait MatchMethods : TElement {
return return
} }
if !self.may_generate_pseudo(&pseudo, data.styles().primary.values()) {
return;
}
debug_assert!(applicable_declarations.is_empty()); debug_assert!(applicable_declarations.is_empty());
// NB: We handle animation rules for ::before and ::after when // NB: We handle animation rules for ::before and ::after when
// traversing them. // traversing them.