mirror of
https://github.com/servo/servo.git
synced 2025-08-07 14:35:33 +01:00
Inherit CSS styles
This commit is contained in:
parent
cd9e0c020b
commit
25ad384974
8 changed files with 55 additions and 162 deletions
|
@ -1 +1 @@
|
|||
Subproject commit fa72e6b29671d70bd866052e55c930249cd2a3f9
|
||||
Subproject commit 1b5d29808c55b375252668a90ab5255598f0e06d
|
|
@ -1 +1 @@
|
|||
Subproject commit d13bc5f0bcd00c70d83f5902f4dd3e52ba54be7d
|
||||
Subproject commit d5734c425ae0dacb37f116ec3b0b8243d600987a
|
|
@ -1 +1 @@
|
|||
Subproject commit 7d3776335dbd66688d25a7dbe0da5638e9e6702e
|
||||
Subproject commit 6d5b25957f5f6493b3acc6ed326354ad81c91cd1
|
|
@ -4,6 +4,7 @@
|
|||
use std::arc::{ARC, get, clone};
|
||||
use dom::node::{Node, NodeTree};
|
||||
use newcss::select::{SelectCtx, SelectResults};
|
||||
use newcss::complete::CompleteSelectResults;
|
||||
use layout::context::LayoutContext;
|
||||
use select_handler::NodeSelectHandler;
|
||||
|
||||
|
@ -20,20 +21,48 @@ impl Node : MatchMethods {
|
|||
* computed style.
|
||||
*/
|
||||
fn restyle_subtree(select_ctx: &SelectCtx) {
|
||||
let mut i = 0u;
|
||||
|
||||
for NodeTree.each_child(&self) |kid| {
|
||||
i = i + 1u;
|
||||
kid.restyle_subtree(select_ctx);
|
||||
}
|
||||
|
||||
// Only elements have styles
|
||||
if self.is_element() {
|
||||
let select_handler = NodeSelectHandler {
|
||||
node: self
|
||||
};
|
||||
let style = select_ctx.select_style(&self, &select_handler);
|
||||
self.set_css_select_results(move style);
|
||||
let incomplete_results = select_ctx.select_style(&self, &select_handler);
|
||||
// Combine this node's results with its parent's to resolve all inherited values
|
||||
let complete_results = compose_results(&self, move incomplete_results);
|
||||
self.set_css_select_results(move complete_results);
|
||||
}
|
||||
|
||||
let mut i = 0u;
|
||||
|
||||
for NodeTree.each_child(&self) |kid| {
|
||||
i = i + 1u;
|
||||
kid.restyle_subtree(select_ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn compose_results(node: &Node, results: SelectResults) -> CompleteSelectResults {
|
||||
match find_parent_element_node(node) {
|
||||
None => CompleteSelectResults::new_root(move results),
|
||||
Some(parent_node) => {
|
||||
let parent_results = parent_node.get_css_select_results();
|
||||
CompleteSelectResults::new_from_parent(parent_results, move results)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn find_parent_element_node(node: &Node) -> Option<Node> {
|
||||
use util::tree::parent;
|
||||
|
||||
match parent(&NodeTree, node) {
|
||||
Some(ref parent) => {
|
||||
if parent.is_element() {
|
||||
Some(*parent)
|
||||
} else {
|
||||
find_parent_element_node(parent)
|
||||
}
|
||||
}
|
||||
None => None
|
||||
}
|
||||
}
|
|
@ -1,152 +1,15 @@
|
|||
/*!
|
||||
Calculates computed Node styles, based on CSS SelectResults.
|
||||
|
||||
These methods mostly defer to the Node's ComputedStyle object.
|
||||
The only exception is that this is where inheritance is resolved.
|
||||
*/
|
||||
|
||||
use dom::node::Node;
|
||||
use newcss::color::{Color, rgba};
|
||||
use newcss::units::{Length, Px};
|
||||
use newcss::values::{CSSValue, Specified, Inherit};
|
||||
use newcss::values::{CSSMargin, CSSMarginLength};
|
||||
use newcss::values::{CSSBorderWidth, CSSBorderWidthLength};
|
||||
use newcss::values::{CSSDisplay, CSSDisplayBlock};
|
||||
use newcss::values::{CSSPosition, CSSPositionRelative};
|
||||
use newcss::values::{CSSFloat, CSSFloatNone};
|
||||
use newcss::values::{CSSWidth, CSSWidthLength};
|
||||
use newcss::values::{CSSHeight, CSSHeightLength};
|
||||
use newcss::computed::ComputedStyle;
|
||||
use newcss::complete::CompleteStyle;
|
||||
|
||||
/// Node mixin providing `style` method that returns a `NodeStyle`
|
||||
trait StyledNode {
|
||||
fn style(&self) -> NodeStyle/&self;
|
||||
fn style(&self) -> CompleteStyle/&self;
|
||||
}
|
||||
|
||||
impl Node: StyledNode {
|
||||
fn style(&self) -> NodeStyle/&self {
|
||||
fn style(&self) -> CompleteStyle/&self {
|
||||
assert self.is_element(); // Only elements can have styles
|
||||
NodeStyle::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Provides getters for calculated node styles
|
||||
pub struct NodeStyle {
|
||||
priv node: &Node
|
||||
}
|
||||
|
||||
impl NodeStyle {
|
||||
|
||||
static fn new(node: &r/Node) -> NodeStyle/&r {
|
||||
NodeStyle {
|
||||
node: node
|
||||
}
|
||||
}
|
||||
|
||||
// CSS 2.1, Section 8 - Box model
|
||||
|
||||
fn margin_top(&self) -> CSSMargin {
|
||||
resolve(self, CSSMarginLength(Px(0.0)), |cs| cs.margin_top() )
|
||||
}
|
||||
|
||||
fn margin_right(&self) -> CSSMargin {
|
||||
resolve(self, CSSMarginLength(Px(0.0)), |cs| cs.margin_right() )
|
||||
}
|
||||
|
||||
fn margin_bottom(&self) -> CSSMargin {
|
||||
resolve(self, CSSMarginLength(Px(0.0)), |cs| cs.margin_bottom() )
|
||||
}
|
||||
|
||||
fn margin_left(&self) -> CSSMargin {
|
||||
resolve(self, CSSMarginLength(Px(0.0)), |cs| cs.margin_left() )
|
||||
}
|
||||
|
||||
fn border_top_width(&self) -> CSSBorderWidth {
|
||||
resolve(self, CSSBorderWidthLength(Px(0.0)), |cs| cs.border_top_width() )
|
||||
}
|
||||
|
||||
fn border_right_width(&self) -> CSSBorderWidth {
|
||||
resolve(self, CSSBorderWidthLength(Px(0.0)), |cs| cs.border_right_width() )
|
||||
}
|
||||
|
||||
fn border_bottom_width(&self) -> CSSBorderWidth {
|
||||
resolve(self, CSSBorderWidthLength(Px(0.0)), |cs| cs.border_bottom_width() )
|
||||
}
|
||||
|
||||
fn border_left_width(&self) -> CSSBorderWidth {
|
||||
resolve(self, CSSBorderWidthLength(Px(0.0)), |cs| cs.border_left_width() )
|
||||
}
|
||||
|
||||
fn border_top_color(&self) -> Color {
|
||||
resolve(self, rgba(255, 255, 255, 0.0), |cs| cs.border_top_color() )
|
||||
}
|
||||
|
||||
fn border_right_color(&self) -> Color {
|
||||
resolve(self, rgba(255, 255, 255, 0.0), |cs| cs.border_right_color() )
|
||||
}
|
||||
|
||||
fn border_bottom_color(&self) -> Color {
|
||||
resolve(self, rgba(255, 255, 255, 0.0), |cs| cs.border_bottom_color() )
|
||||
}
|
||||
|
||||
fn border_left_color(&self) -> Color {
|
||||
resolve(self, rgba(255, 255, 255, 0.0), |cs| cs.border_left_color() )
|
||||
}
|
||||
|
||||
// CSS 2.1, Section 9 - Visual formatting model
|
||||
|
||||
fn display(&self) -> CSSDisplay {
|
||||
// FIXME: Shouldn't be passing false here
|
||||
resolve(self, CSSDisplayBlock, |cs| cs.display(false) )
|
||||
}
|
||||
|
||||
fn position(&self) -> CSSPosition {
|
||||
resolve(self, CSSPositionRelative, |cs| cs.position() )
|
||||
}
|
||||
|
||||
fn float(&self) -> CSSFloat {
|
||||
resolve(self, CSSFloatNone, |cs| cs.float() )
|
||||
}
|
||||
|
||||
// CSS 2.1, Section 10 - Visual formatting model details
|
||||
|
||||
fn width(&self) -> CSSWidth {
|
||||
resolve(self, CSSWidthLength(Px(0.0)), |cs| cs.width() )
|
||||
}
|
||||
|
||||
fn height(&self) -> CSSHeight {
|
||||
resolve(self, CSSHeightLength(Px(0.0)), |cs| cs.height() )
|
||||
}
|
||||
|
||||
// CSS 2.1, Section 11 - Visual effects
|
||||
|
||||
// CSS 2.1, Section 12 - Generated content, automatic numbering, and lists
|
||||
|
||||
// CSS 2.1, Section 13 - Paged media
|
||||
|
||||
// CSS 2.1, Section 14 - Colors and Backgrounds
|
||||
|
||||
fn background_color(&self) -> Color {
|
||||
resolve(self, rgba(0, 0, 0, 0.0), |cs| cs.background_color() )
|
||||
}
|
||||
|
||||
// CSS 2.1, Section 15 - Fonts
|
||||
|
||||
// CSS 2.1, Section 16 - Text
|
||||
|
||||
// CSS 2.1, Section 17 - Tables
|
||||
|
||||
// CSS 2.1, Section 18 - User interface
|
||||
|
||||
}
|
||||
|
||||
fn resolve<T>(node_style: &NodeStyle, default: T, get: &fn(cs: ComputedStyle) -> CSSValue<T>) -> T {
|
||||
let node = node_style.node;
|
||||
let select_res = node.get_css_select_results();
|
||||
let computed = select_res.computed_style();
|
||||
let value = get(computed);
|
||||
match move value {
|
||||
Inherit => /* FIXME: need inheritance */ move default,
|
||||
Specified(move value) => move value,
|
||||
let results = self.get_css_select_results();
|
||||
results.computed_style()
|
||||
}
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
use dom::node::Node;
|
||||
use newcss::select::SelectResults;
|
||||
use newcss::complete::CompleteSelectResults;
|
||||
use std::cell::Cell;
|
||||
|
||||
trait NodeUtil {
|
||||
fn get_css_select_results() -> &self/SelectResults;
|
||||
fn set_css_select_results(decl : SelectResults);
|
||||
fn get_css_select_results() -> &self/CompleteSelectResults;
|
||||
fn set_css_select_results(decl : CompleteSelectResults);
|
||||
}
|
||||
|
||||
impl Node: NodeUtil {
|
||||
|
@ -15,7 +15,7 @@ impl Node: NodeUtil {
|
|||
* FIXME: This isn't completely memory safe since the style is
|
||||
* stored in a box that can be overwritten
|
||||
*/
|
||||
fn get_css_select_results() -> &self/SelectResults {
|
||||
fn get_css_select_results() -> &self/CompleteSelectResults {
|
||||
if !self.has_aux() {
|
||||
fail ~"style() called on a node without aux data!";
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ impl Node: NodeUtil {
|
|||
/**
|
||||
Update the computed style of an HTML element with a style specified by CSS.
|
||||
*/
|
||||
fn set_css_select_results(decl : SelectResults) {
|
||||
fn set_css_select_results(decl : CompleteSelectResults) {
|
||||
let decl = Cell(move decl);
|
||||
do self.aux |data| {
|
||||
data.style = Some(decl.take())
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* The core DOM types. Defines the basic DOM hierarchy as well as all the HTML elements. */
|
||||
use newcss::select::SelectResults;
|
||||
use newcss::complete::CompleteSelectResults;
|
||||
use dom::bindings;
|
||||
use dom::document::Document;
|
||||
use dom::element::{Attr, ElementData};
|
||||
|
@ -118,7 +118,7 @@ fn define_bindings(compartment: &bare_compartment, doc: @Document,
|
|||
|
||||
Note that there may be multiple boxes per DOM node. */
|
||||
enum LayoutData = {
|
||||
mut style: Option<SelectResults>,
|
||||
mut style: Option<CompleteSelectResults>,
|
||||
mut flow: Option<@FlowContext>
|
||||
};
|
||||
|
||||
|
|
|
@ -8,7 +8,8 @@ use au::Au;
|
|||
use core::dvec::DVec;
|
||||
use core::to_str::ToStr;
|
||||
use core::rand;
|
||||
use css::node_style::{NodeStyle, StyledNode};
|
||||
use css::node_style::StyledNode;
|
||||
use newcss::complete::CompleteStyle;
|
||||
use newcss::units::{BoxSizing, Length, Px};
|
||||
use newcss::values::{CSSDisplay, Specified, CSSBackgroundColorColor, CSSBackgroundColorTransparent};
|
||||
use newcss::values::{CSSBorderColor, CSSPositionAbsolute};
|
||||
|
@ -364,7 +365,7 @@ impl RenderBox : RenderBoxMethods {
|
|||
self.content_box()
|
||||
}
|
||||
|
||||
fn style(&self) -> NodeStyle/&self {
|
||||
fn style(&self) -> CompleteStyle/&self {
|
||||
let d: &self/RenderBoxData = self.d();
|
||||
d.node.style()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue