Don't match native anonymous content to user/author rules.

This commit is contained in:
Cameron McCormack 2016-11-24 10:18:20 +08:00
parent 210b1be1d0
commit 22b62e0913
5 changed files with 83 additions and 60 deletions

View file

@ -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
}
}

View file

@ -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)
}

View file

@ -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 {

View file

@ -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
}
}

View file

@ -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);
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));
// 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 important: {:?}", relations);
// 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);
} else {
debug!("skipping non-agent rules");
}
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);
// Step 7: User and UA `!important` rules.
map.user.get_all_matching_rules(element,
parent_bf,
applicable_declarations,
&mut relations,
reason,
Importance::Important);
debug!("user important: {:?}", relations);
// Step 8: UA `!important` rules.
map.user_agent.get_all_matching_rules(element,
parent_bf,
applicable_declarations,