diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/servo/content.rs | 24 | ||||
-rw-r--r-- | src/servo/layout/base.rs | 2 | ||||
-rw-r--r-- | src/servo/layout/display_list_builder.rs | 8 | ||||
-rw-r--r-- | src/servo/layout/layout_task.rs | 1 | ||||
-rw-r--r-- | src/servo/layout/style/matching.rs | 38 | ||||
-rw-r--r-- | src/servo/layout/style/style.rs | 57 | ||||
-rw-r--r-- | src/servo/util/color.rs | 1 | ||||
-rw-r--r-- | src/test/small_color_test.css | 1 | ||||
-rw-r--r-- | src/test/small_color_test.html | 1 | ||||
-rw-r--r-- | src/test/test.css | 2 | ||||
-rw-r--r-- | src/test/tiny_test.html | 1 |
11 files changed, 74 insertions, 62 deletions
diff --git a/src/servo/content.rs b/src/servo/content.rs index 0a5e6d9745b..95393939f70 100644 --- a/src/servo/content.rs +++ b/src/servo/content.rs @@ -9,6 +9,9 @@ export content; import dom::base::NodeScope; import dom::rcu::WriterMethods; import dom::style; +import parser::lexer::{spawn_css_lexer_task, spawn_html_parser_task}; +import parser::css_builder::build_stylesheet; +import parser::html_builder::build_dom; import layout::layout_task; import js::rust::methods; @@ -51,26 +54,23 @@ fn content(to_layout: chan<layout_task::Msg>) -> chan<ControlMsg> { // TODO actually parse where the css sheet should be // Replace .html with .css and try to open a stylesheet assert (*filename).ends_with(".html"); - let new_file = (*filename).substr(0u, (*filename).len() - 5u) - + ".css"; + let new_file = (*filename).substr(0u, (*filename).len() - 5u) + ".css"; // Send off a task to parse the stylesheet let css_port = comm::port(); let css_chan = comm::chan(css_port); task::spawn {|| let new_file <- new_file; - let css_stream = parser::lexer:: - spawn_css_lexer_task(~new_file); - let css_rules = parser::css_builder:: - build_stylesheet(css_stream); + let css_stream = spawn_css_lexer_task(~new_file); + let css_rules = build_stylesheet(css_stream); css_chan.send(css_rules); }; // Note: we can parse the next document in parallel // with any previous documents. - let stream = parser::lexer::spawn_html_parser_task(filename); - let root = parser::html_builder::build_dom(scope, stream); - + let stream = spawn_html_parser_task(filename); + let root = build_dom(scope, stream); + // Collect the css stylesheet let css_rules = comm::recv(css_port); @@ -92,8 +92,7 @@ fn content(to_layout: chan<layout_task::Msg>) -> chan<ControlMsg> { } ExecuteMsg(filename) { - #debug["content: Received filename `%s` to execute", - *filename]; + #debug["content: Received filename `%s` to execute", *filename]; alt io::read_whole_file(*filename) { result::err(msg) { @@ -106,8 +105,7 @@ fn content(to_layout: chan<layout_task::Msg>) -> chan<ControlMsg> { cx.new_compartment(js::global::global_class).chain { |compartment| compartment.define_functions(js::global::debug_fns); - cx.evaluate_script(compartment.global_obj, bytes, - *filename, 1u) + cx.evaluate_script(compartment.global_obj, bytes, *filename, 1u) }; } } diff --git a/src/servo/layout/base.rs b/src/servo/layout/base.rs index 2d5f03746a2..cb3a6e881bf 100644 --- a/src/servo/layout/base.rs +++ b/src/servo/layout/base.rs @@ -51,7 +51,7 @@ class Box { } enum layout_data = { - mut computed_style: computed_style, + mut computed_style: ~computed_style, mut box: option<@Box> }; diff --git a/src/servo/layout/display_list_builder.rs b/src/servo/layout/display_list_builder.rs index b2a747793a1..8ae905a45e5 100644 --- a/src/servo/layout/display_list_builder.rs +++ b/src/servo/layout/display_list_builder.rs @@ -55,9 +55,11 @@ fn build_display_list_from_origin(box: @Box, origin: Point2D<au>) #[doc=" Creates a display list item for a single block. -Args: --box: the box to build the display list for --origin: the coordinates of upper-left corner of the passed in box. + +# Arguments + +* `box` - The box to build the display list for +* `origin` - The coordinates of upper-left corner of the passed in box. "] fn box_to_display_items(box: @Box, origin: Point2D<au>) -> [dl::display_item] { diff --git a/src/servo/layout/layout_task.rs b/src/servo/layout/layout_task.rs index 1b0297de9a4..6bb3e92adbb 100644 --- a/src/servo/layout/layout_task.rs +++ b/src/servo/layout/layout_task.rs @@ -35,6 +35,7 @@ fn layout(to_renderer: chan<renderer::Msg>) -> chan<Msg> { #debug("layout: received layout request for:"); node.dump(); + node.initialize_style_for_subtree(); node.recompute_style_for_subtree(styles); let this_box = node.construct_boxes(); diff --git a/src/servo/layout/style/matching.rs b/src/servo/layout/style/matching.rs index 0554319a622..601c11a341e 100644 --- a/src/servo/layout/style/matching.rs +++ b/src/servo/layout/style/matching.rs @@ -10,15 +10,6 @@ import style::{computed_style, default_style_for_node_kind}; export matching_methods; -#[doc="Update the computed style of an HTML element with a style specified by CSS."] -fn update_style(style : @computed_style, decl : style_decl) { - alt decl { - display(dis) { (*style).display = dis; } - background_color(col) { (*style).back_color = col; } - text_color(*) | font_size(*) { /* not supported yet */ } - } -} - #[doc="Check if a CSS attribute matches the attribute of an HTML element."] fn attrs_match(attr: attr, elmt: ElementData) -> bool { alt attr { @@ -170,14 +161,23 @@ impl priv_matching_methods for Node { } } +impl priv_style_methods for Node { + #[doc="Update the computed style of an HTML element with a style specified by CSS."] + fn update_style(decl : style_decl) { + self.aux() { |layout| + alt decl { + display(dis) { layout.computed_style.display = dis; } + background_color(col) { layout.computed_style.back_color = col; } + text_color(*) | font_size(*) { /* not supported yet */ } + } + } + } +} + impl matching_methods for Node { #[doc="Compare an html element to a list of css rules and update its style according to the rules matching it."] - fn match_css_style(styles : stylesheet) -> computed_style { - let node_kind = self.read { |n| copy *n.kind }; - let style = - @default_style_for_node_kind(node_kind); - + fn match_css_style(styles : stylesheet) { // Loop over each rule, see if our node matches what is described in the rule. If it // matches, update its style. As we don't currently have priorities of style information, // the latest rule takes precedence over the others. So we just overwrite style @@ -187,20 +187,18 @@ impl matching_methods for Node { let (selectors, decls) <- *(copy sty); for selectors.each { |sel| if self.matches_selector(sel) { - #debug("Matched selector {%?} with node {%?}", *sel, node_kind); for decls.each { |decl| - update_style(style, decl); + self.update_style(decl); } } } } - - #debug["Changed the style to: %?", *style]; - - ret copy *(style); + + self.aux() { |a| #debug["Changed the style to: %?", copy *a.computed_style]; } } } +#[cfg(test)] mod test { import dom::base::{Attr, Element, HTMLDivElement, HTMLHeadElement, HTMLImageElement}; import dom::base::{NodeScope, TreeReadMethods, TreeWriteMethods, UnknownElement}; diff --git a/src/servo/layout/style/style.rs b/src/servo/layout/style/style.rs index 806b9bdfd4f..7fcf99cc752 100644 --- a/src/servo/layout/style/style.rs +++ b/src/servo/layout/style/style.rs @@ -9,8 +9,7 @@ import matching::matching_methods; import util::color::{Color, rgb}; import util::color::css_colors::{white, black}; -type computed_style = {mut display : display_type, - mut back_color : Color}; +type computed_style = {mut display : display_type, mut back_color : Color}; #[doc="Returns the default style for the given node kind."] fn default_style_for_node_kind(kind: NodeKind) -> computed_style { @@ -34,29 +33,30 @@ fn default_style_for_node_kind(kind: NodeKind) -> computed_style { } impl style_priv for Node { - #[doc=" - Performs CSS selector matching on a node. + #[doc="Set a default auxilliary 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 computed style. - "] - fn recompute_style(styles : stylesheet) { - let style = self.match_css_style(styles); - - #debug("recomputing style; parent node:"); - + auxiliary box in the RCU model) and populates it with the default style. + "] + fn initialize_style() { + let node_kind = self.read { |n| copy *n.kind }; let the_layout_data = @layout_data({ - mut computed_style: style, - mut box: none + mut computed_style : ~default_style_for_node_kind(node_kind), + mut box : none }); - #debug("layout data: %?", the_layout_data); - self.set_aux(the_layout_data); } } impl style_methods for Node { + #[doc="Sequentially initialize the nodes' auxilliary data so they can be updated in parallel."] + fn initialize_style_for_subtree() { + self.initialize_style(); + + for ntree.each_child(self) { |kid| kid.initialize_style_for_subtree(); } + } + #[doc=" Returns the computed style for the given node. If CSS selector matching has not yet been performed, fails. @@ -67,23 +67,30 @@ impl style_methods for Node { if !self.has_aux() { fail "get_computed_style() called on a node without a style!"; } - ret copy self.aux({ |x| copy x }).computed_style; + ret copy *self.aux({ |x| copy x }).computed_style; } #[doc=" Performs CSS selector matching on a subtree. - 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 computed style. - - TODO: compute the style of multiple nodes in parallel. + 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(styles : stylesheet) { - self.recompute_style(styles); - for ntree.each_child(self) { - |kid| - kid.recompute_style_for_subtree(styles); + listen { |ack_chan| + + // TODO: Don't copy this for every element, look into shared, immutable state + let new_styles = copy styles; + + task::spawn { || + self.match_css_style(new_styles); + ack_chan.send(()); + } + + for ntree.each_child(self) { |kid| kid.recompute_style_for_subtree(styles); } + + // Make sure we finish updating the tree before returning + ack_chan.recv(); } } } - diff --git a/src/servo/util/color.rs b/src/servo/util/color.rs index 53cb86f5019..04a0f3ae7ea 100644 --- a/src/servo/util/color.rs +++ b/src/servo/util/color.rs @@ -174,6 +174,7 @@ mod parsing { } } +#[cfg(test)] mod test { import css_colors::*; import parsing::parse_color; diff --git a/src/test/small_color_test.css b/src/test/small_color_test.css new file mode 100644 index 00000000000..014530c86c8 --- /dev/null +++ b/src/test/small_color_test.css @@ -0,0 +1 @@ +img {background-color : red } diff --git a/src/test/small_color_test.html b/src/test/small_color_test.html new file mode 100644 index 00000000000..e78e3375f98 --- /dev/null +++ b/src/test/small_color_test.html @@ -0,0 +1 @@ +<img></img> diff --git a/src/test/test.css b/src/test/test.css index d51ab975148..12e7ad86ad0 100644 --- a/src/test/test.css +++ b/src/test/test.css @@ -4,6 +4,8 @@ p.blue > p.green + p.red { background-color : blue ;color : green } img[class] .pastoral *[lang|=en] { display:inline} .book > #novel + *[type=novella] p { color : blue; color : white } * {background-color : red} +* * {background-color : lime} +* * * {background-color : yellow} * * * * {background-color : white} * * * * * {background-color : rgb(200,0,200)} div div {background-color : green} diff --git a/src/test/tiny_test.html b/src/test/tiny_test.html new file mode 100644 index 00000000000..1a4baf536d7 --- /dev/null +++ b/src/test/tiny_test.html @@ -0,0 +1 @@ + |