mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
layout: Add support for table rows, columns, rowgroups and colgroups (#31341)
This adds support for table rows, columns, rowgroups and colgroups. There are few additions here: 1. The createion of fragments, which allows script queries and hit testing to work properly. These fragments are empty as all cells are still direct descendants of the table fragment. 2. Properly handling size information from tracks and track groups as well as frustrating rules about reordering rowgroups. 3. Painting a background seemlessly across track groups and groups. This is a thing that isn't done in legacy layout (nor WebKit)! Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
74c07db56c
commit
02ae1f448e
57 changed files with 4274 additions and 21000 deletions
|
@ -64,6 +64,7 @@ use xml5ever::serialize::TraversalScope::{
|
|||
};
|
||||
use xml5ever::serialize::{SerializeOpts as XmlSerializeOpts, TraversalScope as XmlTraversalScope};
|
||||
|
||||
use super::htmltablecolelement::{HTMLTableColElement, HTMLTableColElementLayoutHelpers};
|
||||
use crate::dom::activation::Activatable;
|
||||
use crate::dom::attr::{Attr, AttrHelpersForLayout};
|
||||
use crate::dom::bindings::cell::{ref_filter_map, DomRefCell, Ref, RefMut};
|
||||
|
@ -614,8 +615,9 @@ pub trait LayoutElementHelpers<'dom> {
|
|||
fn synthesize_presentational_hints_for_legacy_attributes<V>(self, hints: &mut V)
|
||||
where
|
||||
V: Push<ApplicableDeclarationBlock>;
|
||||
fn get_colspan(self) -> u32;
|
||||
fn get_rowspan(self) -> u32;
|
||||
fn get_span(self) -> Option<u32>;
|
||||
fn get_colspan(self) -> Option<u32>;
|
||||
fn get_rowspan(self) -> Option<u32>;
|
||||
fn is_html_element(self) -> bool;
|
||||
fn id_attribute(self) -> *const Option<Atom>;
|
||||
fn style_attribute(self) -> *const Option<Arc<Locked<PropertyDeclarationBlock>>>;
|
||||
|
@ -1019,24 +1021,22 @@ impl<'dom> LayoutElementHelpers<'dom> for LayoutDom<'dom, Element> {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_colspan(self) -> u32 {
|
||||
if let Some(this) = self.downcast::<HTMLTableCellElement>() {
|
||||
this.get_colspan().unwrap_or(1)
|
||||
} else {
|
||||
// Don't panic since `display` can cause this to be called on arbitrary
|
||||
// elements.
|
||||
1
|
||||
}
|
||||
fn get_span(self) -> Option<u32> {
|
||||
// Don't panic since `display` can cause this to be called on arbitrary elements.
|
||||
self.downcast::<HTMLTableColElement>()
|
||||
.and_then(|element| element.get_span())
|
||||
}
|
||||
|
||||
fn get_rowspan(self) -> u32 {
|
||||
if let Some(this) = self.downcast::<HTMLTableCellElement>() {
|
||||
this.get_rowspan().unwrap_or(1)
|
||||
} else {
|
||||
// Don't panic since `display` can cause this to be called on arbitrary
|
||||
// elements.
|
||||
1
|
||||
}
|
||||
fn get_colspan(self) -> Option<u32> {
|
||||
// Don't panic since `display` can cause this to be called on arbitrary elements.
|
||||
self.downcast::<HTMLTableCellElement>()
|
||||
.and_then(|element| element.get_colspan())
|
||||
}
|
||||
|
||||
fn get_rowspan(self) -> Option<u32> {
|
||||
// Don't panic since `display` can cause this to be called on arbitrary elements.
|
||||
self.downcast::<HTMLTableCellElement>()
|
||||
.and_then(|element| element.get_rowspan())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -162,24 +162,22 @@ impl VirtualMethods for HTMLTableCellElement {
|
|||
match *local_name {
|
||||
local_name!("colspan") => {
|
||||
let mut attr = AttrValue::from_u32(value.into(), DEFAULT_COLSPAN);
|
||||
if let AttrValue::UInt(ref mut s, ref mut val) = attr {
|
||||
if let AttrValue::UInt(_, ref mut val) = attr {
|
||||
if *val == 0 {
|
||||
*val = 1;
|
||||
*s = "1".into();
|
||||
}
|
||||
}
|
||||
attr
|
||||
},
|
||||
local_name!("rowspan") => {
|
||||
let mut attr = AttrValue::from_u32(value.into(), DEFAULT_ROWSPAN);
|
||||
if let AttrValue::UInt(ref mut s, ref mut val) = attr {
|
||||
if let AttrValue::UInt(_, ref mut val) = attr {
|
||||
if *val == 0 {
|
||||
let node = self.upcast::<Node>();
|
||||
let doc = node.owner_doc();
|
||||
// rowspan = 0 is not supported in quirks mode
|
||||
if doc.quirks_mode() != QuirksMode::NoQuirks {
|
||||
*val = 1;
|
||||
*s = "1".into();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,14 +3,23 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use dom_struct::dom_struct;
|
||||
use html5ever::{LocalName, Prefix};
|
||||
use html5ever::{local_name, namespace_url, ns, LocalName, Prefix};
|
||||
use js::rust::HandleObject;
|
||||
use style::attr::AttrValue;
|
||||
|
||||
use super::bindings::root::LayoutDom;
|
||||
use super::element::Element;
|
||||
use crate::dom::bindings::codegen::Bindings::HTMLTableColElementBinding::HTMLTableColElementMethods;
|
||||
use crate::dom::bindings::inheritance::Castable;
|
||||
use crate::dom::bindings::root::DomRoot;
|
||||
use crate::dom::bindings::str::DOMString;
|
||||
use crate::dom::document::Document;
|
||||
use crate::dom::element::LayoutElementHelpers;
|
||||
use crate::dom::htmlelement::HTMLElement;
|
||||
use crate::dom::node::Node;
|
||||
use crate::dom::virtualmethods::VirtualMethods;
|
||||
|
||||
const DEFAULT_SPAN: u32 = 1;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct HTMLTableColElement {
|
||||
|
@ -47,3 +56,46 @@ impl HTMLTableColElement {
|
|||
n
|
||||
}
|
||||
}
|
||||
|
||||
impl HTMLTableColElementMethods for HTMLTableColElement {
|
||||
// <https://html.spec.whatwg.org/multipage/#attr-col-span>
|
||||
make_uint_getter!(Span, "span", DEFAULT_SPAN);
|
||||
// <https://html.spec.whatwg.org/multipage/#attr-col-span>
|
||||
make_uint_setter!(SetSpan, "span", DEFAULT_SPAN);
|
||||
}
|
||||
|
||||
pub trait HTMLTableColElementLayoutHelpers<'dom> {
|
||||
fn get_span(self) -> Option<u32>;
|
||||
}
|
||||
|
||||
impl<'dom> HTMLTableColElementLayoutHelpers<'dom> for LayoutDom<'dom, HTMLTableColElement> {
|
||||
fn get_span(self) -> Option<u32> {
|
||||
self.upcast::<Element>()
|
||||
.get_attr_for_layout(&ns!(), &local_name!("span"))
|
||||
.map(AttrValue::as_uint)
|
||||
}
|
||||
}
|
||||
|
||||
impl VirtualMethods for HTMLTableColElement {
|
||||
fn super_type(&self) -> Option<&dyn VirtualMethods> {
|
||||
Some(self.upcast::<HTMLElement>() as &dyn VirtualMethods)
|
||||
}
|
||||
|
||||
fn parse_plain_attribute(&self, local_name: &LocalName, value: DOMString) -> AttrValue {
|
||||
match *local_name {
|
||||
local_name!("span") => {
|
||||
let mut attr = AttrValue::from_u32(value.into(), DEFAULT_SPAN);
|
||||
if let AttrValue::UInt(_, ref mut val) = attr {
|
||||
if *val == 0 {
|
||||
*val = 1;
|
||||
}
|
||||
}
|
||||
attr
|
||||
},
|
||||
_ => self
|
||||
.super_type()
|
||||
.unwrap()
|
||||
.parse_plain_attribute(local_name, value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
use html5ever::LocalName;
|
||||
use style::attr::AttrValue;
|
||||
|
||||
use super::htmltablecolelement::HTMLTableColElement;
|
||||
use crate::dom::attr::Attr;
|
||||
use crate::dom::bindings::inheritance::{
|
||||
Castable, ElementTypeId, HTMLElementTypeId, HTMLMediaElementTypeId, NodeTypeId,
|
||||
|
@ -250,6 +251,9 @@ pub fn vtable_for(node: &Node) -> &dyn VirtualMethods {
|
|||
NodeTypeId::Element(ElementTypeId::HTMLElement(
|
||||
HTMLElementTypeId::HTMLTableCellElement,
|
||||
)) => node.downcast::<HTMLTableCellElement>().unwrap() as &dyn VirtualMethods,
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTableColElement)) => {
|
||||
node.downcast::<HTMLTableColElement>().unwrap() as &dyn VirtualMethods
|
||||
},
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTableRowElement)) => {
|
||||
node.downcast::<HTMLTableRowElement>().unwrap() as &dyn VirtualMethods
|
||||
},
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
interface HTMLTableColElement : HTMLElement {
|
||||
[HTMLConstructor] constructor();
|
||||
|
||||
// [CEReactions]
|
||||
// attribute unsigned long span;
|
||||
[CEReactions]
|
||||
attribute unsigned long span;
|
||||
|
||||
// also has obsolete members
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue