mirror of
https://github.com/servo/servo.git
synced 2025-08-07 14:35:33 +01:00
Fill in remaining DisplayType values, replace uses, and make box-building return and option'd box since display:none nodes generate no boxes.
This commit is contained in:
parent
2a0761732e
commit
17552aae37
6 changed files with 87 additions and 63 deletions
|
@ -3,8 +3,8 @@
|
||||||
// TODO: fail according to the css spec instead of failing when things
|
// TODO: fail according to the css spec instead of failing when things
|
||||||
// are not as expected
|
// are not as expected
|
||||||
|
|
||||||
use css::values::{DisInline, DisBlock, DisNone, Display, TextColor, BackgroundColor, FontSize,
|
use css::values::{TextColor, BackgroundColor, FontSize, Height, Width,
|
||||||
Height, Width, StyleDeclaration};
|
Display, StyleDeclaration};
|
||||||
// Disambiguate parsed Selector, Rule values from tokens
|
// Disambiguate parsed Selector, Rule values from tokens
|
||||||
use css = css::values;
|
use css = css::values;
|
||||||
use tok = lexer;
|
use tok = lexer;
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
#[doc = "Helper functions to parse values of specific attributes."]
|
#[doc = "Helper functions to parse values of specific attributes."]
|
||||||
|
|
||||||
import css::values::*;
|
use css::values::{DisplayType, Inline, Block, DisplayNone};
|
||||||
import str::{pop_char, from_chars};
|
use css::values::{Unit, Pt, Mm, Px, Percent, Auto};
|
||||||
import float::from_str;
|
use str::{pop_char, from_chars};
|
||||||
import option::map;
|
use float::from_str;
|
||||||
|
use option::map;
|
||||||
|
|
||||||
export parse_font_size;
|
export parse_font_size;
|
||||||
export parse_size;
|
export parse_size;
|
||||||
|
@ -53,9 +54,9 @@ fn parse_size(str : ~str) -> Option<Unit> {
|
||||||
|
|
||||||
fn parse_display_type(str : ~str) -> Option<DisplayType> {
|
fn parse_display_type(str : ~str) -> Option<DisplayType> {
|
||||||
match str {
|
match str {
|
||||||
~"inline" => Some(DisInline),
|
~"inline" => Some(Inline),
|
||||||
~"block" => Some(DisBlock),
|
~"block" => Some(Block),
|
||||||
~"none" => Some(DisNone),
|
~"none" => Some(DisplayNone),
|
||||||
_ => { #debug["Recieved unknown display value '%s'", str]; None }
|
_ => { #debug["Recieved unknown display value '%s'", str]; None }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import std::arc::{ARC, get, clone};
|
import std::arc::{ARC, get, clone};
|
||||||
|
|
||||||
import css::values::{DisplayType, DisBlock, DisInline, DisNone, Unit, Auto};
|
import css::values::{DisplayType, DisplayNone, Inline, Block, Unit, Auto};
|
||||||
import css::values::Stylesheet;
|
import css::values::Stylesheet;
|
||||||
import dom::base::{HTMLDivElement, HTMLHeadElement, HTMLImageElement, UnknownElement, HTMLScriptElement};
|
import dom::base::{HTMLDivElement, HTMLHeadElement, HTMLImageElement, UnknownElement, HTMLScriptElement};
|
||||||
import dom::base::{Comment, Doctype, Element, Node, NodeKind, Text};
|
import dom::base::{Comment, Doctype, Element, Node, NodeKind, Text};
|
||||||
|
@ -37,17 +37,17 @@ impl NodeKind : DefaultStyleMethods {
|
||||||
|
|
||||||
fn default_display_type() -> DisplayType {
|
fn default_display_type() -> DisplayType {
|
||||||
match self {
|
match self {
|
||||||
Text(*) => { DisInline }
|
Text(*) => { Inline }
|
||||||
Element(element) => {
|
Element(element) => {
|
||||||
match *element.kind {
|
match *element.kind {
|
||||||
HTMLDivElement => DisBlock,
|
HTMLDivElement => Block,
|
||||||
HTMLHeadElement => DisNone,
|
HTMLHeadElement => DisplayNone,
|
||||||
HTMLImageElement(*) => DisInline,
|
HTMLImageElement(*) => Inline,
|
||||||
HTMLScriptElement => DisNone,
|
HTMLScriptElement => DisplayNone,
|
||||||
UnknownElement => DisInline,
|
UnknownElement => Inline,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Comment(*) | Doctype(*) => DisNone
|
Comment(*) | Doctype(*) => DisplayNone
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,21 @@ import util::color::Color;
|
||||||
"]
|
"]
|
||||||
|
|
||||||
enum DisplayType {
|
enum DisplayType {
|
||||||
DisBlock,
|
Inline,
|
||||||
DisInline,
|
Block,
|
||||||
DisNone
|
ListItem,
|
||||||
|
InlineBlock,
|
||||||
|
Table,
|
||||||
|
InlineTable,
|
||||||
|
TableRowGroup,
|
||||||
|
TableHeaderGroup,
|
||||||
|
TableFooterGroup,
|
||||||
|
TableRow,
|
||||||
|
TableColumnGroup,
|
||||||
|
TableColumn,
|
||||||
|
TableCell,
|
||||||
|
TableCaption,
|
||||||
|
DisplayNone
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Unit {
|
enum Unit {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#[doc="Creates CSS boxes from a DOM."]
|
#[doc="Creates CSS boxes from a DOM."]
|
||||||
|
|
||||||
import css::values::{DisplayType, DisBlock, DisInline, DisNone};
|
import css::values::{DisplayType, Block, Inline, DisplayNone};
|
||||||
import dom::base::{ElementData, HTMLDivElement, HTMLImageElement, Element, Text, Node};
|
import dom::base::{ElementData, HTMLDivElement, HTMLImageElement, Element, Text, Node};
|
||||||
import gfx::geometry::zero_size_au;
|
import gfx::geometry::zero_size_au;
|
||||||
import layout::base::{Appearance, BTree, BlockBox, Box, BoxKind, InlineBox, IntrinsicBox, NTree};
|
import layout::base::{Appearance, BTree, BlockBox, Box, BoxKind, InlineBox, IntrinsicBox, NTree};
|
||||||
|
@ -43,17 +43,20 @@ impl ctxt {
|
||||||
|
|
||||||
// Create boxes for the child. Get its primary box.
|
// Create boxes for the child. Get its primary box.
|
||||||
let kid_box = kid.construct_boxes();
|
let kid_box = kid.construct_boxes();
|
||||||
|
if (kid_box.is_none()) {
|
||||||
|
again;
|
||||||
|
}
|
||||||
|
|
||||||
// Determine the child's display.
|
// Determine the child's display.
|
||||||
let disp = kid.get_specified_style().display_type;
|
let disp = kid.get_specified_style().display_type;
|
||||||
if disp != Some(DisInline) {
|
if disp != Some(Inline) {
|
||||||
self.finish_anonymous_box_if_necessary();
|
self.finish_anonymous_box_if_necessary();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the child's box to the current enclosing box or the current anonymous box.
|
// Add the child's box to the current enclosing box or the current anonymous box.
|
||||||
match kid.get_specified_style().display_type {
|
match kid.get_specified_style().display_type {
|
||||||
Some(DisBlock) => BTree.add_child(self.parent_box, kid_box),
|
Some(Block) => BTree.add_child(self.parent_box, kid_box.get()),
|
||||||
Some(DisInline) => {
|
Some(Inline) => {
|
||||||
let anon_box = match self.anon_box {
|
let anon_box = match self.anon_box {
|
||||||
None => {
|
None => {
|
||||||
//
|
//
|
||||||
|
@ -70,9 +73,9 @@ impl ctxt {
|
||||||
}
|
}
|
||||||
Some(b) => b
|
Some(b) => b
|
||||||
};
|
};
|
||||||
BTree.add_child(anon_box, kid_box);
|
BTree.add_child(anon_box, kid_box.get());
|
||||||
}
|
}
|
||||||
Some(DisNone) => {
|
Some(DisplayNone) => {
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
}
|
}
|
||||||
_ => { //hack for now
|
_ => { //hack for now
|
||||||
|
@ -93,21 +96,21 @@ impl ctxt {
|
||||||
|
|
||||||
// Determine the child's display.
|
// Determine the child's display.
|
||||||
let disp = kid.get_specified_style().display_type;
|
let disp = kid.get_specified_style().display_type;
|
||||||
if disp != Some(DisInline) {
|
if disp != Some(Inline) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the child's box to the current enclosing box.
|
// Add the child's box to the current enclosing box.
|
||||||
match kid.get_specified_style().display_type {
|
match kid.get_specified_style().display_type {
|
||||||
Some(DisBlock) => {
|
Some(Block) => {
|
||||||
// TODO
|
// TODO
|
||||||
#warn("TODO: non-inline display found inside inline box");
|
#warn("TODO: non-inline display found inside inline box");
|
||||||
BTree.add_child(self.parent_box, kid_box);
|
BTree.add_child(self.parent_box, kid_box.get());
|
||||||
}
|
}
|
||||||
Some(DisInline) => {
|
Some(Inline) => {
|
||||||
BTree.add_child(self.parent_box, kid_box);
|
BTree.add_child(self.parent_box, kid_box.get());
|
||||||
}
|
}
|
||||||
Some(DisNone) => {
|
Some(DisplayNone) => {
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
}
|
}
|
||||||
_ => { //hack for now
|
_ => { //hack for now
|
||||||
|
@ -122,9 +125,9 @@ impl ctxt {
|
||||||
self.parent_node.dump();
|
self.parent_node.dump();
|
||||||
|
|
||||||
match self.parent_node.get_specified_style().display_type {
|
match self.parent_node.get_specified_style().display_type {
|
||||||
Some(DisBlock) => self.construct_boxes_for_block_children(),
|
Some(Block) => self.construct_boxes_for_block_children(),
|
||||||
Some(DisInline) => self.construct_boxes_for_inline_children(),
|
Some(Inline) => self.construct_boxes_for_inline_children(),
|
||||||
Some(DisNone) => { /* Nothing to do. */ }
|
Some(DisplayNone) => { /* Nothing to do. */ }
|
||||||
_ => { //hack for now
|
_ => { //hack for now
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,7 +150,7 @@ impl ctxt {
|
||||||
}
|
}
|
||||||
|
|
||||||
trait PrivBoxBuilder {
|
trait PrivBoxBuilder {
|
||||||
fn determine_box_kind() -> BoxKind;
|
fn determine_box_kind() -> Option<BoxKind>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Node : PrivBoxBuilder {
|
impl Node : PrivBoxBuilder {
|
||||||
|
@ -155,18 +158,16 @@ impl Node : PrivBoxBuilder {
|
||||||
Determines the kind of box that this node needs. Also, for images, computes the intrinsic
|
Determines the kind of box that this node needs. Also, for images, computes the intrinsic
|
||||||
size.
|
size.
|
||||||
"]
|
"]
|
||||||
fn determine_box_kind() -> BoxKind {
|
fn determine_box_kind() -> Option<BoxKind> {
|
||||||
match self.read(|n| copy n.kind) {
|
match self.read(|n| copy n.kind) {
|
||||||
~Text(string) => TextBoxKind(@TextBox(copy string)),
|
~Text(string) => Some(TextBoxKind(@TextBox(copy string))),
|
||||||
~Element(element) => {
|
~Element(element) => {
|
||||||
match (copy *element.kind, self.get_specified_style().display_type) {
|
match (copy *element.kind, self.get_specified_style().display_type) {
|
||||||
(HTMLImageElement({size}), _) => IntrinsicBox(@size),
|
(HTMLImageElement({size}), _) => Some(IntrinsicBox(@size)),
|
||||||
(_, Some(DisBlock)) => BlockBox,
|
(_, Some(Block)) => Some(BlockBox),
|
||||||
(_, Some(DisInline)) => InlineBox,
|
(_, Some(Inline)) => Some(InlineBox),
|
||||||
(_, Some(DisNone)) => {
|
(_, Some(DisplayNone)) => None,
|
||||||
// TODO: don't have a box here at all?
|
(_, Some(_)) => Some(InlineBox),
|
||||||
IntrinsicBox(@zero_size_au())
|
|
||||||
}
|
|
||||||
(_, None) => {
|
(_, None) => {
|
||||||
fail ~"The specified display style should be a default instead of none"
|
fail ~"The specified display style should be a default instead of none"
|
||||||
}
|
}
|
||||||
|
@ -178,24 +179,28 @@ impl Node : PrivBoxBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
trait BoxBuilder {
|
trait BoxBuilder {
|
||||||
fn construct_boxes() -> @Box;
|
fn construct_boxes() -> Option<@Box>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Node : BoxBuilder {
|
impl Node : BoxBuilder {
|
||||||
#[doc="Creates boxes for this node. This is the entry point."]
|
#[doc="Creates boxes for this node. This is the entry point."]
|
||||||
fn construct_boxes() -> @Box {
|
fn construct_boxes() -> Option<@Box> {
|
||||||
let box_kind = self.determine_box_kind();
|
match self.determine_box_kind() {
|
||||||
let my_box = @Box(self, box_kind);
|
None => None,
|
||||||
match box_kind {
|
Some(kind) => {
|
||||||
BlockBox | InlineBox => {
|
let my_box = @Box(self, kind);
|
||||||
let cx = create_context(self, my_box);
|
match kind {
|
||||||
cx.construct_boxes_for_children();
|
BlockBox | InlineBox => {
|
||||||
}
|
let cx = create_context(self, my_box);
|
||||||
_ => {
|
cx.construct_boxes_for_children();
|
||||||
// Nothing to do.
|
}
|
||||||
}
|
_ => {
|
||||||
|
// Nothing to do.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(my_box)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return my_box;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import css::values::Stylesheet;
|
||||||
import gfx::geometry::px_to_au;
|
import gfx::geometry::px_to_au;
|
||||||
import gfx::render_task;
|
import gfx::render_task;
|
||||||
import render_task::RenderTask;
|
import render_task::RenderTask;
|
||||||
|
import layout::base::Box;
|
||||||
import resource::image_cache_task::ImageCacheTask;
|
import resource::image_cache_task::ImageCacheTask;
|
||||||
import std::net::url::Url;
|
import std::net::url::Url;
|
||||||
import css::resolve::apply::apply_style;
|
import css::resolve::apply::apply_style;
|
||||||
|
@ -48,16 +49,21 @@ fn LayoutTask(render_task: RenderTask, image_cache_task: ImageCacheTask) -> Layo
|
||||||
layout_data_refs += node.initialize_style_for_subtree();
|
layout_data_refs += node.initialize_style_for_subtree();
|
||||||
node.recompute_style_for_subtree(styles);
|
node.recompute_style_for_subtree(styles);
|
||||||
|
|
||||||
let this_box = node.construct_boxes();
|
let root_box: @Box;
|
||||||
this_box.dump();
|
match node.construct_boxes() {
|
||||||
|
None => fail ~"Root node should always exist; did it get 'display: none' somehow?",
|
||||||
|
Some(root) => root_box = root
|
||||||
|
}
|
||||||
|
|
||||||
|
root_box.dump();
|
||||||
|
|
||||||
let reflow: fn~() = || event_chan.send(ReflowEvent);
|
let reflow: fn~() = || event_chan.send(ReflowEvent);
|
||||||
|
|
||||||
apply_style(this_box, &doc_url, image_cache_task, reflow);
|
apply_style(root_box, &doc_url, image_cache_task, reflow);
|
||||||
|
|
||||||
this_box.reflow_subtree(px_to_au(800));
|
root_box.reflow_subtree(px_to_au(800));
|
||||||
|
|
||||||
let dlist = build_display_list(this_box);
|
let dlist = build_display_list(root_box);
|
||||||
render_task.send(render_task::RenderMsg(dlist));
|
render_task.send(render_task::RenderMsg(dlist));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue