Skip to content

Commit

Permalink
Pull decls from Gecko for link preshints
Browse files Browse the repository at this point in the history
Based on a link's active state and the visited handling mode, pull in link,
vlink, and alink preshint declaration blocks from Gecko as needed.

MozReview-Commit-ID: A6udMYbzQnK
  • Loading branch information
jryans committed Jun 2, 2017
1 parent fa158a7 commit 56b44d2
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 10 deletions.
10 changes: 7 additions & 3 deletions components/script/layout_wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ use script_layout_interface::{OpaqueStyleAndLayoutData, StyleData};
use script_layout_interface::wrapper_traits::{DangerousThreadSafeLayoutNode, GetLayoutData, LayoutNode};
use script_layout_interface::wrapper_traits::{PseudoElementType, ThreadSafeLayoutElement, ThreadSafeLayoutNode};
use selectors::attr::{AttrSelectorOperation, NamespaceConstraint};
use selectors::matching::{ElementSelectorFlags, MatchingContext, RelevantLinkStatus};
use selectors::matching::{ElementSelectorFlags, MatchingContext, RelevantLinkStatus, VisitedHandlingMode};
use servo_atoms::Atom;
use servo_url::ServoUrl;
use std::fmt;
Expand Down Expand Up @@ -364,7 +364,9 @@ impl<'le> fmt::Debug for ServoLayoutElement<'le> {
}

impl<'le> PresentationalHintsSynthesizer for ServoLayoutElement<'le> {
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, hints: &mut V)
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self,
_visited_handling: VisitedHandlingMode,
hints: &mut V)
where V: Push<ApplicableDeclarationBlock>
{
unsafe {
Expand Down Expand Up @@ -1228,6 +1230,8 @@ impl<'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> {
}

impl<'le> PresentationalHintsSynthesizer for ServoThreadSafeLayoutElement<'le> {
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, _hints: &mut V)
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self,
_visited_handling: VisitedHandlingMode,
_hints: &mut V)
where V: Push<ApplicableDeclarationBlock> {}
}
6 changes: 4 additions & 2 deletions components/style/dom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use properties::{ComputedValues, PropertyDeclarationBlock};
#[cfg(feature = "gecko")] use properties::animated_properties::TransitionProperty;
use rule_tree::CascadeLevel;
use selector_parser::{ElementExt, PreExistingComputedValues, PseudoElement};
use selectors::matching::ElementSelectorFlags;
use selectors::matching::{ElementSelectorFlags, VisitedHandlingMode};
use shared_lock::Locked;
use sink::Push;
use std::fmt;
Expand Down Expand Up @@ -270,7 +270,9 @@ pub unsafe fn raw_note_descendants<E, B>(element: E) -> bool
pub trait PresentationalHintsSynthesizer {
/// Generate the proper applicable declarations due to presentational hints,
/// and insert them into `hints`.
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, hints: &mut V)
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self,
visited_handling: VisitedHandlingMode,
hints: &mut V)
where V: Push<ApplicableDeclarationBlock>;
}

Expand Down
41 changes: 39 additions & 2 deletions components/style/gecko/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,15 @@ use gecko_bindings::bindings::Gecko_ClassOrClassList;
use gecko_bindings::bindings::Gecko_ElementHasAnimations;
use gecko_bindings::bindings::Gecko_ElementHasCSSAnimations;
use gecko_bindings::bindings::Gecko_ElementHasCSSTransitions;
use gecko_bindings::bindings::Gecko_GetActiveLinkAttrDeclarationBlock;
use gecko_bindings::bindings::Gecko_GetAnimationRule;
use gecko_bindings::bindings::Gecko_GetExtraContentStyleDeclarations;
use gecko_bindings::bindings::Gecko_GetHTMLPresentationAttrDeclarationBlock;
use gecko_bindings::bindings::Gecko_GetSMILOverrideDeclarationBlock;
use gecko_bindings::bindings::Gecko_GetStyleAttrDeclarationBlock;
use gecko_bindings::bindings::Gecko_GetStyleContext;
use gecko_bindings::bindings::Gecko_GetUnvisitedLinkAttrDeclarationBlock;
use gecko_bindings::bindings::Gecko_GetVisitedLinkAttrDeclarationBlock;
use gecko_bindings::bindings::Gecko_IsSignificantChild;
use gecko_bindings::bindings::Gecko_MatchStringArgPseudo;
use gecko_bindings::bindings::Gecko_UnsetDirtyStyleAttr;
Expand All @@ -66,7 +69,8 @@ use rule_tree::CascadeLevel as ServoCascadeLevel;
use selector_parser::ElementExt;
use selectors::Element;
use selectors::attr::{AttrSelectorOperation, AttrSelectorOperator, CaseSensitivity, NamespaceConstraint};
use selectors::matching::{ElementSelectorFlags, MatchingContext, MatchingMode, RelevantLinkStatus};
use selectors::matching::{ElementSelectorFlags, MatchingContext, MatchingMode};
use selectors::matching::{RelevantLinkStatus, VisitedHandlingMode};
use shared_lock::Locked;
use sink::Push;
use std::cell::RefCell;
Expand Down Expand Up @@ -1036,7 +1040,9 @@ impl<'le> Hash for GeckoElement<'le> {
}

