mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Clean up aux layout data creation
This commit is contained in:
parent
545acff3a8
commit
b7b3cc8bbb
4 changed files with 67 additions and 65 deletions
|
@ -1,7 +1,9 @@
|
|||
#[doc="High-level interface to CSS selector matching."]
|
||||
|
||||
/**
|
||||
* High-level interface to CSS selector matching.
|
||||
*/
|
||||
use std::arc::{ARC, get, clone};
|
||||
|
||||
use core::dvec::DVec;
|
||||
use css::values::*;
|
||||
use css::values::Stylesheet;
|
||||
use dom::element::{HTMLDivElement, HTMLHeadElement, HTMLImageElement, UnknownElement, HTMLScriptElement};
|
||||
|
@ -39,7 +41,7 @@ impl NodeKind : DefaultStyleMethods {
|
|||
/* TODO: this belongs in the UA stylesheet */
|
||||
fn default_display_type() -> CSSDisplay {
|
||||
match self {
|
||||
Text(*) => { DisplayInline }
|
||||
Text(*) => DisplayInline,
|
||||
Element(element) => {
|
||||
match *element.kind {
|
||||
HTMLDivElement => DisplayBlock,
|
||||
|
@ -80,75 +82,64 @@ fn empty_style_for_node_kind(kind: NodeKind) -> SpecifiedStyle {
|
|||
mut width : Initial}
|
||||
}
|
||||
|
||||
trait StylePriv {
|
||||
fn initialize_style() -> ~[@LayoutData];
|
||||
}
|
||||
|
||||
impl Node : StylePriv {
|
||||
#[doc="
|
||||
Set a default auxiliary data so that other threads can modify it.
|
||||
|
||||
This is, importantly, the function that creates the layout
|
||||
data for the node (the reader-auxiliary box in the RCU model)
|
||||
and populates it with the default style.
|
||||
|
||||
"]
|
||||
// TODO: we should look into folding this into building the dom,
|
||||
// instead of doing a linear sweep afterwards.
|
||||
fn initialize_style() -> ~[@LayoutData] {
|
||||
if !self.has_aux() {
|
||||
let node_kind = self.read(|n| copy *n.kind);
|
||||
let the_layout_data = @LayoutData({
|
||||
mut style : ~empty_style_for_node_kind(node_kind),
|
||||
mut box : None
|
||||
});
|
||||
|
||||
self.set_aux(the_layout_data);
|
||||
|
||||
~[the_layout_data]
|
||||
} else {
|
||||
~[]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait StyleMethods {
|
||||
fn initialize_style_for_subtree() -> ~[@LayoutData];
|
||||
fn initialize_layout_data() -> Option<@LayoutData>;
|
||||
|
||||
fn style() -> SpecifiedStyle;
|
||||
fn initialize_style_for_subtree(ctx: &LayoutContext, refs: &DVec<@LayoutData>);
|
||||
fn recompute_style_for_subtree(ctx: &LayoutContext, styles : ARC<Stylesheet>);
|
||||
}
|
||||
|
||||
impl Node : StyleMethods {
|
||||
#[doc="Sequentially initialize the nodes' auxilliary data so they can be updated in parallel."]
|
||||
fn initialize_style_for_subtree() -> ~[@LayoutData] {
|
||||
let mut handles = self.initialize_style();
|
||||
|
||||
for NodeTree.each_child(self) |kid| {
|
||||
handles += kid.initialize_style_for_subtree();
|
||||
/** If none exists, creates empty layout data for the node (the reader-auxiliary
|
||||
* box in the RCU model) and populates it with an empty style object.
|
||||
*/
|
||||
fn initialize_layout_data() -> Option<@LayoutData> {
|
||||
match self.has_aux() {
|
||||
false => {
|
||||
let node_kind = self.read(|n| copy *n.kind);
|
||||
let data = @LayoutData({
|
||||
mut style : ~empty_style_for_node_kind(node_kind),
|
||||
mut flow : None
|
||||
});
|
||||
self.set_aux(data); Some(data)
|
||||
},
|
||||
true => None
|
||||
}
|
||||
|
||||
return handles;
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Returns the computed style for the given node. If CSS selector matching has not yet been
|
||||
performed, fails.
|
||||
|
||||
TODO: Return a safe reference; don't copy.
|
||||
"]
|
||||
|
||||
/**
|
||||
* Returns the computed style for the given node. If CSS selector
|
||||
* matching has not yet been performed, fails.
|
||||
*/
|
||||
fn style() -> SpecifiedStyle {
|
||||
if !self.has_aux() {
|
||||
fail ~"get_style() called on a node without a style!";
|
||||
}
|
||||
// TODO: return a safe reference; don't copy!
|
||||
return copy *self.aux(|x| copy x).style;
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Performs CSS selector matching on a subtree.
|
||||
/**
|
||||
* Initializes layout data and styles for a Node tree, if any nodes do not have
|
||||
* this data already. Append created layout data to the task's GC roots.
|
||||
*/
|
||||
fn initialize_style_for_subtree(_ctx: &LayoutContext, refs: &DVec<@LayoutData>) {
|
||||
do self.traverse_preorder |n| {
|
||||
match n.initialize_layout_data() {
|
||||
Some(r) => refs.push(r),
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
This is, importantly, the function that updates the layout data for the node (the reader-
|
||||
auxiliary box in the RCU model) with the computed style.
|
||||
"]
|
||||
/**
|
||||
* Performs CSS selector matching on a subtree.
|
||||
|
||||
* This is, importantly, the function that updates the layout data for
|
||||
* the node (the reader-auxiliary box in the RCU model) with the
|
||||
* computed style.
|
||||
*/
|
||||
fn recompute_style_for_subtree(ctx: &LayoutContext, styles : ARC<Stylesheet>) {
|
||||
let mut i = 0u;
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ use js::glue::bindgen::RUST_OBJECT_TO_JSVAL;
|
|||
use js::jsapi::{JSClass, JSObject, JSPropertySpec, JSContext, jsid, jsval, JSBool};
|
||||
use js::rust::{bare_compartment, compartment, methods};
|
||||
use js::{JSPROP_ENUMERATE, JSPROP_SHARED};
|
||||
use layout::base::RenderBox;
|
||||
use layout::base::FlowContext;
|
||||
use layout::debug::DebugMethods;
|
||||
use ptr::null;
|
||||
use std::arc::ARC;
|
||||
|
@ -37,6 +37,18 @@ impl NodeTree : tree::ReadMethods<Node> {
|
|||
}
|
||||
}
|
||||
|
||||
impl Node {
|
||||
fn traverse_preorder(preorder_cb: &fn(Node)) {
|
||||
preorder_cb(self);
|
||||
do NodeTree.each_child(self) |child| { child.traverse_preorder(preorder_cb); true }
|
||||
}
|
||||
|
||||
fn traverse_postorder(postorder_cb: &fn(Node)) {
|
||||
do NodeTree.each_child(self) |child| { child.traverse_postorder(postorder_cb); true }
|
||||
postorder_cb(self);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Node : DebugMethods {
|
||||
/* Dumps the subtree rooted at this node, for debugging. */
|
||||
|
@ -105,7 +117,7 @@ fn define_bindings(compartment: bare_compartment, doc: @Document,
|
|||
Note that there may be multiple boxes per DOM node. */
|
||||
enum LayoutData = {
|
||||
mut style: ~SpecifiedStyle,
|
||||
mut box: Option<@RenderBox>
|
||||
mut flow: Option<@FlowContext>
|
||||
};
|
||||
|
||||
type Node = rcu::Handle<NodeData, LayoutData>;
|
||||
|
@ -151,5 +163,4 @@ impl NodeScope : tree::WriteMethods<Node> {
|
|||
fn with_tree_fields<R>(node: Node, f: fn(tree::Tree<Node>) -> R) -> R {
|
||||
self.write(node, |n| f(n.tree))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
/** Creates CSS boxes from a DOM. */
|
||||
use au = gfx::geometry;
|
||||
use core::dvec::DVec;
|
||||
use css::styles::SpecifiedStyle;
|
||||
use css::styles::{SpecifiedStyle, empty_style_for_node_kind};
|
||||
use css::values::{CSSDisplay, DisplayBlock, DisplayInline, DisplayInlineBlock, DisplayNone};
|
||||
use css::values::{Inherit, Initial, Specified};
|
||||
use dom::element::*;
|
||||
use dom::node::{Comment, Doctype, Element, Text, Node, NodeTree};
|
||||
use dom::node::{Comment, Doctype, Element, Text, Node, NodeTree, LayoutData};
|
||||
use layout::base::{RenderBox, BoxData, GenericBox, ImageBox, TextBox, RenderBoxTree};
|
||||
use layout::base::{FlowContext, FlowContextData, BlockFlow, InlineFlow, InlineBlockFlow, RootFlow, FlowTree};
|
||||
use layout::block::BlockFlowData;
|
||||
|
|
|
@ -10,7 +10,7 @@ use core::dvec::DVec;
|
|||
use css::resolve::apply::apply_style;
|
||||
use css::values::Stylesheet;
|
||||
use dl = gfx::display_list;
|
||||
use dom::node::Node;
|
||||
use dom::node::{Node, LayoutData};
|
||||
use dom::event::{Event, ReflowEvent};
|
||||
use geom::point::Point2D;
|
||||
use geom::rect::Rect;
|
||||
|
@ -41,7 +41,7 @@ fn LayoutTask(render_task: RenderTask, image_cache_task: ImageCacheTask) -> Layo
|
|||
do spawn_listener::<Msg>|request| {
|
||||
|
||||
// This just keeps our dom aux objects alive
|
||||
let mut layout_data_refs = ~[];
|
||||
let layout_data_refs = DVec();
|
||||
let font_cache = FontCache();
|
||||
|
||||
loop {
|
||||
|
@ -65,7 +65,7 @@ fn LayoutTask(render_task: RenderTask, image_cache_task: ImageCacheTask) -> Layo
|
|||
};
|
||||
|
||||
do util::time::time(~"layout") {
|
||||
layout_data_refs += node.initialize_style_for_subtree();
|
||||
node.initialize_style_for_subtree(&layout_ctx, &layout_data_refs);
|
||||
node.recompute_style_for_subtree(&layout_ctx, styles);
|
||||
|
||||
// TODO: this should care about root flow, not root box.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue