format script_layout_interface

This commit is contained in:
Anshul Malik 2018-09-12 12:39:38 +05:30
parent 8c3b192466
commit ae469b016d
3 changed files with 123 additions and 82 deletions

View file

@ -15,13 +15,15 @@ extern crate canvas_traits;
extern crate cssparser; extern crate cssparser;
extern crate euclid; extern crate euclid;
extern crate gfx_traits; extern crate gfx_traits;
#[macro_use] extern crate html5ever; #[macro_use]
extern crate html5ever;
extern crate ipc_channel; extern crate ipc_channel;
extern crate libc; extern crate libc;
#[macro_use] #[macro_use]
extern crate log; extern crate log;
extern crate malloc_size_of; extern crate malloc_size_of;
#[macro_use] extern crate malloc_size_of_derive; #[macro_use]
extern crate malloc_size_of_derive;
extern crate metrics; extern crate metrics;
extern crate msg; extern crate msg;
extern crate net_traits; extern crate net_traits;
@ -98,7 +100,6 @@ impl DomParallelInfo {
} }
} }
#[derive(Clone, Copy, Debug, Eq, PartialEq)] #[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum LayoutNodeType { pub enum LayoutNodeType {
Element(LayoutElementType), Element(LayoutElementType),
@ -126,7 +127,7 @@ pub enum LayoutElementType {
pub enum HTMLCanvasDataSource { pub enum HTMLCanvasDataSource {
WebGL(webrender_api::ImageKey), WebGL(webrender_api::ImageKey),
Image(Option<IpcSender<CanvasMsg>>) Image(Option<IpcSender<CanvasMsg>>),
} }
pub struct HTMLCanvasData { pub struct HTMLCanvasData {
@ -149,7 +150,8 @@ pub struct TrustedNodeAddress(pub *const c_void);
unsafe impl Send for TrustedNodeAddress {} unsafe impl Send for TrustedNodeAddress {}
pub fn is_image_data(uri: &str) -> bool { pub fn is_image_data(uri: &str) -> bool {
static TYPES: &'static [&'static str] = &["data:image/png", "data:image/gif", "data:image/jpeg"]; static TYPES: &'static [&'static str] =
&["data:image/png", "data:image/gif", "data:image/jpeg"];
TYPES.iter().any(|&type_| uri.starts_with(type_)) TYPES.iter().any(|&type_| uri.starts_with(type_))
} }

View file

@ -22,24 +22,28 @@ pub struct CSSErrorReporter {
} }
impl ParseErrorReporter for CSSErrorReporter { impl ParseErrorReporter for CSSErrorReporter {
fn report_error(&self, fn report_error(&self, url: &ServoUrl, location: SourceLocation, error: ContextualParseError) {
url: &ServoUrl,
location: SourceLocation,
error: ContextualParseError) {
if log_enabled!(log::Level::Info) { if log_enabled!(log::Level::Info) {
info!("Url:\t{}\n{}:{} {}", info!(
url.as_str(), "Url:\t{}\n{}:{} {}",
location.line, url.as_str(),
location.column, location.line,
error) location.column,
error
)
} }
//TODO: report a real filename //TODO: report a real filename
let _ = self.script_chan.lock().unwrap().send( let _ = self
ConstellationControlMsg::ReportCSSError(self.pipelineid, .script_chan
"".to_owned(), .lock()
location.line, .unwrap()
location.column, .send(ConstellationControlMsg::ReportCSSError(
error.to_string())); self.pipelineid,
"".to_owned(),
location.line,
location.column,
error.to_string(),
));
} }
} }

View file