impl<'le> PresentationalHintsSynthesizer for GeckoElement<'le> {
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, hints: &mut V)
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self,
visited_handling: VisitedHandlingMode,
hints: &mut V)
where V: Push<ApplicableDeclarationBlock>,
{
use properties::longhands::_x_lang::SpecifiedValue as SpecifiedLang;
Expand Down Expand Up @@ -1098,6 +1104,37 @@ impl<'le> PresentationalHintsSynthesizer for GeckoElement<'le> {
);
}

// Support for link, vlink, and alink presentation hints on <body>
if self.is_link() {
// Unvisited vs. visited styles are computed up-front based on the
// visited mode (not the element's actual state).
let declarations = match visited_handling {
VisitedHandlingMode::AllLinksUnvisited => unsafe {
Gecko_GetUnvisitedLinkAttrDeclarationBlock(self.0)
},
VisitedHandlingMode::RelevantLinkVisited => unsafe {
Gecko_GetVisitedLinkAttrDeclarationBlock(self.0)
},
};
let declarations = declarations.and_then(|s| s.as_arc_opt());
if let Some(decl) = declarations {
hints.push(
ApplicableDeclarationBlock::from_declarations(Clone::clone(decl), ServoCascadeLevel::PresHints)
);
}

let active = self.get_state().intersects(NonTSPseudoClass::Active.state_flag());
if active {
let declarations = unsafe { Gecko_GetActiveLinkAttrDeclarationBlock(self.0) };
let declarations = declarations.and_then(|s| s.as_arc_opt());
if let Some(decl) = declarations {
hints.push(
ApplicableDeclarationBlock::from_declarations(Clone::clone(decl), ServoCascadeLevel::PresHints)
);
}
}
}

// xml:lang has precedence over lang, which can be
// set by Gecko_GetHTMLPresentationAttrDeclarationBlock
//
Expand Down
7 changes: 5 additions & 2 deletions components/style/sharing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use dom::{TElement, SendElement};
use matching::{ChildCascadeRequirement, MatchMethods};
use properties::ComputedValues;
use selectors::bloom::BloomFilter;
use selectors::matching::{ElementSelectorFlags, StyleRelations};
use selectors::matching::{ElementSelectorFlags, VisitedHandlingMode, StyleRelations};
use smallvec::SmallVec;
use std::mem;
use std::ops::Deref;
Expand Down Expand Up @@ -66,7 +66,10 @@ impl ValidationData {
{
if self.pres_hints.is_none() {
let mut pres_hints = SmallVec::new();
element.synthesize_presentational_hints_for_legacy_attributes(&mut pres_hints);
element.synthesize_presentational_hints_for_legacy_attributes(
VisitedHandlingMode::AllLinksUnvisited,
&mut pres_hints
);
self.pres_hints = Some(pres_hints);
}
&*self.pres_hints.as_ref().unwrap()
Expand Down
5 changes: 4 additions & 1 deletion components/style/stylist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -959,7 +959,10 @@ impl Stylist {
if pseudo_element.is_none() && !only_default_rules {
// Step 2: Presentational hints.
let length_before_preshints = applicable_declarations.len();
element.synthesize_presentational_hints_for_legacy_attributes(applicable_declarations);
element.synthesize_presentational_hints_for_legacy_attributes(
context.visited_handling,
applicable_declarations
);
if applicable_declarations.len() != length_before_preshints {
if cfg!(debug_assertions) {
for declaration in &applicable_declarations[length_before_preshints..] {
Expand Down

0 comments on commit 56b44d2

Please sign in to comment.