aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/style/gecko/wrapper.rs6
-rw-r--r--components/style/matching.rs5
-rw-r--r--components/style/selector_parser.rs2
-rw-r--r--components/style/servo/selector_parser.rs5
-rw-r--r--components/style/stylist.rs119
5 files changed, 80 insertions, 57 deletions
diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs
index 36712a99be6..3d178a5ab89 100644
--- a/components/style/gecko/wrapper.rs
+++ b/components/style/gecko/wrapper.rs
@@ -28,6 +28,7 @@ use gecko_bindings::bindings::Gecko_StoreStyleDifference;
use gecko_bindings::structs;
use gecko_bindings::structs::{NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO, NODE_IS_DIRTY_FOR_SERVO};
use gecko_bindings::structs::{nsIAtom, nsIContent, nsStyleContext};
+use gecko_bindings::structs::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE;
use parking_lot::RwLock;
use parser::ParserContextExtraData;
use properties::{ComputedValues, parse_style_attribute};
@@ -624,4 +625,9 @@ impl<'le> ElementExt for GeckoElement<'le> {
fn is_link(&self) -> bool {
self.match_non_ts_pseudo_class(NonTSPseudoClass::AnyLink)
}
+
+ #[inline]
+ fn matches_user_and_author_rules(&self) -> bool {
+ self.flags() & (NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE as u32) == 0
+ }
}
diff --git a/components/style/matching.rs b/components/style/matching.rs
index f4ed47e64d6..442e2c3fffa 100644
--- a/components/style/matching.rs
+++ b/components/style/matching.rs
@@ -106,6 +106,7 @@ pub enum CacheMiss {
LocalName,
Namespace,
Link,
+ UserAndAuthorRules,
State,
IdAttr,
StyleAttr,
@@ -143,6 +144,10 @@ fn element_matches_candidate<E: TElement>(element: &E,
miss!(Link)
}
+ if element.matches_user_and_author_rules() != candidate_element.matches_user_and_author_rules() {
+ miss!(UserAndAuthorRules)
+ }
+
if element.get_state() != candidate_element.get_state() {
miss!(State)
}
diff --git a/components/style/selector_parser.rs b/components/style/selector_parser.rs
index 98dc5a3e57d..1c281439256 100644
--- a/components/style/selector_parser.rs
+++ b/components/style/selector_parser.rs
@@ -101,6 +101,8 @@ impl PseudoElementCascadeType {
pub trait ElementExt: Element<Impl=SelectorImpl> {
fn is_link(&self) -> bool;
+
+ fn matches_user_and_author_rules(&self) -> bool;
}
impl SelectorImpl {
diff --git a/components/style/servo/selector_parser.rs b/components/style/servo/selector_parser.rs
index 493710debfb..8dc844456bd 100644
--- a/components/style/servo/selector_parser.rs
+++ b/components/style/servo/selector_parser.rs
@@ -398,4 +398,9 @@ impl<E: Element<Impl=SelectorImpl>> ElementExt for E {
fn is_link(&self) -> bool {
self.match_non_ts_pseudo_class(NonTSPseudoClass::AnyLink)
}
+
+ #[inline]
+ fn matches_user_and_author_rules(&self) -> bool {
+ true
+ }
}
diff --git a/components/style/stylist.rs b/components/style/stylist.rs
index 294b1b4cece..2f756717869 100644
--- a/components/style/stylist.rs
+++ b/components/style/stylist.rs
@@ -330,9 +330,9 @@ impl Stylist {
pseudo: &PseudoElement,
parent: &Arc<ComputedValues>)
-> Option<(Arc<ComputedValues>, StrongRuleNode)>
- where E: Element<Impl=SelectorImpl> +
- fmt::Debug +
- PresentationalHintsSynthetizer
+ where E: ElementExt +
+ fmt::Debug +
+ PresentationalHintsSynthetizer
{
debug_assert!(SelectorImpl::pseudo_element_cascade_type(pseudo).is_lazy());
if self.pseudos_map.get(pseudo).is_none() {
@@ -418,7 +418,7 @@ impl Stylist {
pseudo_element: Option<&PseudoElement>,
applicable_declarations: &mut V,
reason: MatchingReason) -> StyleRelations
- where E: Element<Impl=SelectorImpl> +
+ where E: ElementExt +
fmt::Debug +
PresentationalHintsSynthetizer,
V: Push<ApplicableDeclarationBlock> + VecLike<ApplicableDeclarationBlock>
@@ -456,66 +456,71 @@ impl Stylist {
}
debug!("preshints: {:?}", relations);
- // Step 3: User and author normal rules.
- map.user.get_all_matching_rules(element,
- parent_bf,
- applicable_declarations,
- &mut relations,
- reason,
- Importance::Normal);
- debug!("user normal: {:?}", relations);
- map.author.get_all_matching_rules(element,
- parent_bf,
- applicable_declarations,
- &mut relations,
- reason,
- Importance::Normal);
- debug!("author normal: {:?}", relations);
-
- // Step 4: Normal style attributes.
- if let Some(sa) = style_attribute {
- if sa.read().any_normal() {
- relations |= AFFECTED_BY_STYLE_ATTRIBUTE;
- Push::push(
- applicable_declarations,
- ApplicableDeclarationBlock::from_declarations(sa.clone(), Importance::Normal));
+ if element.matches_user_and_author_rules() {
+ // Step 3: User and author normal rules.
+ map.user.get_all_matching_rules(element,
+ parent_bf,
+ applicable_declarations,
+ &mut relations,
+ reason,
+ Importance::Normal);
+ debug!("user normal: {:?}", relations);
+ map.author.get_all_matching_rules(element,
+ parent_bf,
+ applicable_declarations,
+ &mut relations,
+ reason,
+ Importance::Normal);
+ debug!("author normal: {:?}", relations);
+
+ // Step 4: Normal style attributes.
+ if let Some(sa) = style_attribute {
+ if sa.read().any_normal() {
+ relations |= AFFECTED_BY_STYLE_ATTRIBUTE;
+ Push::push(
+ applicable_declarations,
+ ApplicableDeclarationBlock::from_declarations(sa.clone(), Importance::Normal));
+ }
}
- }
- debug!("style attr: {:?}", relations);
-
- // Step 5: Author-supplied `!important` rules.
- map.author.get_all_matching_rules(element,
- parent_bf,
- applicable_declarations,
- &mut relations,
- reason,
- Importance::Important);
-
- debug!("author important: {:?}", relations);
-
- // Step 6: `!important` style attributes.
- if let Some(sa) = style_attribute {
- if sa.read().any_important() {
- relations |= AFFECTED_BY_STYLE_ATTRIBUTE;
- Push::push(
- applicable_declarations,
- ApplicableDeclarationBlock::from_declarations(sa.clone(), Importance::Important));
+ debug!("style attr: {:?}", relations);
+
+ // Step 5: Author-supplied `!important` rules.
+ map.author.get_all_matching_rules(element,
+ parent_bf,
+ applicable_declarations,
+ &mut relations,
+ reason,
+ Importance::Important);
+
+ debug!("author important: {:?}", relations);
+
+ // Step 6: `!important` style attributes.
+ if let Some(sa) = style_attribute {
+ if sa.read().any_important() {
+ relations |= AFFECTED_BY_STYLE_ATTRIBUTE;
+ Push::push(
+ applicable_declarations,
+ ApplicableDeclarationBlock::from_declarations(sa.clone(), Importance::Important));
+ }
}
- }
- debug!("style attr important: {:?}", relations);
+ debug!("style attr important: {:?}", relations);
- // Step 7: User and UA `!important` rules.
- map.user.get_all_matching_rules(element,
- parent_bf,
- applicable_declarations,
- &mut relations,
- reason,
- Importance::Important);
+ // Step 7: User `!important` rules.
+ map.user.get_all_matching_rules(element,
+ parent_bf,
+ applicable_declarations,
+ &mut relations,
+ reason,
+ Importance::Important);
- debug!("user important: {:?}", relations);
+ debug!("user important: {:?}", relations);
+ } else {
+ debug!("skipping non-agent rules");
+ }
+ // Step 8: UA `!important` rules.
map.user_agent.get_all_matching_rules(element,
parent_bf,
applicable_declarations,