@ -63,7 +63,9 @@ impl PseudoElementType {
pub fn style_pseudo_element(&self) -> PseudoElement { pub fn style_pseudo_element(&self) -> PseudoElement {
match *self { match *self {
PseudoElementType::Normal => unreachable!("style_pseudo_element called with PseudoElementType::Normal"), PseudoElementType::Normal => {
unreachable!("style_pseudo_element called with PseudoElementType::Normal")
},
PseudoElementType::Before => PseudoElement::Before, PseudoElementType::Before => PseudoElement::Before,
PseudoElementType::After => PseudoElement::After, PseudoElementType::After => PseudoElement::After,
PseudoElementType::DetailsSummary => PseudoElement::DetailsSummary, PseudoElementType::DetailsSummary => PseudoElement::DetailsSummary,
@ -101,12 +103,17 @@ pub trait LayoutNode: Debug + GetLayoutData + TNode {
} }
} }
pub struct ReverseChildrenIterator<ConcreteNode> where ConcreteNode: LayoutNode { pub struct ReverseChildrenIterator<ConcreteNode>
where
ConcreteNode: LayoutNode,
{
current: Option<ConcreteNode>, current: Option<ConcreteNode>,
} }
impl<ConcreteNode> Iterator for ReverseChildrenIterator<ConcreteNode> impl<ConcreteNode> Iterator for ReverseChildrenIterator<ConcreteNode>
where ConcreteNode: LayoutNode { where
ConcreteNode: LayoutNode,
{
type Item = ConcreteNode; type Item = ConcreteNode;
fn next(&mut self) -> Option<ConcreteNode> { fn next(&mut self) -> Option<ConcreteNode> {
let node = self.current; let node = self.current;
@ -115,17 +122,21 @@ impl<ConcreteNode> Iterator for ReverseChildrenIterator<ConcreteNode>
} }
} }
pub struct TreeIterator<ConcreteNode> where ConcreteNode: LayoutNode { pub struct TreeIterator<ConcreteNode>
where
ConcreteNode: LayoutNode,
{
stack: Vec<ConcreteNode>, stack: Vec<ConcreteNode>,
} }
impl<ConcreteNode> TreeIterator<ConcreteNode> where ConcreteNode: LayoutNode { impl<ConcreteNode> TreeIterator<ConcreteNode>
where
ConcreteNode: LayoutNode,
{
fn new(root: ConcreteNode) -> TreeIterator<ConcreteNode> { fn new(root: ConcreteNode) -> TreeIterator<ConcreteNode> {
let mut stack = vec![]; let mut stack = vec![];
stack.push(root); stack.push(root);
TreeIterator { TreeIterator { stack: stack }
stack: stack,
}
} }
pub fn next_skipping_children(&mut self) -> Option<ConcreteNode> { pub fn next_skipping_children(&mut self) -> Option<ConcreteNode> {
@ -134,7 +145,9 @@ impl<ConcreteNode> TreeIterator<ConcreteNode> where ConcreteNode: LayoutNode {
} }
impl<ConcreteNode> Iterator for TreeIterator<ConcreteNode> impl<ConcreteNode> Iterator for TreeIterator<ConcreteNode>
where ConcreteNode: LayoutNode { where
ConcreteNode: LayoutNode,
{
type Item = ConcreteNode; type Item = ConcreteNode;
fn next(&mut self) -> Option<ConcreteNode> { fn next(&mut self) -> Option<ConcreteNode> {
let ret = self.stack.pop(); let ret = self.stack.pop();
@ -143,16 +156,17 @@ impl<ConcreteNode> Iterator for TreeIterator<ConcreteNode>
} }
} }
/// 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 + Debug + GetLayoutData + NodeInfo + PartialEq + Sized { pub trait ThreadSafeLayoutNode:
Clone + Copy + Debug + GetLayoutData + NodeInfo + PartialEq + Sized
{
type ConcreteNode: LayoutNode<ConcreteThreadSafeLayoutNode = Self>; type ConcreteNode: LayoutNode<ConcreteThreadSafeLayoutNode = Self>;
type ConcreteElement: TElement; type ConcreteElement: TElement;
type ConcreteThreadSafeLayoutElement: type ConcreteThreadSafeLayoutElement: ThreadSafeLayoutElement<
ThreadSafeLayoutElement<ConcreteThreadSafeLayoutNode = Self> ConcreteThreadSafeLayoutNode = Self,
+ ::selectors::Element<Impl=SelectorImpl>; > + ::selectors::Element<Impl = SelectorImpl>;
type ChildrenIterator: Iterator<Item = Self> + Sized; type ChildrenIterator: Iterator<Item = Self> + Sized;
/// Converts self into an `OpaqueNode`. /// Converts self into an `OpaqueNode`.
@ -173,19 +187,27 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + Debug + GetLayoutData + NodeInfo
fn parent_style(&self) -> Arc<ComputedValues>; fn parent_style(&self) -> Arc<ComputedValues>;
fn get_before_pseudo(&self) -> Option<Self> { fn get_before_pseudo(&self) -> Option<Self> {
self.as_element().and_then(|el| el.get_before_pseudo()).map(|el| el.as_node()) self.as_element()
.and_then(|el| el.get_before_pseudo())
.map(|el| el.as_node())
} }
fn get_after_pseudo(&self) -> Option<Self> { fn get_after_pseudo(&self) -> Option<Self> {
self.as_element().and_then(|el| el.get_after_pseudo()).map(|el| el.as_node()) self.as_element()
.and_then(|el| el.get_after_pseudo())
.map(|el| el.as_node())
} }
fn get_details_summary_pseudo(&self) -> Option<Self> { fn get_details_summary_pseudo(&self) -> Option<Self> {
self.as_element().and_then(|el| el.get_details_summary_pseudo()).map(|el| el.as_node()) self.as_element()
.and_then(|el| el.get_details_summary_pseudo())
.map(|el| el.as_node())
} }
fn get_details_content_pseudo(&self) -> Option<Self> { fn get_details_content_pseudo(&self) -> Option<Self> {
self.as_element().and_then(|el| el.get_details_content_pseudo()).map(|el| el.as_node()) self.as_element()
.and_then(|el| el.get_details_content_pseudo())
.map(|el| el.as_node())
} }
fn debug_id(self) -> usize; fn debug_id(self) -> usize;
@ -199,7 +221,8 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + Debug + GetLayoutData + NodeInfo
#[inline] #[inline]
fn get_pseudo_element_type(&self) -> PseudoElementType { fn get_pseudo_element_type(&self) -> PseudoElementType {
self.as_element().map_or(PseudoElementType::Normal, |el| el.get_pseudo_element_type()) self.as_element()
.map_or(PseudoElementType::Normal, |el| el.get_pseudo_element_type())
} }
fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData>; fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData>;
@ -283,13 +306,8 @@ pub trait DangerousThreadSafeLayoutNode: ThreadSafeLayoutNode {
unsafe fn dangerous_next_sibling(&self) -> Option<Self>; unsafe fn dangerous_next_sibling(&self) -> Option<Self>;
} }
pub trait ThreadSafeLayoutElement pub trait ThreadSafeLayoutElement:
: Clone Clone + Copy + Sized + Debug + ::selectors::Element<Impl = SelectorImpl> + GetLayoutData
+ Copy
+ Sized
+ Debug
+ ::selectors::Element<Impl=SelectorImpl>
+ GetLayoutData
{ {
type ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<ConcreteThreadSafeLayoutElement = Self>; type ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<ConcreteThreadSafeLayoutElement = Self>;
@ -329,7 +347,13 @@ pub trait ThreadSafeLayoutElement
#[inline] #[inline]
fn get_before_pseudo(&self) -> Option<Self> { fn get_before_pseudo(&self) -> Option<Self> {
if self.style_data().styles.pseudos.get(&PseudoElement::Before).is_some() { if self
.style_data()
.styles
.pseudos
.get(&PseudoElement::Before)
.is_some()
{
Some(self.with_pseudo(PseudoElementType::Before)) Some(self.with_pseudo(PseudoElementType::Before))
} else { } else {
None None
@ -338,7 +362,13 @@ pub trait ThreadSafeLayoutElement
#[inline] #[inline]
fn get_after_pseudo(&self) -> Option<Self> { fn get_after_pseudo(&self) -> Option<Self> {
if self.style_data().styles.pseudos.get(&PseudoElement::After).is_some() { if self
.style_data()
.styles
.pseudos
.get(&PseudoElement::After)
.is_some()
{
Some(self.with_pseudo(PseudoElementType::After)) Some(self.with_pseudo(PseudoElementType::After))
} else { } else {
None None
@ -347,8 +377,7 @@ pub trait ThreadSafeLayoutElement
#[inline] #[inline]
fn get_details_summary_pseudo(&self) -> Option<Self> { fn get_details_summary_pseudo(&self) -> Option<Self> {
if self.local_name() == &local_name!("details") && if self.local_name() == &local_name!("details") && self.namespace() == &ns!(html) {
self.namespace() == &ns!(html) {
Some(self.with_pseudo(PseudoElementType::DetailsSummary)) Some(self.with_pseudo(PseudoElementType::DetailsSummary))
} else { } else {
None None
@ -358,8 +387,9 @@ pub trait ThreadSafeLayoutElement
#[inline] #[inline]
fn get_details_content_pseudo(&self) -> Option<Self> { fn get_details_content_pseudo(&self) -> Option<Self> {
if self.local_name() == &local_name!("details") && if self.local_name() == &local_name!("details") &&
self.namespace() == &ns!(html) && self.namespace() == &ns!(html) &&
self.get_attr(&ns!(), &local_name!("open")).is_some() { self.get_attr(&ns!(), &local_name!("open")).is_some()
{
Some(self.with_pseudo(PseudoElementType::DetailsContent)) Some(self.with_pseudo(PseudoElementType::DetailsContent))
} else { } else {
None None
@ -374,49 +404,52 @@ pub trait ThreadSafeLayoutElement
fn style(&self, context: &SharedStyleContext) -> Arc<ComputedValues> { fn style(&self, context: &SharedStyleContext) -> Arc<ComputedValues> {
let data = self.style_data(); let data = self.style_data();
match self.get_pseudo_element_type() { match self.get_pseudo_element_type() {
PseudoElementType::Normal => { PseudoElementType::Normal => data.styles.primary().clone(),
data.styles.primary().clone()
},
other => { other => {
// Precompute non-eagerly-cascaded pseudo-element styles if not // Precompute non-eagerly-cascaded pseudo-element styles if not
// cached before. // cached before.
let style_pseudo = other.style_pseudo_element(); let style_pseudo = other.style_pseudo_element();
match style_pseudo.cascade_type() { match style_pseudo.cascade_type() {
// Already computed during the cascade. // Already computed during the cascade.
PseudoElementCascadeType::Eager => { PseudoElementCascadeType::Eager => self
self.style_data() .style_data()
.styles.pseudos.get(&style_pseudo) .styles
.unwrap().clone() .pseudos
}, .get(&style_pseudo)
PseudoElementCascadeType::Precomputed => { .unwrap()
context.stylist.precomputed_values_for_pseudo::<Self::ConcreteElement>( .clone(),
PseudoElementCascadeType::Precomputed => context
.stylist
.precomputed_values_for_pseudo::<Self::ConcreteElement>(
&context.guards, &context.guards,
&style_pseudo, &style_pseudo,
Some(data.styles.primary()), Some(data.styles.primary()),
&ServoMetricsProvider, &ServoMetricsProvider,
) ),
}
PseudoElementCascadeType::Lazy => { PseudoElementCascadeType::Lazy => {
context.stylist.lazily_compute_pseudo_element_style( context
&context.guards, .stylist
unsafe { self.unsafe_get() }, .lazily_compute_pseudo_element_style(
&style_pseudo, &context.guards,
RuleInclusion::All, unsafe { self.unsafe_get() },
data.styles.primary(), &style_pseudo,
/* is_probe = */ false, RuleInclusion::All,
&ServoMetricsProvider, data.styles.primary(),
/* matching_func = */ None, /* is_probe = */ false,
).unwrap() &ServoMetricsProvider,
} /* matching_func = */ None,
).unwrap()
},
} }
} },
} }
} }
#[inline] #[inline]
fn selected_style(&self) -> Arc<ComputedValues> { fn selected_style(&self) -> Arc<ComputedValues> {
let data = self.style_data(); let data = self.style_data();
data.styles.pseudos data.styles
.pseudos
.get(&PseudoElement::Selection) .get(&PseudoElement::Selection)
.unwrap_or(data.styles.primary()) .unwrap_or(data.styles.primary())
.clone() .clone()
@ -433,11 +466,13 @@ pub trait ThreadSafeLayoutElement
fn resolved_style(&self) -> Arc<ComputedValues> { fn resolved_style(&self) -> Arc<ComputedValues> {
let data = self.style_data(); let data = self.style_data();
match self.get_pseudo_element_type() { match self.get_pseudo_element_type() {
PseudoElementType::Normal PseudoElementType::Normal => data.styles.primary().clone(),
=> data.styles.primary().clone(), other => data
other .styles
=> data.styles.pseudos .pseudos
.get(&other.style_pseudo_element()).unwrap().clone(), .get(&other.style_pseudo_element())
.unwrap()
.clone(),
} }
} }
} }