Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

style: Implement basic column spans and the legacy `bgcolor` and `border` attributes. #4278

Closed
wants to merge 3 commits into from
Closed
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Next

style: Parse the legacy `border` attribute per the legacy HTML specif…

…ication.

Additionally, this patch cleans up some miscellaneous formatting issues
and refactors layout/css somewhat to eliminate needless levels of
indirection.
  • Loading branch information
pcwalton committed Dec 8, 2014
commit 236bcd6ad18d693d873ae50e273b3d19b7c32989
@@ -268,6 +268,9 @@ impl StyleSharingCandidate {
return false
}

// FIXME(pcwalton): It's probably faster to iterate over all the element's attributes and
// use the {common, rare}-style-affecting-attributes tables as lookup tables.

for attribute_info in style::common_style_affecting_attributes().iter() {
match attribute_info.mode {
AttrIsPresentMode(flag) => {
@@ -295,6 +298,12 @@ impl StyleSharingCandidate {
}
}

for attribute_name in style::rare_style_affecting_attributes().iter() {
if element.get_attr(&ns!(""), attribute_name).is_some() {
return false
}
}

if element.get_link().is_some() != self.link {
return false
}
@@ -2,27 +2,75 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// Style retrieval from DOM elements.
//! Style retrieval from DOM elements.

use css::node_util::NodeUtil;
use wrapper::ThreadSafeLayoutNode;
use wrapper::{After, Before, Normal, ThreadSafeLayoutNode};

use std::mem;
use style::ComputedValues;
use sync::Arc;

/// Node mixin providing `style` method that returns a `NodeStyle`
pub trait StyledNode {
/// Returns the style results for the given node. If CSS selector matching has not yet been
/// performed, fails.
fn style<'a>(&'a self) -> &'a Arc<ComputedValues>;
/// Does this node have a computed style yet?
fn has_style(&self) -> bool;
/// Removes the style from this node.
fn unstyle(self);
}

impl<'ln> StyledNode for ThreadSafeLayoutNode<'ln> {
#[inline]
fn style<'a>(&'a self) -> &'a Arc<ComputedValues> {
self.get_css_select_results()
unsafe {
let layout_data_ref = self.borrow_layout_data();
match self.get_pseudo_element_type() {
Before(_) => {
mem::transmute(layout_data_ref.as_ref()
.unwrap()
.data
.before_style
.as_ref()
.unwrap())
}
After(_) => {
mem::transmute(layout_data_ref.as_ref()
.unwrap()
.data
.after_style
.as_ref()
.unwrap())
}
Normal => {
mem::transmute(layout_data_ref.as_ref()
.unwrap()
.shared_data
.style
.as_ref()
.unwrap())
}
}
}
}

fn has_style(&self) -> bool {
let layout_data_ref = self.borrow_layout_data();
layout_data_ref.as_ref().unwrap().shared_data.style.is_some()
}

fn unstyle(self) {
self.remove_css_select_results()
let mut layout_data_ref = self.mutate_layout_data();
let layout_data = layout_data_ref.as_mut().expect("no layout data");

let style =
match self.get_pseudo_element_type() {
Before(_) => &mut layout_data.data.before_style,
After (_) => &mut layout_data.data.after_style,
Normal => &mut layout_data.shared_data.style,
};

*style = None;
}
}

This file was deleted.

@@ -69,8 +69,6 @@ pub mod incremental;
pub mod wrapper;

pub mod css {
mod node_util;

pub mod matching;
pub mod node_style;
}
@@ -53,14 +53,15 @@ use script::dom::node::{HAS_CHANGED, IS_DIRTY, HAS_DIRTY_SIBLINGS, HAS_DIRTY_DES
use script::dom::text::Text;
use script::layout_interface::LayoutChan;
use servo_msg::constellation_msg::{PipelineId, SubpageId};
use servo_util::str::{LengthOrPercentageOrAuto, is_whitespace};
use servo_util::str::{LengthOrPercentageOrAuto, SimpleColor, is_whitespace};
use std::kinds::marker::ContravariantLifetime;
use std::mem;
use string_cache::{Atom, Namespace};
use style::computed_values::{content, display, white_space};
use style::{AnyNamespace, AttrSelector, IntegerAttribute, LengthAttribute};
use style::{PropertyDeclarationBlock, SpecificNamespace, TElement, TElementAttributes, TNode};
use style::{PropertyDeclarationBlock, SimpleColorAttribute, SpecificNamespace, TElement};
use style::{TElementAttributes, TNode, UnsignedIntegerAttribute};
use url::Url;
use string_cache::{Atom, Namespace};

use std::cell::{Ref, RefMut};

@@ -586,6 +587,12 @@ impl<'le> TElementAttributes for LayoutElement<'le> {
self.element.get_integer_attribute_for_layout(integer_attribute)
}
}

