mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Auto merge of #17027 - Manishearth:rollup, r=Manishearth
Rollup of 9 pull requests - Successful merges: #16993, #17000, #17010, #17013, #17014, #17017, #17019, #17020, #17022 - Failed merges: <!-- 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/17027) <!-- Reviewable:end -->
This commit is contained in:
commit
8ae546f7ea
18 changed files with 299 additions and 179 deletions
|
@ -632,14 +632,6 @@ impl<T: ClipboardProvider> TextInput<T> {
|
||||||
self.insert_char(c);
|
self.insert_char(c);
|
||||||
KeyReaction::DispatchInput
|
KeyReaction::DispatchInput
|
||||||
},
|
},
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
(None, Key::Home) => {
|
|
||||||
KeyReaction::RedrawSelection
|
|
||||||
},
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
(None, Key::End) => {
|
|
||||||
KeyReaction::RedrawSelection
|
|
||||||
},
|
|
||||||
(None, Key::Delete) => {
|
(None, Key::Delete) => {
|
||||||
self.delete_char(Direction::Forward);
|
self.delete_char(Direction::Forward);
|
||||||
KeyReaction::DispatchInput
|
KeyReaction::DispatchInput
|
||||||
|
@ -694,12 +686,18 @@ impl<T: ClipboardProvider> TextInput<T> {
|
||||||
},
|
},
|
||||||
(None, Key::Enter) | (None, Key::KpEnter) => self.handle_return(),
|
(None, Key::Enter) | (None, Key::KpEnter) => self.handle_return(),
|
||||||
(None, Key::Home) => {
|
(None, Key::Home) => {
|
||||||
self.edit_point.index = 0;
|
#[cfg(not(target_os = "macos"))]
|
||||||
|
{
|
||||||
|
self.edit_point.index = 0;
|
||||||
|
}
|
||||||
KeyReaction::RedrawSelection
|
KeyReaction::RedrawSelection
|
||||||
},
|
},
|
||||||
(None, Key::End) => {
|
(None, Key::End) => {
|
||||||
self.edit_point.index = self.current_line_length();
|
#[cfg(not(target_os = "macos"))]
|
||||||
self.assert_ok_selection();
|
{
|
||||||
|
self.edit_point.index = self.current_line_length();
|
||||||
|
self.assert_ok_selection();
|
||||||
|
}
|
||||||
KeyReaction::RedrawSelection
|
KeyReaction::RedrawSelection
|
||||||
},
|
},
|
||||||
(None, Key::PageUp) => {
|
(None, Key::PageUp) => {
|
||||||
|
|
|
@ -6,12 +6,12 @@
|
||||||
|
|
||||||
use context::SharedStyleContext;
|
use context::SharedStyleContext;
|
||||||
use dom::TElement;
|
use dom::TElement;
|
||||||
use properties::ComputedValues;
|
use properties::{AnimationRules, ComputedValues, PropertyDeclarationBlock};
|
||||||
use properties::longhands::display::computed_value as display;
|
use properties::longhands::display::computed_value as display;
|
||||||
use restyle_hints::{HintComputationContext, RestyleReplacements, RestyleHint};
|
use restyle_hints::{HintComputationContext, RestyleReplacements, RestyleHint};
|
||||||
use rule_tree::StrongRuleNode;
|
use rule_tree::StrongRuleNode;
|
||||||
use selector_parser::{EAGER_PSEUDO_COUNT, PseudoElement, RestyleDamage};
|
use selector_parser::{EAGER_PSEUDO_COUNT, PseudoElement, RestyleDamage};
|
||||||
use shared_lock::StylesheetGuards;
|
use shared_lock::{Locked, StylesheetGuards};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use stylearc::Arc;
|
use stylearc::Arc;
|
||||||
use traversal::TraversalFlags;
|
use traversal::TraversalFlags;
|
||||||
|
@ -558,4 +558,29 @@ impl ElementData {
|
||||||
pub fn restyle_mut(&mut self) -> &mut RestyleData {
|
pub fn restyle_mut(&mut self) -> &mut RestyleData {
|
||||||
self.get_restyle_mut().expect("Calling restyle_mut without RestyleData")
|
self.get_restyle_mut().expect("Calling restyle_mut without RestyleData")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns SMIL overriden value if exists.
|
||||||
|
pub fn get_smil_override(&self) -> Option<&Arc<Locked<PropertyDeclarationBlock>>> {
|
||||||
|
if cfg!(feature = "servo") {
|
||||||
|
// Servo has no knowledge of a SMIL rule, so just avoid looking for it.
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.get_styles() {
|
||||||
|
Some(s) => s.primary.rules.get_smil_animation_rule(),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns AnimationRules that has processed during animation-only restyles.
|
||||||
|
pub fn get_animation_rules(&self) -> AnimationRules {
|
||||||
|
if cfg!(feature = "servo") {
|
||||||
|
return AnimationRules(None, None)
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.get_styles() {
|
||||||
|
Some(s) => s.primary.rules.get_animation_rules(),
|
||||||
|
None => AnimationRules(None, None),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -274,20 +274,6 @@ pub trait PresentationalHintsSynthesizer {
|
||||||
where V: Push<ApplicableDeclarationBlock>;
|
where V: Push<ApplicableDeclarationBlock>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The animation rules.
|
|
||||||
///
|
|
||||||
/// The first one is for Animation cascade level, and the second one is for
|
|
||||||
/// Transition cascade level.
|
|
||||||
pub struct AnimationRules(pub Option<Arc<Locked<PropertyDeclarationBlock>>>,
|
|
||||||
pub Option<Arc<Locked<PropertyDeclarationBlock>>>);
|
|
||||||
|
|
||||||
impl AnimationRules {
|
|
||||||
/// Returns whether these animation rules represents an actual rule or not.
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
self.0.is_none() && self.1.is_none()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The element trait, the main abstraction the style crate acts over.
|
/// The element trait, the main abstraction the style crate acts over.
|
||||||
pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone +
|
pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone +
|
||||||
ElementExt + PresentationalHintsSynthesizer {
|
ElementExt + PresentationalHintsSynthesizer {
|
||||||
|
@ -348,11 +334,6 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone +
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get this element's animation rules.
|
|
||||||
fn get_animation_rules(&self) -> AnimationRules {
|
|
||||||
AnimationRules(None, None)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get this element's animation rule by the cascade level.
|
/// Get this element's animation rule by the cascade level.
|
||||||
fn get_animation_rule_by_cascade(&self,
|
fn get_animation_rule_by_cascade(&self,
|
||||||
_cascade_level: CascadeLevel)
|
_cascade_level: CascadeLevel)
|
||||||
|
@ -525,6 +506,11 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone +
|
||||||
/// Returns true if the element has all the specified selector flags.
|
/// Returns true if the element has all the specified selector flags.
|
||||||
fn has_selector_flags(&self, flags: ElementSelectorFlags) -> bool;
|
fn has_selector_flags(&self, flags: ElementSelectorFlags) -> bool;
|
||||||
|
|
||||||
|
/// In Gecko, element has a flag that represents the element may have
|
||||||
|
/// any type of animations or not to bail out animation stuff early.
|
||||||
|
/// Whereas Servo doesn't have such flag.
|
||||||
|
fn may_have_animations(&self) -> bool { false }
|
||||||
|
|
||||||
/// Creates a task to update various animation state on a given (pseudo-)element.
|
/// Creates a task to update various animation state on a given (pseudo-)element.
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
fn update_animations(&self,
|
fn update_animations(&self,
|
||||||
|
|
|
@ -128,6 +128,10 @@ impl ToCss for Expression {
|
||||||
where W: fmt::Write,
|
where W: fmt::Write,
|
||||||
{
|
{
|
||||||
dest.write_str("(")?;
|
dest.write_str("(")?;
|
||||||
|
|
||||||
|
if (self.feature.mReqFlags & nsMediaFeature_RequirementFlags::eHasWebkitPrefix as u8) != 0 {
|
||||||
|
dest.write_str("-webkit-")?;
|
||||||
|
}
|
||||||
match self.range {
|
match self.range {
|
||||||
nsMediaExpression_Range::eMin => dest.write_str("min-")?,
|
nsMediaExpression_Range::eMin => dest.write_str("min-")?,
|
||||||
nsMediaExpression_Range::eMax => dest.write_str("max-")?,
|
nsMediaExpression_Range::eMax => dest.write_str("max-")?,
|
||||||
|
|
|
@ -107,6 +107,7 @@ macro_rules! apply_non_ts_list {
|
||||||
("-moz-only-whitespace", MozOnlyWhitespace, mozOnlyWhitespace, _, _),
|
("-moz-only-whitespace", MozOnlyWhitespace, mozOnlyWhitespace, _, _),
|
||||||
("-moz-native-anonymous", MozNativeAnonymous, mozNativeAnonymous, _, PSEUDO_CLASS_INTERNAL),
|
("-moz-native-anonymous", MozNativeAnonymous, mozNativeAnonymous, _, PSEUDO_CLASS_INTERNAL),
|
||||||
("-moz-is-html", MozIsHTML, mozIsHTML, _, _),
|
("-moz-is-html", MozIsHTML, mozIsHTML, _, _),
|
||||||
|
("-moz-placeholder", MozPlaceholder, mozPlaceholder, _, _),
|
||||||
],
|
],
|
||||||
string: [
|
string: [
|
||||||
("-moz-system-metric", MozSystemMetric, mozSystemMetric, _, PSEUDO_CLASS_INTERNAL),
|
("-moz-system-metric", MozSystemMetric, mozSystemMetric, _, PSEUDO_CLASS_INTERNAL),
|
||||||
|
|
|
@ -102,6 +102,15 @@ impl PseudoElement {
|
||||||
pub fn is_precomputed(&self) -> bool {
|
pub fn is_precomputed(&self) -> bool {
|
||||||
self.is_anon_box()
|
self.is_anon_box()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Covert non-canonical pseudo-element to canonical one, and keep a
|
||||||
|
/// canonical one as it is.
|
||||||
|
pub fn canonical(&self) -> PseudoElement {
|
||||||
|
match *self {
|
||||||
|
PseudoElement::MozPlaceholder => PseudoElement::Placeholder,
|
||||||
|
_ => self.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToCss for PseudoElement {
|
impl ToCss for PseudoElement {
|
||||||
|
|
|
@ -166,7 +166,8 @@ impl NonTSPseudoClass {
|
||||||
!matches!(*self,
|
!matches!(*self,
|
||||||
NonTSPseudoClass::MozAny(_) |
|
NonTSPseudoClass::MozAny(_) |
|
||||||
NonTSPseudoClass::Dir(_) |
|
NonTSPseudoClass::Dir(_) |
|
||||||
NonTSPseudoClass::MozIsHTML)
|
NonTSPseudoClass::MozIsHTML |
|
||||||
|
NonTSPseudoClass::MozPlaceholder)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert NonTSPseudoClass to Gecko's CSSPseudoClassType.
|
/// Convert NonTSPseudoClass to Gecko's CSSPseudoClassType.
|
||||||
|
|
|
@ -18,7 +18,7 @@ use app_units::Au;
|
||||||
use atomic_refcell::AtomicRefCell;
|
use atomic_refcell::AtomicRefCell;
|
||||||
use context::{QuirksMode, SharedStyleContext, UpdateAnimationsTasks};
|
use context::{QuirksMode, SharedStyleContext, UpdateAnimationsTasks};
|
||||||
use data::ElementData;
|
use data::ElementData;
|
||||||
use dom::{self, AnimationRules, DescendantsBit, LayoutIterator, NodeInfo, TElement, TNode, UnsafeNode};
|
use dom::{self, DescendantsBit, LayoutIterator, NodeInfo, TElement, TNode, UnsafeNode};
|
||||||
use dom::{OpaqueNode, PresentationalHintsSynthesizer};
|
use dom::{OpaqueNode, PresentationalHintsSynthesizer};
|
||||||
use element_state::ElementState;
|
use element_state::ElementState;
|
||||||
use error_reporting::RustLogReporter;
|
use error_reporting::RustLogReporter;
|
||||||
|
@ -422,11 +422,6 @@ impl<'le> GeckoElement<'le> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn may_have_animations(&self) -> bool {
|
|
||||||
self.as_node().get_bool_flag(nsINode_BooleanFlag::ElementHasAnimations)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn has_id(&self) -> bool {
|
fn has_id(&self) -> bool {
|
||||||
self.as_node().get_bool_flag(nsINode_BooleanFlag::ElementHasID)
|
self.as_node().get_bool_flag(nsINode_BooleanFlag::ElementHasID)
|
||||||
|
@ -613,11 +608,6 @@ impl<'le> TElement for GeckoElement<'le> {
|
||||||
declarations.map(|s| s.as_arc_opt()).unwrap_or(None)
|
declarations.map(|s| s.as_arc_opt()).unwrap_or(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_animation_rules(&self) -> AnimationRules {
|
|
||||||
AnimationRules(self.get_animation_rule(),
|
|
||||||
self.get_transition_rule())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_animation_rule_by_cascade(&self, cascade_level: ServoCascadeLevel)
|
fn get_animation_rule_by_cascade(&self, cascade_level: ServoCascadeLevel)
|
||||||
-> Option<Arc<Locked<PropertyDeclarationBlock>>> {
|
-> Option<Arc<Locked<PropertyDeclarationBlock>>> {
|
||||||
match cascade_level {
|
match cascade_level {
|
||||||
|
@ -782,6 +772,11 @@ impl<'le> TElement for GeckoElement<'le> {
|
||||||
(self.flags() & node_flags) == node_flags
|
(self.flags() & node_flags) == node_flags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn may_have_animations(&self) -> bool {
|
||||||
|
self.as_node().get_bool_flag(nsINode_BooleanFlag::ElementHasAnimations)
|
||||||
|
}
|
||||||
|
|
||||||
fn update_animations(&self,
|
fn update_animations(&self,
|
||||||
before_change_style: Option<Arc<ComputedValues>>,
|
before_change_style: Option<Arc<ComputedValues>>,
|
||||||
tasks: UpdateAnimationsTasks) {
|
tasks: UpdateAnimationsTasks) {
|
||||||
|
@ -1335,6 +1330,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
||||||
NonTSPseudoClass::MozIsHTML => {
|
NonTSPseudoClass::MozIsHTML => {
|
||||||
self.is_html_element_in_html_document()
|
self.is_html_element_in_html_document()
|
||||||
}
|
}
|
||||||
|
NonTSPseudoClass::MozPlaceholder => false,
|
||||||
NonTSPseudoClass::MozAny(ref sels) => {
|
NonTSPseudoClass::MozAny(ref sels) => {
|
||||||
sels.iter().any(|s| {
|
sels.iter().any(|s| {
|
||||||
matches_complex_selector(s, self, context, flags_setter)
|
matches_complex_selector(s, self, context, flags_setter)
|
||||||
|
@ -1368,7 +1364,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
||||||
// match the proper pseudo-element, given how we rulehash the stuff
|
// match the proper pseudo-element, given how we rulehash the stuff
|
||||||
// based on the pseudo.
|
// based on the pseudo.
|
||||||
match self.implemented_pseudo_element() {
|
match self.implemented_pseudo_element() {
|
||||||
Some(ref pseudo) => pseudo == pseudo_element,
|
Some(ref pseudo) => *pseudo == pseudo_element.canonical(),
|
||||||
None => false,
|
None => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -239,6 +239,10 @@ impl Atom {
|
||||||
|
|
||||||
/// Return whether two atoms are ASCII-case-insensitive matches
|
/// Return whether two atoms are ASCII-case-insensitive matches
|
||||||
pub fn eq_ignore_ascii_case(&self, other: &Self) -> bool {
|
pub fn eq_ignore_ascii_case(&self, other: &Self) -> bool {
|
||||||
|
if self == other {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
let a = self.as_slice();
|
let a = self.as_slice();
|
||||||
let b = other.as_slice();
|
let b = other.as_slice();
|
||||||
a.len() == b.len() && a.iter().zip(b).all(|(&a16, &b16)| {
|
a.len() == b.len() && a.iter().zip(b).all(|(&a16, &b16)| {
|
||||||
|
|
|
@ -10,10 +10,10 @@
|
||||||
use cascade_info::CascadeInfo;
|
use cascade_info::CascadeInfo;
|
||||||
use context::{SelectorFlagsMap, SharedStyleContext, StyleContext};
|
use context::{SelectorFlagsMap, SharedStyleContext, StyleContext};
|
||||||
use data::{ComputedStyle, ElementData, RestyleData};
|
use data::{ComputedStyle, ElementData, RestyleData};
|
||||||
use dom::{AnimationRules, TElement, TNode};
|
use dom::{TElement, TNode};
|
||||||
use font_metrics::FontMetricsProvider;
|
use font_metrics::FontMetricsProvider;
|
||||||
use log::LogLevel::Trace;
|
use log::LogLevel::Trace;
|
||||||
use properties::{CascadeFlags, ComputedValues, SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP, cascade};
|
use properties::{AnimationRules, CascadeFlags, ComputedValues, SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP, cascade};
|
||||||
use properties::longhands::display::computed_value as display;
|
use properties::longhands::display::computed_value as display;
|
||||||
use restyle_hints::{RESTYLE_CSS_ANIMATIONS, RESTYLE_CSS_TRANSITIONS, RestyleReplacements};
|
use restyle_hints::{RESTYLE_CSS_ANIMATIONS, RESTYLE_CSS_TRANSITIONS, RestyleReplacements};
|
||||||
use restyle_hints::{RESTYLE_STYLE_ATTRIBUTE, RESTYLE_SMIL};
|
use restyle_hints::{RESTYLE_STYLE_ATTRIBUTE, RESTYLE_SMIL};
|
||||||
|
@ -254,12 +254,15 @@ trait PrivateMatchMethods: TElement {
|
||||||
// We could make that a bit better if the complexity cost is not too
|
// We could make that a bit better if the complexity cost is not too
|
||||||
// big, but given further restyles are posted directly to
|
// big, but given further restyles are posted directly to
|
||||||
// pseudo-elements, it doesn't seem worth the effort at a glance.
|
// pseudo-elements, it doesn't seem worth the effort at a glance.
|
||||||
if pseudo.is_eager() && self.get_animation_rules().is_empty() {
|
if pseudo.is_eager() {
|
||||||
let parent = self.parent_element().unwrap();
|
let parent = self.parent_element().unwrap();
|
||||||
let parent_data = parent.borrow_data().unwrap();
|
if !parent.may_have_animations() ||
|
||||||
let pseudo_style =
|
primary_style.rules.get_animation_rules().is_empty() {
|
||||||
parent_data.styles().pseudos.get(&pseudo).unwrap();
|
let parent_data = parent.borrow_data().unwrap();
|
||||||
return pseudo_style.values().clone()
|
let pseudo_style =
|
||||||
|
parent_data.styles().pseudos.get(&pseudo).unwrap();
|
||||||
|
return pseudo_style.values().clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -684,6 +687,8 @@ pub trait MatchMethods : TElement {
|
||||||
{
|
{
|
||||||
let implemented_pseudo = self.implemented_pseudo_element();
|
let implemented_pseudo = self.implemented_pseudo_element();
|
||||||
if let Some(ref pseudo) = implemented_pseudo {
|
if let Some(ref pseudo) = implemented_pseudo {
|
||||||
|
// We don't expect to match against a non-canonical pseudo-element.
|
||||||
|
debug_assert_eq!(*pseudo, pseudo.canonical());
|
||||||
if pseudo.is_eager() {
|
if pseudo.is_eager() {
|
||||||
// If it's an eager element-backed pseudo, just grab the matched
|
// If it's an eager element-backed pseudo, just grab the matched
|
||||||
// rules from the parent, and update animations.
|
// rules from the parent, and update animations.
|
||||||
|
@ -692,38 +697,39 @@ pub trait MatchMethods : TElement {
|
||||||
let pseudo_style =
|
let pseudo_style =
|
||||||
parent_data.styles().pseudos.get(&pseudo).unwrap();
|
parent_data.styles().pseudos.get(&pseudo).unwrap();
|
||||||
let mut rules = pseudo_style.rules.clone();
|
let mut rules = pseudo_style.rules.clone();
|
||||||
let animation_rules = self.get_animation_rules();
|
if parent.may_have_animations() {
|
||||||
|
let animation_rules = data.get_animation_rules();
|
||||||
|
|
||||||
// Handle animations here.
|
// Handle animations here.
|
||||||
if let Some(animation_rule) = animation_rules.0 {
|
if let Some(animation_rule) = animation_rules.0 {
|
||||||
let animation_rule_node =
|
let animation_rule_node =
|
||||||
context.shared.stylist.rule_tree()
|
context.shared.stylist.rule_tree()
|
||||||
.update_rule_at_level(CascadeLevel::Animations,
|
.update_rule_at_level(CascadeLevel::Animations,
|
||||||
Some(&animation_rule),
|
Some(&animation_rule),
|
||||||
&mut rules,
|
&mut rules,
|
||||||
&context.shared.guards);
|
&context.shared.guards);
|
||||||
if let Some(node) = animation_rule_node {
|
if let Some(node) = animation_rule_node {
|
||||||
rules = node;
|
rules = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(animation_rule) = animation_rules.1 {
|
||||||
|
let animation_rule_node =
|
||||||
|
context.shared.stylist.rule_tree()
|
||||||
|
.update_rule_at_level(CascadeLevel::Transitions,
|
||||||
|
Some(&animation_rule),
|
||||||
|
&mut rules,
|
||||||
|
&context.shared.guards);
|
||||||
|
if let Some(node) = animation_rule_node {
|
||||||
|
rules = node;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(animation_rule) = animation_rules.1 {
|
|
||||||
let animation_rule_node =
|
|
||||||
context.shared.stylist.rule_tree()
|
|
||||||
.update_rule_at_level(CascadeLevel::Transitions,
|
|
||||||
Some(&animation_rule),
|
|
||||||
&mut rules,
|
|
||||||
&context.shared.guards);
|
|
||||||
if let Some(node) = animation_rule_node {
|
|
||||||
rules = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let important_rules_changed =
|
let important_rules_changed =
|
||||||
self.has_animations() &&
|
self.has_animations() &&
|
||||||
data.has_styles() &&
|
data.has_styles() &&
|
||||||
data.important_rules_are_different(&rules,
|
data.important_rules_are_different(&rules,
|
||||||
&context.shared.guards);
|
&context.shared.guards);
|
||||||
|
|
||||||
return RulesMatchedResult {
|
return RulesMatchedResult {
|
||||||
rule_nodes_changed: data.set_primary_rules(rules),
|
rule_nodes_changed: data.set_primary_rules(rules),
|
||||||
|
@ -736,30 +742,35 @@ pub trait MatchMethods : TElement {
|
||||||
|
|
||||||
let stylist = &context.shared.stylist;
|
let stylist = &context.shared.stylist;
|
||||||
let style_attribute = self.style_attribute();
|
let style_attribute = self.style_attribute();
|
||||||
let smil_override = self.get_smil_override();
|
{
|
||||||
let animation_rules = self.get_animation_rules();
|
let smil_override = data.get_smil_override();
|
||||||
let bloom = context.thread_local.bloom_filter.filter();
|
let animation_rules = if self.may_have_animations() {
|
||||||
|
data.get_animation_rules()
|
||||||
|
} else {
|
||||||
|
AnimationRules(None, None)
|
||||||
|
};
|
||||||
|
let bloom = context.thread_local.bloom_filter.filter();
|
||||||
|
|
||||||
|
let map = &mut context.thread_local.selector_flags;
|
||||||
|
let mut set_selector_flags = |element: &Self, flags: ElementSelectorFlags| {
|
||||||
|
self.apply_selector_flags(map, element, flags);
|
||||||
|
};
|
||||||
|
|
||||||
let map = &mut context.thread_local.selector_flags;
|
let mut matching_context =
|
||||||
let mut set_selector_flags = |element: &Self, flags: ElementSelectorFlags| {
|
MatchingContext::new(MatchingMode::Normal, Some(bloom));
|
||||||
self.apply_selector_flags(map, element, flags);
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut matching_context =
|
// Compute the primary rule node.
|
||||||
MatchingContext::new(MatchingMode::Normal, Some(bloom));
|
stylist.push_applicable_declarations(self,
|
||||||
|
implemented_pseudo.as_ref(),
|
||||||
|
style_attribute,
|
||||||
|
smil_override,
|
||||||
|
animation_rules,
|
||||||
|
&mut applicable_declarations,
|
||||||
|
&mut matching_context,
|
||||||
|
&mut set_selector_flags);
|
||||||
|
|
||||||
// Compute the primary rule node.
|
*relations = matching_context.relations;
|
||||||
stylist.push_applicable_declarations(self,
|
}
|
||||||
implemented_pseudo.as_ref(),
|
|
||||||
style_attribute,
|
|
||||||
smil_override,
|
|
||||||
animation_rules,
|
|
||||||
&mut applicable_declarations,
|
|
||||||
&mut matching_context,
|
|
||||||
&mut set_selector_flags);
|
|
||||||
|
|
||||||
*relations = matching_context.relations;
|
|
||||||
|
|
||||||
let primary_rule_node =
|
let primary_rule_node =
|
||||||
compute_rule_node::<Self>(stylist.rule_tree(),
|
compute_rule_node::<Self>(stylist.rule_tree(),
|
||||||
|
@ -963,81 +974,82 @@ pub trait MatchMethods : TElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates the rule nodes without re-running selector matching, using just
|
/// Updates the rule nodes without re-running selector matching, using just
|
||||||
/// the rule tree. Returns RulesChanged which indicates whether the rule nodes changed
|
/// the rule tree. Returns true if an !important rule was replaced.
|
||||||
/// and whether the important rules changed.
|
|
||||||
fn replace_rules(&self,
|
fn replace_rules(&self,
|
||||||
replacements: RestyleReplacements,
|
replacements: RestyleReplacements,
|
||||||
context: &StyleContext<Self>,
|
context: &StyleContext<Self>,
|
||||||
data: &mut ElementData)
|
data: &mut ElementData)
|
||||||
-> RulesChanged {
|
-> bool {
|
||||||
use properties::PropertyDeclarationBlock;
|
use properties::PropertyDeclarationBlock;
|
||||||
use shared_lock::Locked;
|
use shared_lock::Locked;
|
||||||
|
|
||||||
let element_styles = &mut data.styles_mut();
|
let element_styles = &mut data.styles_mut();
|
||||||
let primary_rules = &mut element_styles.primary.rules;
|
let primary_rules = &mut element_styles.primary.rules;
|
||||||
let mut result = RulesChanged::empty();
|
|
||||||
|
|
||||||
{
|
let replace_rule_node = |level: CascadeLevel,
|
||||||
let mut replace_rule_node = |level: CascadeLevel,
|
pdb: Option<&Arc<Locked<PropertyDeclarationBlock>>>,
|
||||||
pdb: Option<&Arc<Locked<PropertyDeclarationBlock>>>,
|
path: &mut StrongRuleNode| -> bool {
|
||||||
path: &mut StrongRuleNode| {
|
let new_node = context.shared.stylist.rule_tree()
|
||||||
let new_node = context.shared.stylist.rule_tree()
|
.update_rule_at_level(level, pdb, path, &context.shared.guards);
|
||||||
.update_rule_at_level(level, pdb, path, &context.shared.guards);
|
match new_node {
|
||||||
if let Some(n) = new_node {
|
Some(n) => {
|
||||||
*path = n;
|
*path = n;
|
||||||
if level.is_important() {
|
level.is_important()
|
||||||
result.insert(IMPORTANT_RULES_CHANGED);
|
},
|
||||||
} else {
|
None => false,
|
||||||
result.insert(NORMAL_RULES_CHANGED);
|
}
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
if !context.shared.traversal_flags.for_animation_only() {
|
||||||
|
let mut result = false;
|
||||||
|
if replacements.contains(RESTYLE_STYLE_ATTRIBUTE) {
|
||||||
|
let style_attribute = self.style_attribute();
|
||||||
|
result |= replace_rule_node(CascadeLevel::StyleAttributeNormal,
|
||||||
|
style_attribute,
|
||||||
|
primary_rules);
|
||||||
|
result |= replace_rule_node(CascadeLevel::StyleAttributeImportant,
|
||||||
|
style_attribute,
|
||||||
|
primary_rules);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Animation restyle hints are processed prior to other restyle
|
||||||
|
// hints in the animation-only traversal.
|
||||||
|
//
|
||||||
|
// Non-animation restyle hints will be processed in a subsequent
|
||||||
|
// normal traversal.
|
||||||
|
if replacements.intersects(RestyleReplacements::for_animations()) {
|
||||||
|
debug_assert!(context.shared.traversal_flags.for_animation_only());
|
||||||
|
|
||||||
|
if replacements.contains(RESTYLE_SMIL) {
|
||||||
|
replace_rule_node(CascadeLevel::SMILOverride,
|
||||||
|
self.get_smil_override(),
|
||||||
|
primary_rules);
|
||||||
|
}
|
||||||
|
|
||||||
|
let replace_rule_node_for_animation = |level: CascadeLevel,
|
||||||
|
primary_rules: &mut StrongRuleNode| {
|
||||||
|
let animation_rule = self.get_animation_rule_by_cascade(level);
|
||||||
|
replace_rule_node(level,
|
||||||
|
animation_rule.as_ref(),
|
||||||
|
primary_rules);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Animation restyle hints are processed prior to other restyle
|
// Apply Transition rules and Animation rules if the corresponding restyle hint
|
||||||
// hints in the animation-only traversal.
|
// is contained.
|
||||||
//
|
if replacements.contains(RESTYLE_CSS_TRANSITIONS) {
|
||||||
// Non-animation restyle hints will be processed in a subsequent
|
replace_rule_node_for_animation(CascadeLevel::Transitions,
|
||||||
// normal traversal.
|
primary_rules);
|
||||||
if replacements.intersects(RestyleReplacements::for_animations()) {
|
}
|
||||||
debug_assert!(context.shared.traversal_flags.for_animation_only());
|
|
||||||
|
|
||||||
if replacements.contains(RESTYLE_SMIL) {
|
if replacements.contains(RESTYLE_CSS_ANIMATIONS) {
|
||||||
replace_rule_node(CascadeLevel::SMILOverride,
|
replace_rule_node_for_animation(CascadeLevel::Animations,
|
||||||
self.get_smil_override(),
|
primary_rules);
|
||||||
primary_rules);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut replace_rule_node_for_animation = |level: CascadeLevel,
|
|
||||||
primary_rules: &mut StrongRuleNode| {
|
|
||||||
let animation_rule = self.get_animation_rule_by_cascade(level);
|
|
||||||
replace_rule_node(level,
|
|
||||||
animation_rule.as_ref(),
|
|
||||||
primary_rules);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Apply Transition rules and Animation rules if the corresponding restyle hint
|
|
||||||
// is contained.
|
|
||||||
if replacements.contains(RESTYLE_CSS_TRANSITIONS) {
|
|
||||||
replace_rule_node_for_animation(CascadeLevel::Transitions,
|
|
||||||
primary_rules);
|
|
||||||
}
|
|
||||||
|
|
||||||
if replacements.contains(RESTYLE_CSS_ANIMATIONS) {
|
|
||||||
replace_rule_node_for_animation(CascadeLevel::Animations,
|
|
||||||
primary_rules);
|
|
||||||
}
|
|
||||||
} else if replacements.contains(RESTYLE_STYLE_ATTRIBUTE) {
|
|
||||||
let style_attribute = self.style_attribute();
|
|
||||||
replace_rule_node(CascadeLevel::StyleAttributeNormal,
|
|
||||||
style_attribute,
|
|
||||||
primary_rules);
|
|
||||||
replace_rule_node(CascadeLevel::StyleAttributeImportant,
|
|
||||||
style_attribute,
|
|
||||||
primary_rules);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to share a style with another node. This method is unsafe
|
/// Attempts to share a style with another node. This method is unsafe
|
||||||
|
|
|
@ -11,6 +11,7 @@ use cssparser::{DeclarationListParser, parse_important};
|
||||||
use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter};
|
use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter};
|
||||||
use error_reporting::ParseErrorReporter;
|
use error_reporting::ParseErrorReporter;
|
||||||
use parser::{PARSING_MODE_DEFAULT, ParsingMode, ParserContext, log_css_error};
|
use parser::{PARSING_MODE_DEFAULT, ParsingMode, ParserContext, log_css_error};
|
||||||
|
use shared_lock::Locked;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::slice::Iter;
|
use std::slice::Iter;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
|
@ -18,6 +19,20 @@ use stylesheets::{CssRuleType, Origin, UrlExtraData};
|
||||||
use super::*;
|
use super::*;
|
||||||
#[cfg(feature = "gecko")] use properties::animated_properties::AnimationValueMap;
|
#[cfg(feature = "gecko")] use properties::animated_properties::AnimationValueMap;
|
||||||
|
|
||||||
|
/// The animation rules.
|
||||||
|
///
|
||||||
|
/// The first one is for Animation cascade level, and the second one is for
|
||||||
|
/// Transition cascade level.
|
||||||
|
pub struct AnimationRules<'a>(pub Option<&'a Arc<Locked<PropertyDeclarationBlock>>>,
|
||||||
|
pub Option<&'a Arc<Locked<PropertyDeclarationBlock>>>);
|
||||||
|
|
||||||
|
impl<'a> AnimationRules<'a> {
|
||||||
|
/// Returns whether these animation rules represents an actual rule or not.
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.0.is_none() && self.1.is_none()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A declaration [importance][importance].
|
/// A declaration [importance][importance].
|
||||||
///
|
///
|
||||||
/// [importance]: https://drafts.csswg.org/css-cascade/#importance
|
/// [importance]: https://drafts.csswg.org/css-cascade/#importance
|
||||||
|
|
|
@ -753,6 +753,7 @@ impl <T> Animatable for Option<T>
|
||||||
(&Some(ref this), &Some(ref other)) => {
|
(&Some(ref this), &Some(ref other)) => {
|
||||||
Ok(this.add_weighted(other, self_portion, other_portion).ok())
|
Ok(this.add_weighted(other, self_portion, other_portion).ok())
|
||||||
}
|
}
|
||||||
|
(&None, &None) => Ok(None),
|
||||||
_ => Err(()),
|
_ => Err(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -763,6 +764,7 @@ impl <T> Animatable for Option<T>
|
||||||
(&Some(ref this), &Some(ref other)) => {
|
(&Some(ref this), &Some(ref other)) => {
|
||||||
this.compute_distance(other)
|
this.compute_distance(other)
|
||||||
},
|
},
|
||||||
|
(&None, &None) => Ok(0.0),
|
||||||
_ => Err(()),
|
_ => Err(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -464,12 +464,13 @@ ${helpers.single_keyword_system("font-variant-caps",
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Obtain a Servo computed value from a Gecko computed font-weight
|
/// Obtain a Servo computed value from a Gecko computed font-weight
|
||||||
pub unsafe fn from_gecko_weight(weight: u16) -> Self {
|
pub fn from_gecko_weight(weight: u16) -> Self {
|
||||||
use std::mem::transmute;
|
match weight {
|
||||||
debug_assert!(weight >= 100);
|
% for weight in range(100, 901, 100):
|
||||||
debug_assert!(weight <= 900);
|
${weight} => T::Weight${weight},
|
||||||
debug_assert!(weight % 10 == 0);
|
% endfor
|
||||||
transmute(weight)
|
_ => panic!("from_gecko_weight: called with invalid weight")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2362,9 +2363,7 @@ ${helpers.single_keyword("-moz-math-variant",
|
||||||
quoted: true
|
quoted: true
|
||||||
})
|
})
|
||||||
}).collect::<Vec<_>>();
|
}).collect::<Vec<_>>();
|
||||||
let weight = unsafe {
|
let weight = longhands::font_weight::computed_value::T::from_gecko_weight(system.weight);
|
||||||
longhands::font_weight::computed_value::T::from_gecko_weight(system.weight)
|
|
||||||
};
|
|
||||||
let ret = ComputedSystemFont {
|
let ret = ComputedSystemFont {
|
||||||
font_family: longhands::font_family::computed_value::T(family),
|
font_family: longhands::font_family::computed_value::T(family),
|
||||||
font_size: Au(system.size),
|
font_size: Au(system.size),
|
||||||
|
|
|
@ -39,17 +39,20 @@
|
||||||
let mut background_${name} = background_${name}::SpecifiedValue(Vec::new());
|
let mut background_${name} = background_${name}::SpecifiedValue(Vec::new());
|
||||||
% endfor
|
% endfor
|
||||||
try!(input.parse_comma_separated(|input| {
|
try!(input.parse_comma_separated(|input| {
|
||||||
|
// background-color can only be in the last element, so if it
|
||||||
|
// is parsed anywhere before, the value is invalid.
|
||||||
|
if background_color.is_some() {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
% for name in "image position repeat size attachment origin clip".split():
|
% for name in "image position repeat size attachment origin clip".split():
|
||||||
let mut ${name} = None;
|
let mut ${name} = None;
|
||||||
% endfor
|
% endfor
|
||||||
loop {
|
loop {
|
||||||
if let Ok(value) = input.try(|i| CSSColor::parse(context, i)) {
|
if background_color.is_none() {
|
||||||
if background_color.is_none() {
|
if let Ok(value) = input.try(|i| CSSColor::parse(context, i)) {
|
||||||
background_color = Some(value);
|
background_color = Some(value);
|
||||||
continue
|
continue
|
||||||
} else {
|
|
||||||
// color can only be the last element
|
|
||||||
return Err(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if position.is_none() {
|
if position.is_none() {
|
||||||
|
@ -69,6 +72,13 @@
|
||||||
if ${name}.is_none() {
|
if ${name}.is_none() {
|
||||||
if let Ok(value) = input.try(|input| background_${name}::single_value
|
if let Ok(value) = input.try(|input| background_${name}::single_value
|
||||||
::parse(context, input)) {
|
::parse(context, input)) {
|
||||||
|
% if name == "clip" and product == "gecko":
|
||||||
|
// "text" value of background-clip should not be part of background
|
||||||
|
// shorthand per current spec and impls.
|
||||||
|
if value == background_clip::single_value::SpecifiedValue::text {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
% endif
|
||||||
${name} = Some(value);
|
${name} = Some(value);
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
use heapsize::HeapSizeOf;
|
use heapsize::HeapSizeOf;
|
||||||
use properties::{Importance, LonghandIdSet, PropertyDeclarationBlock};
|
use properties::{AnimationRules, Importance, LonghandIdSet, PropertyDeclarationBlock};
|
||||||
use shared_lock::{Locked, StylesheetGuards, SharedRwLockReadGuard};
|
use shared_lock::{Locked, StylesheetGuards, SharedRwLockReadGuard};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
@ -1142,6 +1142,56 @@ impl StrongRuleNode {
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns PropertyDeclarationBlock for this node.
|
||||||
|
/// This function must be called only for animation level node.
|
||||||
|
fn get_animation_style(&self) -> &Arc<Locked<PropertyDeclarationBlock>> {
|
||||||
|
debug_assert!(self.cascade_level().is_animation(),
|
||||||
|
"The cascade level should be an animation level");
|
||||||
|
match *self.style_source().unwrap() {
|
||||||
|
StyleSource::Declarations(ref block) => block,
|
||||||
|
StyleSource::Style(_) => unreachable!("animating style should not be a style rule"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns SMIL override declaration block if exists.
|
||||||
|
pub fn get_smil_animation_rule(&self) -> Option<&Arc<Locked<PropertyDeclarationBlock>>> {
|
||||||
|
if cfg!(feature = "servo") {
|
||||||
|
// Servo has no knowledge of a SMIL rule, so just avoid looking for it.
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.self_and_ancestors()
|
||||||
|
.take_while(|node| node.cascade_level() >= CascadeLevel::SMILOverride)
|
||||||
|
.find(|node| node.cascade_level() == CascadeLevel::SMILOverride)
|
||||||
|
.map(|node| node.get_animation_style())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns AnimationRules that has processed during animation-only restyles.
|
||||||
|
pub fn get_animation_rules(&self) -> AnimationRules {
|
||||||
|
if cfg!(feature = "servo") {
|
||||||
|
return AnimationRules(None, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut animation = None;
|
||||||
|
let mut transition = None;
|
||||||
|
|
||||||
|
for node in self.self_and_ancestors()
|
||||||
|
.take_while(|node| node.cascade_level() >= CascadeLevel::Animations) {
|
||||||
|
match node.cascade_level() {
|
||||||
|
CascadeLevel::Animations => {
|
||||||
|
debug_assert!(animation.is_none());
|
||||||
|
animation = Some(node.get_animation_style())
|
||||||
|
},
|
||||||
|
CascadeLevel::Transitions => {
|
||||||
|
debug_assert!(transition.is_none());
|
||||||
|
transition = Some(node.get_animation_style())
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AnimationRules(animation, transition)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An iterator over a rule node and its ancestors.
|
/// An iterator over a rule node and its ancestors.
|
||||||
|
|
|
@ -152,6 +152,12 @@ impl PseudoElement {
|
||||||
PseudoElement::ServoInlineAbsolute => PseudoElementCascadeType::Precomputed,
|
PseudoElement::ServoInlineAbsolute => PseudoElementCascadeType::Precomputed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Covert non-canonical pseudo-element to canonical one, and keep a
|
||||||
|
/// canonical one as it is.
|
||||||
|
pub fn canonical(&self) -> PseudoElement {
|
||||||
|
self.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A non tree-structural pseudo-class.
|
/// A non tree-structural pseudo-class.
|
||||||
|
|
|
@ -8,7 +8,7 @@ use {Atom, LocalName, Namespace};
|
||||||
use bit_vec::BitVec;
|
use bit_vec::BitVec;
|
||||||
use context::{QuirksMode, SharedStyleContext};
|
use context::{QuirksMode, SharedStyleContext};
|
||||||
use data::ComputedStyle;
|
use data::ComputedStyle;
|
||||||
use dom::{AnimationRules, TElement};
|
use dom::TElement;
|
||||||
use element_state::ElementState;
|
use element_state::ElementState;
|
||||||
use error_reporting::RustLogReporter;
|
use error_reporting::RustLogReporter;
|
||||||
use font_metrics::FontMetricsProvider;
|
use font_metrics::FontMetricsProvider;
|
||||||
|
@ -17,9 +17,9 @@ use gecko_bindings::structs::nsIAtom;
|
||||||
use keyframes::KeyframesAnimation;
|
use keyframes::KeyframesAnimation;
|
||||||
use media_queries::Device;
|
use media_queries::Device;
|
||||||
use properties::{self, CascadeFlags, ComputedValues};
|
use properties::{self, CascadeFlags, ComputedValues};
|
||||||
|
use properties::{AnimationRules, PropertyDeclarationBlock};
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
use properties::INHERIT_ALL;
|
use properties::INHERIT_ALL;
|
||||||
use properties::PropertyDeclarationBlock;
|
|
||||||
use restyle_hints::{HintComputationContext, DependencySet, RestyleHint};
|
use restyle_hints::{HintComputationContext, DependencySet, RestyleHint};
|
||||||
use rule_tree::{CascadeLevel, RuleTree, StrongRuleNode, StyleSource};
|
use rule_tree::{CascadeLevel, RuleTree, StrongRuleNode, StyleSource};
|
||||||
use selector_map::{SelectorMap, SelectorMapEntry};
|
use selector_map::{SelectorMap, SelectorMapEntry};
|
||||||
|
@ -473,7 +473,7 @@ impl Stylist {
|
||||||
{
|
{
|
||||||
let map = if let Some(pseudo) = selector.pseudo_element() {
|
let map = if let Some(pseudo) = selector.pseudo_element() {
|
||||||
self.pseudos_map
|
self.pseudos_map
|
||||||
.entry(pseudo.clone())
|
.entry(pseudo.canonical())
|
||||||
.or_insert_with(PerPseudoElementSelectorMap::new)
|
.or_insert_with(PerPseudoElementSelectorMap::new)
|
||||||
.borrow_for_origin(&stylesheet.origin)
|
.borrow_for_origin(&stylesheet.origin)
|
||||||
} else {
|
} else {
|
||||||
|
@ -665,8 +665,9 @@ impl Stylist {
|
||||||
-> Option<StrongRuleNode>
|
-> Option<StrongRuleNode>
|
||||||
where E: TElement
|
where E: TElement
|
||||||
{
|
{
|
||||||
|
let pseudo = pseudo.canonical();
|
||||||
debug_assert!(pseudo.is_lazy());
|
debug_assert!(pseudo.is_lazy());
|
||||||
if self.pseudos_map.get(pseudo).is_none() {
|
if self.pseudos_map.get(&pseudo).is_none() {
|
||||||
return None
|
return None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -698,7 +699,7 @@ impl Stylist {
|
||||||
let mut matching_context =
|
let mut matching_context =
|
||||||
MatchingContext::new(MatchingMode::ForStatelessPseudoElement, None);
|
MatchingContext::new(MatchingMode::ForStatelessPseudoElement, None);
|
||||||
self.push_applicable_declarations(element,
|
self.push_applicable_declarations(element,
|
||||||
Some(pseudo),
|
Some(&pseudo),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
AnimationRules(None, None),
|
AnimationRules(None, None),
|
||||||
|
@ -943,7 +944,7 @@ impl Stylist {
|
||||||
if let Some(anim) = animation_rules.0 {
|
if let Some(anim) = animation_rules.0 {
|
||||||
Push::push(
|
Push::push(
|
||||||
applicable_declarations,
|
applicable_declarations,
|
||||||
ApplicableDeclarationBlock::from_declarations(anim,
|
ApplicableDeclarationBlock::from_declarations(anim.clone(),
|
||||||
CascadeLevel::Animations));
|
CascadeLevel::Animations));
|
||||||
}
|
}
|
||||||
debug!("animation: {:?}", context.relations);
|
debug!("animation: {:?}", context.relations);
|
||||||
|
@ -961,7 +962,8 @@ impl Stylist {
|
||||||
if let Some(anim) = animation_rules.1 {
|
if let Some(anim) = animation_rules.1 {
|
||||||
Push::push(
|
Push::push(
|
||||||
applicable_declarations,
|
applicable_declarations,
|
||||||
ApplicableDeclarationBlock::from_declarations(anim, CascadeLevel::Transitions));
|
ApplicableDeclarationBlock::from_declarations(anim.clone(),
|
||||||
|
CascadeLevel::Transitions));
|
||||||
}
|
}
|
||||||
debug!("transition: {:?}", context.relations);
|
debug!("transition: {:?}", context.relations);
|
||||||
debug!("push_applicable_declarations: shareable: {:?}", context.relations);
|
debug!("push_applicable_declarations: shareable: {:?}", context.relations);
|
||||||
|
|
|
@ -770,11 +770,11 @@ fn compute_style<E, D>(_traversal: &D,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
CascadeWithReplacements(flags) => {
|
CascadeWithReplacements(flags) => {
|
||||||
let rules_changed = element.replace_rules(flags, context, data);
|
let important_rules_changed = element.replace_rules(flags, context, data);
|
||||||
element.cascade_primary_and_pseudos(
|
element.cascade_primary_and_pseudos(
|
||||||
context,
|
context,
|
||||||
data,
|
data,
|
||||||
rules_changed.important_rules_changed()
|
important_rules_changed
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
CascadeOnly => {
|
CascadeOnly => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue