mirror of
https://github.com/servo/servo.git
synced 2025-07-31 11:10:22 +01:00
style: layout: Allow a lazy pseudo-element implementation in Servo.
This commit is contained in:
parent
18c1fee3c7
commit
028f9b6cd2
6 changed files with 172 additions and 57 deletions
|
@ -66,7 +66,7 @@ use std::sync::Arc;
|
||||||
use string_cache::{Atom, Namespace};
|
use string_cache::{Atom, Namespace};
|
||||||
use style::computed_values::content::ContentItem;
|
use style::computed_values::content::ContentItem;
|
||||||
use style::computed_values::{content, display};
|
use style::computed_values::{content, display};
|
||||||
use style::dom::{TDocument, TElement, TNode, UnsafeNode};
|
use style::dom::{PresentationalHintsSynthetizer, TDocument, TElement, TNode, UnsafeNode};
|
||||||
use style::element_state::*;
|
use style::element_state::*;
|
||||||
use style::properties::{ComputedValues, ServoComputedValues};
|
use style::properties::{ComputedValues, ServoComputedValues};
|
||||||
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock};
|
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock};
|
||||||
|
@ -81,7 +81,7 @@ pub type NonOpaqueStyleAndLayoutData = *mut RefCell<PrivateLayoutData>;
|
||||||
/// A wrapper so that layout can access only the methods that it should have access to. Layout must
|
/// A wrapper so that layout can access only the methods that it should have access to. Layout must
|
||||||
/// only ever see these and must never see instances of `LayoutJS`.
|
/// only ever see these and must never see instances of `LayoutJS`.
|
||||||
|
|
||||||
pub trait LayoutNode : TNode {
|
pub trait LayoutNode: TNode {
|
||||||
type ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode;
|
type ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode;
|
||||||
fn to_threadsafe(&self) -> Self::ConcreteThreadSafeLayoutNode;
|
fn to_threadsafe(&self) -> Self::ConcreteThreadSafeLayoutNode;
|
||||||
|
|
||||||
|
@ -401,6 +401,16 @@ pub struct ServoLayoutElement<'le> {
|
||||||
chain: PhantomData<&'le ()>,
|
chain: PhantomData<&'le ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'le> PresentationalHintsSynthetizer for ServoLayoutElement<'le> {
|
||||||
|
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, hints: &mut V)
|
||||||
|
where V: VecLike<DeclarationBlock<Vec<PropertyDeclaration>>>
|
||||||
|
{
|
||||||
|
unsafe {
|
||||||
|
self.element.synthesize_presentational_hints_for_legacy_attributes(hints);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'le> TElement for ServoLayoutElement<'le> {
|
impl<'le> TElement for ServoLayoutElement<'le> {
|
||||||
type ConcreteNode = ServoLayoutNode<'le>;
|
type ConcreteNode = ServoLayoutNode<'le>;
|
||||||
type ConcreteDocument = ServoLayoutDocument<'le>;
|
type ConcreteDocument = ServoLayoutDocument<'le>;
|
||||||
|
@ -419,14 +429,6 @@ impl<'le> TElement for ServoLayoutElement<'le> {
|
||||||
self.element.get_state_for_layout()
|
self.element.get_state_for_layout()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, hints: &mut V)
|
|
||||||
where V: VecLike<DeclarationBlock<Vec<PropertyDeclaration>>>
|
|
||||||
{
|
|
||||||
unsafe {
|
|
||||||
self.element.synthesize_presentational_hints_for_legacy_attributes(hints);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_attr(&self, namespace: &Namespace, name: &Atom) -> Option<&str> {
|
fn get_attr(&self, namespace: &Namespace, name: &Atom) -> Option<&str> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -665,8 +667,10 @@ impl<T> PseudoElementType<T> {
|
||||||
/// A thread-safe version of `LayoutNode`, used during flow construction. This type of layout
|
/// A thread-safe version of `LayoutNode`, used during flow construction. This type of layout
|
||||||
/// node does not allow any parents or siblings of nodes to be accessed, to avoid races.
|
/// node does not allow any parents or siblings of nodes to be accessed, to avoid races.
|
||||||
|
|
||||||
pub trait ThreadSafeLayoutNode : Clone + Copy + Sized + PartialEq {
|
pub trait ThreadSafeLayoutNode: Clone + Copy + Sized + PartialEq {
|
||||||
type ConcreteThreadSafeLayoutElement: ThreadSafeLayoutElement<ConcreteThreadSafeLayoutNode = Self>;
|
type ConcreteThreadSafeLayoutElement:
|
||||||
|
ThreadSafeLayoutElement<ConcreteThreadSafeLayoutNode = Self>
|
||||||
|
+ ::selectors::Element<Impl=ServoSelectorImpl>;
|
||||||
type ChildrenIterator: Iterator<Item = Self> + Sized;
|
type ChildrenIterator: Iterator<Item = Self> + Sized;
|
||||||
|
|
||||||
/// Creates a new `ThreadSafeLayoutNode` for the same `LayoutNode`
|
/// Creates a new `ThreadSafeLayoutNode` for the same `LayoutNode`
|
||||||
|
@ -680,6 +684,18 @@ pub trait ThreadSafeLayoutNode : Clone + Copy + Sized + PartialEq {
|
||||||
/// Returns `None` if this is a pseudo-element; otherwise, returns `Some`.
|
/// Returns `None` if this is a pseudo-element; otherwise, returns `Some`.
|
||||||
fn type_id(&self) -> Option<NodeTypeId>;
|
fn type_id(&self) -> Option<NodeTypeId>;
|
||||||
|
|
||||||
|
/// Returns the type ID of this node, without discarding pseudo-elements as
|
||||||
|
/// `type_id` does.
|
||||||
|
fn type_id_without_excluding_pseudo_elements(&self) -> NodeTypeId;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_element_or_elements_pseudo(&self) -> bool {
|
||||||
|
match self.type_id_without_excluding_pseudo_elements() {
|
||||||
|
NodeTypeId::Element(..) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn debug_id(self) -> usize;
|
fn debug_id(self) -> usize;
|
||||||
|
|
||||||
fn flow_debug_id(self) -> usize;
|
fn flow_debug_id(self) -> usize;
|
||||||
|
@ -791,23 +807,20 @@ pub trait ThreadSafeLayoutNode : Clone + Copy + Sized + PartialEq {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PseudoElementCascadeType::Lazy => {
|
PseudoElementCascadeType::Lazy => {
|
||||||
panic!("Lazy pseudo-elements can't be used in Servo \
|
debug_assert!(self.is_element_or_elements_pseudo());
|
||||||
since accessing the DOM tree during layout \
|
if !self.borrow_layout_data()
|
||||||
could be unsafe.")
|
.unwrap().style_data
|
||||||
// debug_assert!(self.is_element());
|
.per_pseudo.contains_key(&style_pseudo) {
|
||||||
// if !self.borrow_layout_data()
|
let mut data = self.mutate_layout_data().unwrap();
|
||||||
// .unwrap().style_data
|
let new_style =
|
||||||
// .per_pseudo.contains_key(&style_pseudo) {
|
context.stylist
|
||||||
// let mut data = self.mutate_layout_data().unwrap();
|
.lazily_compute_pseudo_element_style(
|
||||||
// let new_style =
|
&self.as_element(),
|
||||||
// context.stylist
|
&style_pseudo,
|
||||||
// .lazily_compute_pseudo_element_style(
|
data.style_data.style.as_ref().unwrap());
|
||||||
// &self.as_element(),
|
data.style_data.per_pseudo
|
||||||
// &style_pseudo,
|
.insert(style_pseudo.clone(), new_style.unwrap());
|
||||||
// data.style_data.style.as_ref().unwrap());
|
}
|
||||||
// data.style_data.per_pseudo
|
|
||||||
// .insert(style_pseudo.clone(), new_style.unwrap())
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -932,12 +945,14 @@ pub trait ThreadSafeLayoutNode : Clone + Copy + Sized + PartialEq {
|
||||||
|
|
||||||
// This trait is only public so that it can be implemented by the gecko wrapper.
|
// This trait is only public so that it can be implemented by the gecko wrapper.
|
||||||
// It can be used to violate thread-safety, so don't use it elsewhere in layout!
|
// It can be used to violate thread-safety, so don't use it elsewhere in layout!
|
||||||
pub trait DangerousThreadSafeLayoutNode : ThreadSafeLayoutNode {
|
pub trait DangerousThreadSafeLayoutNode: ThreadSafeLayoutNode {
|
||||||
unsafe fn dangerous_first_child(&self) -> Option<Self>;
|
unsafe fn dangerous_first_child(&self) -> Option<Self>;
|
||||||
unsafe fn dangerous_next_sibling(&self) -> Option<Self>;
|
unsafe fn dangerous_next_sibling(&self) -> Option<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ThreadSafeLayoutElement: Clone + Copy + Sized {
|
pub trait ThreadSafeLayoutElement: Clone + Copy + Sized +
|
||||||
|
::selectors::Element<Impl=ServoSelectorImpl> +
|
||||||
|
PresentationalHintsSynthetizer {
|
||||||
type ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<ConcreteThreadSafeLayoutElement = Self>;
|
type ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<ConcreteThreadSafeLayoutElement = Self>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1027,6 +1042,11 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> {
|
||||||
Some(self.node.type_id())
|
Some(self.node.type_id())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn type_id_without_excluding_pseudo_elements(&self) -> NodeTypeId {
|
||||||
|
self.node.type_id()
|
||||||
|
}
|
||||||
|
|
||||||
fn debug_id(self) -> usize {
|
fn debug_id(self) -> usize {
|
||||||
self.node.debug_id()
|
self.node.debug_id()
|
||||||
}
|
}
|
||||||
|
@ -1320,3 +1340,101 @@ impl TextContent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl <'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> {
|
||||||
|
type Impl = ServoSelectorImpl;
|
||||||
|
|
||||||
|
fn parent_element(&self) -> Option<Self> {
|
||||||
|
warn!("ServoThreadSafeLayoutElement::parent_element called");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn first_child_element(&self) -> Option<Self> {
|
||||||
|
warn!("ServoThreadSafeLayoutElement::first_child_element called");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skips non-element nodes
|
||||||
|
fn last_child_element(&self) -> Option<Self> {
|
||||||
|
warn!("ServoThreadSafeLayoutElement::last_child_element called");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skips non-element nodes
|
||||||
|
fn prev_sibling_element(&self) -> Option<Self> {
|
||||||
|
warn!("ServoThreadSafeLayoutElement::prev_sibling_element called");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skips non-element nodes
|
||||||
|
fn next_sibling_element(&self) -> Option<Self> {
|
||||||
|
warn!("ServoThreadSafeLayoutElement::next_sibling_element called");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_html_element_in_html_document(&self) -> bool {
|
||||||
|
warn!("ServoThreadSafeLayoutElement::is_html_element_in_html_document called");
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn get_local_name(&self) -> &Atom {
|
||||||
|
ThreadSafeLayoutElement::get_local_name(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn get_namespace(&self) -> &Namespace {
|
||||||
|
ThreadSafeLayoutElement::get_namespace(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn match_non_ts_pseudo_class(&self, _: NonTSPseudoClass) -> bool {
|
||||||
|
// NB: This could maybe be implemented
|
||||||
|
warn!("ServoThreadSafeLayoutElement::match_non_ts_pseudo_class called");
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_id(&self) -> Option<Atom> {
|
||||||
|
warn!("ServoThreadSafeLayoutElement::get_id called");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_class(&self, _name: &Atom) -> bool {
|
||||||
|
warn!("ServoThreadSafeLayoutElement::has_class called");
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn match_attr<F>(&self, attr: &AttrSelector, test: F) -> bool
|
||||||
|
where F: Fn(&str) -> bool {
|
||||||
|
match attr.namespace {
|
||||||
|
NamespaceConstraint::Specific(ref ns) => {
|
||||||
|
self.get_attr(ns, &attr.name).map_or(false, |attr| test(attr))
|
||||||
|
},
|
||||||
|
NamespaceConstraint::Any => {
|
||||||
|
unsafe {
|
||||||
|
self.element.get_attr_vals_for_layout(&attr.name).iter()
|
||||||
|
.any(|attr| test(*attr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_empty(&self) -> bool {
|
||||||
|
warn!("ServoThreadSafeLayoutElement::is_empty called");
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_root(&self) -> bool {
|
||||||
|
warn!("ServoThreadSafeLayoutElement::is_root called");
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn each_class<F>(&self, _callback: F)
|
||||||
|
where F: FnMut(&Atom) {
|
||||||
|
warn!("ServoThreadSafeLayoutElement::each_class called");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'le> PresentationalHintsSynthetizer for ServoThreadSafeLayoutElement<'le> {
|
||||||
|
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, _hints: &mut V)
|
||||||
|
where V: VecLike<DeclarationBlock<Vec<PropertyDeclaration>>> {}
|
||||||
|
}
|
||||||
|
|
|
@ -195,7 +195,12 @@ pub trait TDocument : Sized + Copy + Clone {
|
||||||
fn drain_modified_elements(&self) -> Vec<(Self::ConcreteElement, ElementSnapshot)>;
|
fn drain_modified_elements(&self) -> Vec<(Self::ConcreteElement, ElementSnapshot)>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TElement : Sized + Copy + Clone + ElementExt {
|
pub trait PresentationalHintsSynthetizer {
|
||||||
|
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, hints: &mut V)
|
||||||
|
where V: VecLike<DeclarationBlock<Vec<PropertyDeclaration>>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait TElement : Sized + Copy + Clone + ElementExt + PresentationalHintsSynthetizer {
|
||||||
type ConcreteNode: TNode<ConcreteElement = Self, ConcreteDocument = Self::ConcreteDocument>;
|
type ConcreteNode: TNode<ConcreteElement = Self, ConcreteDocument = Self::ConcreteDocument>;
|
||||||
type ConcreteDocument: TDocument<ConcreteNode = Self::ConcreteNode, ConcreteElement = Self>;
|
type ConcreteDocument: TDocument<ConcreteNode = Self::ConcreteNode, ConcreteElement = Self>;
|
||||||
|
|
||||||
|
@ -205,9 +210,6 @@ pub trait TElement : Sized + Copy + Clone + ElementExt {
|
||||||
|
|
||||||
fn get_state(&self) -> ElementState;
|
fn get_state(&self) -> ElementState;
|
||||||
|
|
||||||
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, &mut V)
|
|
||||||
where V: VecLike<DeclarationBlock<Vec<PropertyDeclaration>>>;
|
|
||||||
|
|
||||||
fn get_attr<'a>(&'a self, namespace: &Namespace, attr: &Atom) -> Option<&'a str>;
|
fn get_attr<'a>(&'a self, namespace: &Namespace, attr: &Atom) -> Option<&'a str>;
|
||||||
fn get_attrs<'a>(&'a self, attr: &Atom) -> Vec<&'a str>;
|
fn get_attrs<'a>(&'a self, attr: &Atom) -> Vec<&'a str>;
|
||||||
|
|
||||||
|
|
|
@ -104,19 +104,11 @@ pub enum PseudoElement {
|
||||||
impl PseudoElement {
|
impl PseudoElement {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn cascade_type(&self) -> PseudoElementCascadeType {
|
pub fn cascade_type(&self) -> PseudoElementCascadeType {
|
||||||
// TODO: Make PseudoElementCascadeType::Lazy work for Servo.
|
|
||||||
//
|
|
||||||
// This can't be done right now since it would require
|
|
||||||
// ServoThreadSafeLayoutElement to implement ::selectors::Element,
|
|
||||||
// and it might not be thread-safe.
|
|
||||||
//
|
|
||||||
// After that, we'd probably want ::selection and
|
|
||||||
// ::-servo-details-summary to be lazy.
|
|
||||||
match *self {
|
match *self {
|
||||||
PseudoElement::Before |
|
PseudoElement::Before |
|
||||||
PseudoElement::After |
|
PseudoElement::After |
|
||||||
PseudoElement::Selection |
|
PseudoElement::Selection => PseudoElementCascadeType::Eager,
|
||||||
PseudoElement::DetailsSummary => PseudoElementCascadeType::Eager,
|
PseudoElement::DetailsSummary => PseudoElementCascadeType::Lazy,
|
||||||
PseudoElement::DetailsContent => PseudoElementCascadeType::Precomputed,
|
PseudoElement::DetailsContent => PseudoElementCascadeType::Precomputed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// For lazy_static
|
// For lazy_static
|
||||||
#![allow(unsafe_code)]
|
#![allow(unsafe_code)]
|
||||||
|
|
||||||
use dom::TElement;
|
use dom::PresentationalHintsSynthetizer;
|
||||||
use element_state::*;
|
use element_state::*;
|
||||||
use error_reporting::{ParseErrorReporter, StdoutErrorReporter};
|
use error_reporting::{ParseErrorReporter, StdoutErrorReporter};
|
||||||
use media_queries::{Device, MediaType};
|
use media_queries::{Device, MediaType};
|
||||||
|
@ -281,7 +281,8 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
|
||||||
pseudo: &Impl::PseudoElement,
|
pseudo: &Impl::PseudoElement,
|
||||||
parent: &Arc<Impl::ComputedValues>)
|
parent: &Arc<Impl::ComputedValues>)
|
||||||
-> Option<Arc<Impl::ComputedValues>>
|
-> Option<Arc<Impl::ComputedValues>>
|
||||||
where E: Element<Impl=Impl> + TElement {
|
where E: Element<Impl=Impl> +
|
||||||
|
PresentationalHintsSynthetizer {
|
||||||
debug_assert!(Impl::pseudo_element_cascade_type(pseudo).is_lazy());
|
debug_assert!(Impl::pseudo_element_cascade_type(pseudo).is_lazy());
|
||||||
if self.pseudos_map.get(pseudo).is_none() {
|
if self.pseudos_map.get(pseudo).is_none() {
|
||||||
return None;
|
return None;
|
||||||
|
@ -358,7 +359,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
|
||||||
pseudo_element: Option<&Impl::PseudoElement>,
|
pseudo_element: Option<&Impl::PseudoElement>,
|
||||||
applicable_declarations: &mut V)
|
applicable_declarations: &mut V)
|
||||||
-> bool
|
-> bool
|
||||||
where E: Element<Impl=Impl> + TElement,
|
where E: Element<Impl=Impl> + PresentationalHintsSynthetizer,
|
||||||
V: VecLike<DeclarationBlock> {
|
V: VecLike<DeclarationBlock> {
|
||||||
assert!(!self.is_device_dirty);
|
assert!(!self.is_device_dirty);
|
||||||
assert!(style_attribute.is_none() || pseudo_element.is_none(),
|
assert!(style_attribute.is_none() || pseudo_element.is_none(),
|
||||||
|
|
|
@ -23,7 +23,6 @@ pub enum PseudoElement {
|
||||||
// TODO: Probably a few more are missing here
|
// TODO: Probably a few more are missing here
|
||||||
|
|
||||||
AnonBox(AnonBoxPseudoElement),
|
AnonBox(AnonBoxPseudoElement),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://mxr.mozilla.org/mozilla-central/source/layout/style/nsCSSAnonBoxList.h
|
// https://mxr.mozilla.org/mozilla-central/source/layout/style/nsCSSAnonBoxList.h
|
||||||
|
@ -262,8 +261,8 @@ impl SelectorImplExt for GeckoSelectorImpl {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn each_pseudo_element<F>(mut fun: F)
|
fn each_pseudo_element<F>(mut fun: F)
|
||||||
where F: FnMut(PseudoElement) {
|
where F: FnMut(PseudoElement) {
|
||||||
use self::PseudoElement::*;
|
|
||||||
use self::AnonBoxPseudoElement::*;
|
use self::AnonBoxPseudoElement::*;
|
||||||
|
use self::PseudoElement::*;
|
||||||
|
|
||||||
fun(Before);
|
fun(Before);
|
||||||
fun(After);
|
fun(After);
|
||||||
|
|
|
@ -32,7 +32,8 @@ use std::slice;
|
||||||
use std::str::from_utf8_unchecked;
|
use std::str::from_utf8_unchecked;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use string_cache::{Atom, Namespace};
|
use string_cache::{Atom, Namespace};
|
||||||
use style::dom::{OpaqueNode, TDocument, TElement, TNode, TRestyleDamage, UnsafeNode};
|
use style::dom::{OpaqueNode, PresentationalHintsSynthetizer};
|
||||||
|
use style::dom::{TDocument, TElement, TNode, TRestyleDamage, UnsafeNode};
|
||||||
use style::element_state::ElementState;
|
use style::element_state::ElementState;
|
||||||
#[allow(unused_imports)] // Used in commented-out code.
|
#[allow(unused_imports)] // Used in commented-out code.
|
||||||
use style::error_reporting::StdoutErrorReporter;
|
use style::error_reporting::StdoutErrorReporter;
|
||||||
|
@ -339,12 +340,6 @@ impl<'le> TElement for GeckoElement<'le> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, _hints: &mut V)
|
|
||||||
where V: VecLike<DeclarationBlock<Vec<PropertyDeclaration>>>
|
|
||||||
{
|
|
||||||
// FIXME(bholley) - Need to implement this.
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_attr<'a>(&'a self, namespace: &Namespace, name: &Atom) -> Option<&'a str> {
|
fn get_attr<'a>(&'a self, namespace: &Namespace, name: &Atom) -> Option<&'a str> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -360,6 +355,14 @@ impl<'le> TElement for GeckoElement<'le> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'le> PresentationalHintsSynthetizer for GeckoElement<'le> {
|
||||||
|
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, _hints: &mut V)
|
||||||
|
where V: VecLike<DeclarationBlock<Vec<PropertyDeclaration>>>
|
||||||
|
{
|
||||||
|
// FIXME(bholley) - Need to implement this.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'le> ::selectors::Element for GeckoElement<'le> {
|
impl<'le> ::selectors::Element for GeckoElement<'le> {
|
||||||
type Impl = GeckoSelectorImpl;
|
type Impl = GeckoSelectorImpl;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue