Generate ::before and ::after content from attr() for layout 2020

This commit is contained in:
Fernando Jiménez Moreno 2020-02-20 16:09:40 +01:00
parent bc66948f7c
commit 5b2d6c81b2
5 changed files with 29 additions and 14 deletions

1
Cargo.lock generated
View file

@ -2917,6 +2917,7 @@ dependencies = [
"fnv", "fnv",
"gfx", "gfx",
"gfx_traits", "gfx_traits",
"html5ever",
"ipc-channel", "ipc-channel",
"libc", "libc",
"mitochondria", "mitochondria",

View file

@ -21,6 +21,7 @@ euclid = "0.20"
fnv = "1.0" fnv = "1.0"
gfx = {path = "../gfx"} gfx = {path = "../gfx"}
gfx_traits = {path = "../gfx_traits"} gfx_traits = {path = "../gfx_traits"}
html5ever = "0.25"
ipc-channel = "0.14" ipc-channel = "0.14"
libc = "0.2" libc = "0.2"
msg = {path = "../msg"} msg = {path = "../msg"}

View file

@ -9,8 +9,11 @@ use crate::replaced::ReplacedContent;
use crate::style_ext::{Display, DisplayGeneratingBox, DisplayInside, DisplayOutside}; use crate::style_ext::{Display, DisplayGeneratingBox, DisplayInside, DisplayOutside};
use crate::wrapper::GetRawData; use crate::wrapper::GetRawData;
use atomic_refcell::{AtomicRefCell, AtomicRefMut}; use atomic_refcell::{AtomicRefCell, AtomicRefMut};
use html5ever::LocalName;
use net_traits::image::base::Image as NetImage; use net_traits::image::base::Image as NetImage;
use script_layout_interface::wrapper_traits::{LayoutNode, ThreadSafeLayoutNode}; use script_layout_interface::wrapper_traits::{
LayoutNode, ThreadSafeLayoutElement, ThreadSafeLayoutNode,
};
use servo_arc::Arc as ServoArc; use servo_arc::Arc as ServoArc;
use std::marker::PhantomData as marker; use std::marker::PhantomData as marker;
use std::sync::Arc; use std::sync::Arc;
@ -253,24 +256,23 @@ fn pseudo_element_style<'dom, Node>(
where where
Node: NodeExt<'dom>, Node: NodeExt<'dom>,
{ {
if let Some(pseudo_element) = match which { match which {
WhichPseudoElement::Before => element.to_threadsafe().get_before_pseudo(), WhichPseudoElement::Before => element.to_threadsafe().get_before_pseudo(),
WhichPseudoElement::After => element.to_threadsafe().get_after_pseudo(), WhichPseudoElement::After => element.to_threadsafe().get_after_pseudo(),
} { }
.and_then(|pseudo_element| {
let style = pseudo_element.style(context.shared_context()); let style = pseudo_element.style(context.shared_context());
if style.ineffective_content_property() { if style.ineffective_content_property() {
None None
} else { } else {
Some(style) Some(style)
} }
} else { })
None
}
} }
fn generate_pseudo_element_content<'dom, Node>( fn generate_pseudo_element_content<'dom, Node>(
pseudo_element_style: &ComputedValues, pseudo_element_style: &ComputedValues,
_element: Node, element: Node,
_context: &LayoutContext, _context: &LayoutContext,
) -> Vec<PseudoElementContentItem> ) -> Vec<PseudoElementContentItem>
where where
@ -282,14 +284,25 @@ where
for item in items.iter() { for item in items.iter() {
match item { match item {
ContentItem::String(s) => { ContentItem::String(s) => {
vec.push(PseudoElementContentItem::Text(s.to_string())) vec.push(PseudoElementContentItem::Text(s.to_string()));
}, },
_ => unimplemented!(), ContentItem::Attr(attr) => {
let element = element
.to_threadsafe()
.as_element()
.expect("Expected an element");
let attr_val = element
.get_attr(&attr.namespace_url, &LocalName::from(&*attr.attribute));
vec.push(PseudoElementContentItem::Text(
attr_val.map_or("".to_string(), |s| s.to_string()),
));
},
_ => (),
} }
} }
vec vec
}, },
_ => vec![], Content::Normal | Content::None => unreachable!(),
} }
} }

View file

@ -8,7 +8,7 @@
use crate::computed_values::list_style_type::T as ListStyleType; use crate::computed_values::list_style_type::T as ListStyleType;
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use crate::values::generics::CounterStyle; use crate::values::generics::CounterStyle;
#[cfg(feature = "gecko")] #[cfg(any(feature = "gecko", feature = "servo-layout-2020"))]
use crate::values::specified::Attr; use crate::values::specified::Attr;
use crate::values::CustomIdent; use crate::values::CustomIdent;
use std::ops::Deref; use std::ops::Deref;
@ -212,7 +212,7 @@ pub enum GenericContentItem<ImageUrl> {
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
MozAltContent, MozAltContent,
/// `attr([namespace? `|`]? ident)` /// `attr([namespace? `|`]? ident)`
#[cfg(feature = "gecko")] #[cfg(any(feature = "gecko", feature = "servo-layout-2020"))]
Attr(Attr), Attr(Attr),
/// `url(url)` /// `url(url)`
Url(ImageUrl), Url(ImageUrl),

View file

@ -12,7 +12,7 @@ use crate::values::generics::counters::CounterPair;
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use crate::values::generics::CounterStyle; use crate::values::generics::CounterStyle;
use crate::values::specified::url::SpecifiedImageUrl; use crate::values::specified::url::SpecifiedImageUrl;
#[cfg(feature = "gecko")] #[cfg(any(feature = "gecko", feature = "servo-layout-2020"))]
use crate::values::specified::Attr; use crate::values::specified::Attr;
use crate::values::specified::Integer; use crate::values::specified::Integer;
use crate::values::CustomIdent; use crate::values::CustomIdent;
@ -163,7 +163,7 @@ impl Parse for Content {
let style = Content::parse_counter_style(context, input); let style = Content::parse_counter_style(context, input);
Ok(generics::ContentItem::Counters(name, separator, style)) Ok(generics::ContentItem::Counters(name, separator, style))
}), }),
#[cfg(feature = "gecko")] #[cfg(any(feature = "gecko", feature = "servo-layout-2020"))]
"attr" => input.parse_nested_block(|input| { "attr" => input.parse_nested_block(|input| {
Ok(generics::ContentItem::Attr(Attr::parse_function(context, input)?)) Ok(generics::ContentItem::Attr(Attr::parse_function(context, input)?))
}), }),