fn get_unsigned_integer_attribute(self, attribute: UnsignedIntegerAttribute) -> Option<u32> {
unsafe {
self.element.get_unsigned_integer_attribute_for_layout(attribute)
}
}
}

fn get_content(content_list: &content::T) -> String {
@@ -14,8 +14,10 @@ use dom::bindings::codegen::Bindings::ElementBinding;
use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
use dom::bindings::codegen::Bindings::NamedNodeMapBinding::NamedNodeMapMethods;
use dom::bindings::codegen::InheritTypes::{ElementDerived, HTMLInputElementDerived, HTMLTableCellElementDerived};
use dom::bindings::codegen::InheritTypes::{HTMLInputElementCast, NodeCast, EventTargetCast, ElementCast};
use dom::bindings::codegen::InheritTypes::{ElementCast, ElementDerived, EventTargetCast};
use dom::bindings::codegen::InheritTypes::{HTMLBodyElementDerived, HTMLInputElementCast};
use dom::bindings::codegen::InheritTypes::{HTMLInputElementDerived, HTMLTableElementDerived};
use dom::bindings::codegen::InheritTypes::{HTMLTableCellElementDerived, NodeCast};
use dom::bindings::js::{MutNullableJS, JS, JSRef, Temporary, TemporaryPushable};
use dom::bindings::js::{OptionalRootable, Root};
use dom::bindings::utils::{Reflectable, Reflector};
@@ -31,14 +33,17 @@ use dom::eventtarget::{EventTarget, NodeTargetTypeId, EventTargetHelpers};
use dom::htmlcollection::HTMLCollection;
use dom::htmlinputelement::{HTMLInputElement, RawLayoutHTMLInputElementHelpers};
use dom::htmlserializer::serialize;
use dom::htmltableelement::{HTMLTableElement, HTMLTableElementHelpers};
use dom::htmltablecellelement::{HTMLTableCellElement, HTMLTableCellElementHelpers};
use dom::node::{ElementNodeTypeId, Node, NodeHelpers, NodeIterator, document_from_node, CLICK_IN_PROGRESS};
use dom::node::{window_from_node, LayoutNodeHelpers};
use dom::node::{CLICK_IN_PROGRESS, ElementNodeTypeId, LayoutNodeHelpers, Node, NodeHelpers};
use dom::node::{NodeIterator, document_from_node, window_from_node};
use dom::nodelist::NodeList;
use dom::virtualmethods::{VirtualMethods, vtable_for};
use devtools_traits::AttrInfo;
use style::{IntegerAttribute, LengthAttribute, SizeIntegerAttribute, WidthLengthAttribute};
use style::{matches, parse_selector_list_from_str};
use style::{BgColorSimpleColorAttribute, BorderUnsignedIntegerAttribute};
use style::{ColSpanUnsignedIntegerAttribute, IntegerAttribute, LengthAttribute};
use style::{SimpleColorAttribute, SizeIntegerAttribute, UnsignedIntegerAttribute};
use style::{WidthLengthAttribute, matches, parse_selector_list_from_str};
use style;
use servo_util::namespace;
use servo_util::str::{DOMString, LengthOrPercentageOrAuto};
@@ -198,6 +203,8 @@ pub trait RawLayoutElementHelpers {
-> LengthOrPercentageOrAuto;
unsafe fn get_integer_attribute_for_layout(&self, integer_attribute: IntegerAttribute)
-> Option<i32>;
unsafe fn get_unsigned_integer_attribute_for_layout(&self, attribute: UnsignedIntegerAttribute)
-> Option<u32>;
fn local_name<'a>(&'a self) -> &'a Atom;
fn namespace<'a>(&'a self) -> &'a Namespace;
fn style_attribute<'a>(&'a self) -> &'a DOMRefCell<Option<style::PropertyDeclarationBlock>>;
@@ -289,11 +296,15 @@ impl RawLayoutElementHelpers for Element {
-> LengthOrPercentageOrAuto {
match length_attribute {
WidthLengthAttribute => {
if !self.is_htmltablecellelement() {
panic!("I'm not a table cell!")
if self.is_htmltableelement() {
let this: &HTMLTableElement = mem::transmute(self);
this.get_width()
} else if self.is_htmltablecellelement() {
let this: &HTMLTableCellElement = mem::transmute(self);
this.get_width()
} else {
panic!("I'm not a table or table cell!")
}
let this: &HTMLTableCellElement = mem::transmute(self);
this.get_width()
}
}
}
@@ -313,6 +324,34 @@ impl RawLayoutElementHelpers for Element {
}
}

#[inline]
#[allow(unrooted_must_root)]
unsafe fn get_unsigned_integer_attribute_for_layout(&self,
attribute: UnsignedIntegerAttribute)
-> Option<u32> {
match attribute {
BorderUnsignedIntegerAttribute => {
if self.is_htmltableelement() {
let this: &HTMLTableElement = mem::transmute(self);
this.get_border()
} else if self.is_htmltablecellelement() {
let this: &HTMLTableCellElement = mem::transmute(self);
this.get_border()
} else {
panic!("I'm not a table or table cell!")
}
}
ColSpanUnsignedIntegerAttribute => {
if self.is_htmltablecellelement() {
let this: &HTMLTableCellElement = mem::transmute(self);
this.get_colspan()
} else {
panic!("I'm not a table cell!")
}
}
}
}

// Getters used in components/layout/wrapper.rs

fn local_name<'a>(&'a self) -> &'a Atom {
@@ -2,8 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::attr::Attr;
use dom::attr::AttrHelpers;
use dom::attr::{Attr, AttrHelpers};
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLTableCellElementDerived};
use dom::bindings::js::JSRef;
use dom::bindings::utils::{Reflectable, Reflector};
@@ -22,6 +21,7 @@ use std::cell::Cell;
#[dom_struct]
pub struct HTMLTableCellElement {
htmlelement: HTMLElement,
border: Cell<Option<u32>>,
width: Cell<LengthOrPercentageOrAuto>,
}

@@ -36,10 +36,15 @@ impl HTMLTableCellElementDerived for EventTarget {
}

impl HTMLTableCellElement {
pub fn new_inherited(type_id: ElementTypeId, tag_name: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLTableCellElement {
pub fn new_inherited(type_id: ElementTypeId,
tag_name: DOMString,
prefix: Option<DOMString>,
document: JSRef<Document>)
-> HTMLTableCellElement {
HTMLTableCellElement {
htmlelement: HTMLElement::new_inherited(type_id, tag_name, prefix, document),
width: Cell::new(AutoLpa)
border: Cell::new(None),
width: Cell::new(AutoLpa),
}
}

@@ -50,10 +55,15 @@ impl HTMLTableCellElement {
}

pub trait HTMLTableCellElementHelpers {
fn get_border(&self) -> Option<u32>;
fn get_width(&self) -> LengthOrPercentageOrAuto;
}

impl HTMLTableCellElementHelpers for HTMLTableCellElement {
fn get_border(&self) -> Option<u32> {
self.border.get()
}

fn get_width(&self) -> LengthOrPercentageOrAuto {
self.width.get()
}
@@ -72,6 +82,12 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTableCellElement> {
}

match attr.local_name() {
&atom!("border") => {
// According to HTML5 § 14.3.9, invalid values map to 1px.
self.border.set(Some(str::parse_unsigned_integer(attr.value()
.as_slice()
.chars()).unwrap_or(1)))
}
&atom!("width") => self.width.set(str::parse_length(attr.value().as_slice())),
_ => ()
}
@@ -84,6 +100,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTableCellElement> {
}

match attr.local_name() {
&atom!("border") => self.border.set(None),
&atom!("width") => self.width.set(AutoLpa),
_ => ()
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.