mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
script: Clamp table spans according to the HTML specification (#36703)
Previously, spans were partially clamped during layout, but this means that accessing and setting these properties via script wouldn't behave according to the HTML specification. In addition, the value wasn't floored in layout, so could lead to panics. This change improves clamping and moves it to script. Testing: This change includes a new WPT test. Fixes #36699. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
b10fc49e8a
commit
0d21992edd
9 changed files with 177 additions and 75 deletions
|
@ -70,13 +70,17 @@ impl HTMLTableCellElementMethods<crate::DomTypeHolder> for HTMLTableCellElement
|
|||
make_uint_getter!(ColSpan, "colspan", DEFAULT_COLSPAN);
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-tdth-colspan
|
||||
make_uint_setter!(SetColSpan, "colspan", DEFAULT_COLSPAN);
|
||||
// > The colSpan IDL attribute must reflect the colspan content attribute. It is clamped to
|
||||
// > the range [1, 1000], and its default value is 1.
|
||||
make_clamped_uint_setter!(SetColSpan, "colspan", 1, 1000, 1);
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-tdth-rowspan
|
||||
make_uint_getter!(RowSpan, "rowspan", DEFAULT_ROWSPAN);
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-tdth-rowspan
|
||||
make_uint_setter!(SetRowSpan, "rowspan", DEFAULT_ROWSPAN);
|
||||
// > The rowSpan IDL attribute must reflect the rowspan content attribute. It is clamped to
|
||||
// > the range [0, 65534], and its default value is 1.
|
||||
make_clamped_uint_setter!(SetRowSpan, "rowspan", 0, 65534, 1);
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-tdth-bgcolor
|
||||
make_getter!(BgColor, "bgcolor");
|
||||
|
@ -174,23 +178,26 @@ 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 val) = attr {
|
||||
if *val == 0 {
|
||||
*val = 1;
|
||||
}
|
||||
if let AttrValue::UInt(_, ref mut value) = attr {
|
||||
// From <https://html.spec.whatwg.org/multipage/#dom-tdth-colspan>:
|
||||
// > The colSpan IDL attribute must reflect the colspan content attribute. It is clamped to
|
||||
// > the range [1, 1000], and its default value is 1.
|
||||
*value = (*value).clamp(1, 1000);
|
||||
}
|
||||
attr
|
||||
},
|
||||
local_name!("rowspan") => {
|
||||
let mut attr = AttrValue::from_u32(value.into(), DEFAULT_ROWSPAN);
|
||||
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;
|
||||
}
|
||||
if let AttrValue::UInt(_, ref mut value) = attr {
|
||||
// From <https://html.spec.whatwg.org/multipage/#dom-tdth-rowspan>:
|
||||
// > The rowSpan IDL attribute must reflect the rowspan content attribute. It is clamped to
|
||||
// > the range [0, 65534], and its default value is 1.
|
||||
// Note that rowspan = 0 is not supported in quirks mode.
|
||||
let document = self.upcast::<Node>().owner_doc();
|
||||
if document.quirks_mode() != QuirksMode::NoQuirks {
|
||||
*value = (*value).clamp(1, 65534);
|
||||
} else {
|
||||
*value = (*value).clamp(0, 65534);
|
||||
}
|
||||
}
|
||||
attr
|
||||
|
|
|
@ -20,8 +20,6 @@ use crate::dom::node::Node;
|
|||
use crate::dom::virtualmethods::VirtualMethods;
|
||||
use crate::script_runtime::CanGc;
|
||||
|
||||
const DEFAULT_SPAN: u32 = 1;
|
||||
|
||||
#[dom_struct]
|
||||
pub(crate) struct HTMLTableColElement {
|
||||
htmlelement: HTMLElement,
|
||||
|
@ -62,9 +60,11 @@ impl HTMLTableColElement {
|
|||
|
||||
impl HTMLTableColElementMethods<crate::DomTypeHolder> for HTMLTableColElement {
|
||||
// <https://html.spec.whatwg.org/multipage/#attr-col-span>
|
||||
make_uint_getter!(Span, "span", DEFAULT_SPAN);
|
||||
make_uint_getter!(Span, "span", 1);
|
||||
// <https://html.spec.whatwg.org/multipage/#attr-col-span>
|
||||
make_uint_setter!(SetSpan, "span", DEFAULT_SPAN);
|
||||
// > The span IDL attribute must reflect the content attribute of the same name. It is clamped
|
||||
// > to the range [1, 1000], and its default value is 1.
|
||||
make_clamped_uint_setter!(SetSpan, "span", 1, 1000, 1);
|
||||
}
|
||||
|
||||
pub(crate) trait HTMLTableColElementLayoutHelpers<'dom> {
|
||||
|
@ -96,11 +96,12 @@ impl VirtualMethods for HTMLTableColElement {
|
|||
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);
|
||||
let mut attr = AttrValue::from_u32(value.into(), 1);
|
||||
if let AttrValue::UInt(_, ref mut val) = attr {
|
||||
if *val == 0 {
|
||||
*val = 1;
|
||||
}
|
||||
// From <https://html.spec.whatwg.org/multipage/#attr-col-span>:
|
||||
// > The span IDL attribute must reflect the content attribute of the same name.
|
||||
// > It is clamped to the range [1, 1000], and its default value is 1.
|
||||
*val = (*val).clamp(1, 1000);
|
||||
}
|
||||
attr
|
||||
},
|
||||
|
|
|
@ -317,6 +317,26 @@ macro_rules! make_uint_setter(
|
|||
};
|
||||
);
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! make_clamped_uint_setter(
|
||||
($attr:ident, $htmlname:tt, $min:expr, $max:expr, $default:expr) => (
|
||||
fn $attr(&self, value: u32) {
|
||||
use $crate::dom::bindings::inheritance::Castable;
|
||||
use $crate::dom::element::Element;
|
||||
use $crate::dom::values::UNSIGNED_LONG_MAX;
|
||||
use $crate::script_runtime::CanGc;
|
||||
let value = if value > UNSIGNED_LONG_MAX {
|
||||
$default
|
||||
} else {
|
||||
value.clamp($min, $max)
|
||||
};
|
||||
|
||||
let element = self.upcast::<Element>();
|
||||
element.set_uint_attribute(&html5ever::local_name!($htmlname), value, CanGc::note())
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! make_limited_uint_setter(
|
||||
($attr:ident, $htmlname:tt, $default:expr) => (
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue