mirror of
https://github.com/servo/servo.git
synced 2025-08-07 06:25:32 +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 std::arc::{ARC, get, clone};
|
||||||
|
|
||||||
|
use core::dvec::DVec;
|
||||||
use css::values::*;
|
use css::values::*;
|
||||||
use css::values::Stylesheet;
|
use css::values::Stylesheet;
|
||||||
use dom::element::{HTMLDivElement, HTMLHeadElement, HTMLImageElement, UnknownElement, HTMLScriptElement};
|
use dom::element::{HTMLDivElement, HTMLHeadElement, HTMLImageElement, UnknownElement, HTMLScriptElement};
|
||||||
|
@ -39,7 +41,7 @@ impl NodeKind : DefaultStyleMethods {
|
||||||
/* TODO: this belongs in the UA stylesheet */
|
/* TODO: this belongs in the UA stylesheet */
|
||||||
fn default_display_type() -> CSSDisplay {
|
fn default_display_type() -> CSSDisplay {
|
||||||
match self {
|
match self {
|
||||||
Text(*) => { DisplayInline }
|
Text(*) => DisplayInline,
|
||||||
Element(element) => {
|
Element(element) => {
|
||||||
match *element.kind {
|
match *element.kind {
|
||||||
HTMLDivElement => DisplayBlock,
|
HTMLDivElement => DisplayBlock,
|
||||||
|
@ -80,75 +82,64 @@ fn empty_style_for_node_kind(kind: NodeKind) -> SpecifiedStyle {
|
||||||
mut width : Initial}
|
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 {
|
trait StyleMethods {
|
||||||
fn initialize_style_for_subtree() -> ~[@LayoutData];
|
fn initialize_layout_data() -> Option<@LayoutData>;
|
||||||
|
|
||||||
fn style() -> SpecifiedStyle;
|
fn style() -> SpecifiedStyle;
|
||||||
|
fn initialize_style_for_subtree(ctx: &LayoutContext, refs: &DVec<@LayoutData>);
|
||||||
fn recompute_style_for_subtree(ctx: &LayoutContext, styles : ARC<Stylesheet>);
|
fn recompute_style_for_subtree(ctx: &LayoutContext, styles : ARC<Stylesheet>);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Node : StyleMethods {
|
impl Node : StyleMethods {
|
||||||
#[doc="Sequentially initialize the nodes' auxilliary data so they can be updated in parallel."]
|
/** If none exists, creates empty layout data for the node (the reader-auxiliary
|
||||||
fn initialize_style_for_subtree() -> ~[@LayoutData] {
|
* box in the RCU model) and populates it with an empty style object.
|
||||||
let mut handles = self.initialize_style();
|
*/
|
||||||
|
fn initialize_layout_data() -> Option<@LayoutData> {
|
||||||
for NodeTree.each_child(self) |kid| {
|
match self.has_aux() {
|
||||||
handles += kid.initialize_style_for_subtree();
|
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
|
* Returns the computed style for the given node. If CSS selector
|
||||||
performed, fails.
|
* matching has not yet been performed, fails.
|
||||||
|
*/
|
||||||
TODO: Return a safe reference; don't copy.
|
|
||||||
"]
|
|
||||||
fn style() -> SpecifiedStyle {
|
fn style() -> SpecifiedStyle {
|
||||||
if !self.has_aux() {
|
if !self.has_aux() {
|
||||||
fail ~"get_style() called on a node without a style!";
|
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;
|
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>) {
|
fn recompute_style_for_subtree(ctx: &LayoutContext, styles : ARC<Stylesheet>) {
|
||||||
let mut i = 0u;
|
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::jsapi::{JSClass, JSObject, JSPropertySpec, JSContext, jsid, jsval, JSBool};
|
||||||
use js::rust::{bare_compartment, compartment, methods};
|
use js::rust::{bare_compartment, compartment, methods};
|
||||||
use js::{JSPROP_ENUMERATE, JSPROP_SHARED};
|
use js::{JSPROP_ENUMERATE, JSPROP_SHARED};
|
||||||
use layout::base::RenderBox;
|
use layout::base::FlowContext;
|
||||||
use layout::debug::DebugMethods;
|
use layout::debug::DebugMethods;
|
||||||
use ptr::null;
|
use ptr::null;
|
||||||
use std::arc::ARC;
|
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 {
|
impl Node : DebugMethods {
|
||||||
/* Dumps the subtree rooted at this node, for debugging. */
|
/* 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. */
|
Note that there may be multiple boxes per DOM node. */
|
||||||
enum LayoutData = {
|
enum LayoutData = {
|
||||||
mut style: ~SpecifiedStyle,
|
mut style: ~SpecifiedStyle,
|
||||||
mut box: Option<@RenderBox>
|
mut flow: Option<@FlowContext>
|
||||||
};
|
};
|
||||||
|
|
||||||
type Node = rcu::Handle<NodeData, LayoutData>;
|
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 {
|
fn with_tree_fields<R>(node: Node, f: fn(tree::Tree<Node>) -> R) -> R {
|
||||||
self.write(node, |n| f(n.tree))
|
self.write(node, |n| f(n.tree))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
/** Creates CSS boxes from a DOM. */
|
/** Creates CSS boxes from a DOM. */
|
||||||
use au = gfx::geometry;
|
use au = gfx::geometry;
|
||||||
use core::dvec::DVec;
|
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::{CSSDisplay, DisplayBlock, DisplayInline, DisplayInlineBlock, DisplayNone};
|
||||||
use css::values::{Inherit, Initial, Specified};
|
use css::values::{Inherit, Initial, Specified};
|
||||||
use dom::element::*;
|
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::{RenderBox, BoxData, GenericBox, ImageBox, TextBox, RenderBoxTree};
|
||||||
use layout::base::{FlowContext, FlowContextData, BlockFlow, InlineFlow, InlineBlockFlow, RootFlow, FlowTree};
|
use layout::base::{FlowContext, FlowContextData, BlockFlow, InlineFlow, InlineBlockFlow, RootFlow, FlowTree};
|
||||||
use layout::block::BlockFlowData;
|
use layout::block::BlockFlowData;
|
||||||
|
|
|
@ -10,7 +10,7 @@ use core::dvec::DVec;
|
||||||
use css::resolve::apply::apply_style;
|
use css::resolve::apply::apply_style;
|
||||||
use css::values::Stylesheet;
|
use css::values::Stylesheet;
|
||||||
use dl = gfx::display_list;
|
use dl = gfx::display_list;
|
||||||
use dom::node::Node;
|
use dom::node::{Node, LayoutData};
|
||||||
use dom::event::{Event, ReflowEvent};
|
use dom::event::{Event, ReflowEvent};
|
||||||
use geom::point::Point2D;
|
use geom::point::Point2D;
|
||||||
use geom::rect::Rect;
|
use geom::rect::Rect;
|
||||||
|
@ -41,7 +41,7 @@ fn LayoutTask(render_task: RenderTask, image_cache_task: ImageCacheTask) -> Layo
|
||||||
do spawn_listener::<Msg>|request| {
|
do spawn_listener::<Msg>|request| {
|
||||||
|
|
||||||
// This just keeps our dom aux objects alive
|
// This just keeps our dom aux objects alive
|
||||||
let mut layout_data_refs = ~[];
|
let layout_data_refs = DVec();
|
||||||
let font_cache = FontCache();
|
let font_cache = FontCache();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
@ -65,7 +65,7 @@ fn LayoutTask(render_task: RenderTask, image_cache_task: ImageCacheTask) -> Layo
|
||||||
};
|
};
|
||||||
|
|
||||||
do util::time::time(~"layout") {
|
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);
|
node.recompute_style_for_subtree(&layout_ctx, styles);
|
||||||
|
|
||||||
// TODO: this should care about root flow, not root box.
|
// TODO: this should care about root flow, not root box.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue