mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Implement the size
presentational hint for <hr>
elements (#37211)
This presentational hint either sets the width values of all borders, removes the bottom border or sets the height of the element, depending on the context. This change also implements the corresponding idl attribute (and the `noshade` attribute, which does nothing in html5) Testing: Adds new web platform tests --------- Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This commit is contained in:
parent
b4035cc88e
commit
8937542fe3
10 changed files with 204 additions and 251 deletions
|
@ -121,7 +121,7 @@ use crate::dom::htmlelement::HTMLElement;
|
|||
use crate::dom::htmlfieldsetelement::HTMLFieldSetElement;
|
||||
use crate::dom::htmlfontelement::{HTMLFontElement, HTMLFontElementLayoutHelpers};
|
||||
use crate::dom::htmlformelement::FormControlElementHelpers;
|
||||
use crate::dom::htmlhrelement::{HTMLHRElement, HTMLHRLayoutHelpers};
|
||||
use crate::dom::htmlhrelement::{HTMLHRElement, HTMLHRLayoutHelpers, SizePresentationalHint};
|
||||
use crate::dom::htmliframeelement::{HTMLIFrameElement, HTMLIFrameElementLayoutMethods};
|
||||
use crate::dom::htmlimageelement::{HTMLImageElement, LayoutHTMLImageElementHelpers};
|
||||
use crate::dom::htmlinputelement::{HTMLInputElement, LayoutHTMLInputElementHelpers};
|
||||
|
@ -1306,6 +1306,47 @@ impl<'dom> LayoutElementHelpers<'dom> for LayoutDom<'dom, Element> {
|
|||
PropertyDeclaration::PaddingRight(cellpadding),
|
||||
));
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#the-hr-element-2
|
||||
if let Some(size_info) = self
|
||||
.downcast::<HTMLHRElement>()
|
||||
.and_then(|hr_element| hr_element.get_size_info())
|
||||
{
|
||||
match size_info {
|
||||
SizePresentationalHint::SetHeightTo(height) => {
|
||||
hints.push(from_declaration(
|
||||
shared_lock,
|
||||
PropertyDeclaration::Height(height),
|
||||
));
|
||||
},
|
||||
SizePresentationalHint::SetAllBorderWidthValuesTo(border_width) => {
|
||||
hints.push(from_declaration(
|
||||
shared_lock,
|
||||
PropertyDeclaration::BorderLeftWidth(border_width.clone()),
|
||||
));
|
||||
hints.push(from_declaration(
|
||||
shared_lock,
|
||||
PropertyDeclaration::BorderRightWidth(border_width.clone()),
|
||||
));
|
||||
hints.push(from_declaration(
|
||||
shared_lock,
|
||||
PropertyDeclaration::BorderTopWidth(border_width.clone()),
|
||||
));
|
||||
hints.push(from_declaration(
|
||||
shared_lock,
|
||||
PropertyDeclaration::BorderBottomWidth(border_width),
|
||||
));
|
||||
},
|
||||
SizePresentationalHint::SetBottomBorderWidthToZero => {
|
||||
hints.push(from_declaration(
|
||||
shared_lock,
|
||||
PropertyDeclaration::BorderBottomWidth(
|
||||
specified::border::BorderSideWidth::from_px(0.),
|
||||
),
|
||||
));
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_span(self) -> Option<u32> {
|
||||
|
|
|
@ -2,11 +2,17 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::str::FromStr;
|
||||
|
||||
use dom_struct::dom_struct;
|
||||
use html5ever::{LocalName, Prefix, local_name, ns};
|
||||
use js::rust::HandleObject;
|
||||
use style::attr::{AttrValue, LengthOrPercentageOrAuto};
|
||||
use style::color::AbsoluteColor;
|
||||
use style::values::generics::NonNegative;
|
||||
use style::values::specified::border::BorderSideWidth;
|
||||
use style::values::specified::length::Size;
|
||||
use style::values::specified::{LengthPercentage, NoCalcLength};
|
||||
|
||||
use crate::dom::bindings::codegen::Bindings::HTMLHRElementBinding::HTMLHRElementMethods;
|
||||
use crate::dom::bindings::inheritance::Castable;
|
||||
|
@ -65,6 +71,18 @@ impl HTMLHRElementMethods<crate::DomTypeHolder> for HTMLHRElement {
|
|||
// https://html.spec.whatwg.org/multipage/#dom-hr-color
|
||||
make_legacy_color_setter!(SetColor, "color");
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-hr-noshade
|
||||
make_bool_getter!(NoShade, "noshade");
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-hr-noshade
|
||||
make_bool_setter!(SetNoShade, "noshade");
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-hr-size
|
||||
make_getter!(Size, "size");
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-hr-size
|
||||
make_dimension_setter!(SetSize, "size");
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-hr-width
|
||||
make_getter!(Width, "width");
|
||||
|
||||
|
@ -72,9 +90,20 @@ impl HTMLHRElementMethods<crate::DomTypeHolder> for HTMLHRElement {
|
|||
make_dimension_setter!(SetWidth, "width");
|
||||
}
|
||||
|
||||
/// The result of applying the the presentational hint for the `size` attribute.
|
||||
///
|
||||
/// (This attribute can mean different things depending on its value and other attributes)
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
pub(crate) enum SizePresentationalHint {
|
||||
SetHeightTo(Size),
|
||||
SetAllBorderWidthValuesTo(BorderSideWidth),
|
||||
SetBottomBorderWidthToZero,
|
||||
}
|
||||
|
||||
pub(crate) trait HTMLHRLayoutHelpers {
|
||||
fn get_color(self) -> Option<AbsoluteColor>;
|
||||
fn get_width(self) -> LengthOrPercentageOrAuto;
|
||||
fn get_size_info(self) -> Option<SizePresentationalHint>;
|
||||
}
|
||||
|
||||
impl HTMLHRLayoutHelpers for LayoutDom<'_, HTMLHRElement> {
|
||||
|
@ -92,6 +121,35 @@ impl HTMLHRLayoutHelpers for LayoutDom<'_, HTMLHRElement> {
|
|||
.cloned()
|
||||
.unwrap_or(LengthOrPercentageOrAuto::Auto)
|
||||
}
|
||||
|
||||
fn get_size_info(self) -> Option<SizePresentationalHint> {
|
||||
// https://html.spec.whatwg.org/multipage/#the-hr-element-2
|
||||
let element = self.upcast::<Element>();
|
||||
let size_value = element
|
||||
.get_attr_val_for_layout(&ns!(), &local_name!("size"))
|
||||
.and_then(|value| usize::from_str(value).ok())
|
||||
.filter(|value| *value != 0)?;
|
||||
|
||||
let hint = if element
|
||||
.get_attr_for_layout(&ns!(), &local_name!("color"))
|
||||
.is_some() ||
|
||||
element
|
||||
.get_attr_for_layout(&ns!(), &local_name!("noshade"))
|
||||
.is_some()
|
||||
{
|
||||
SizePresentationalHint::SetAllBorderWidthValuesTo(BorderSideWidth::from_px(
|
||||
size_value as f32 / 2.0,
|
||||
))
|
||||
} else if size_value == 1 {
|
||||
SizePresentationalHint::SetBottomBorderWidthToZero
|
||||
} else {
|
||||
SizePresentationalHint::SetHeightTo(Size::LengthPercentage(NonNegative(
|
||||
LengthPercentage::Length(NoCalcLength::from_px((size_value - 2) as f32)),
|
||||
)))
|
||||
};
|
||||
|
||||
Some(hint)
|
||||
}
|
||||
}
|
||||
|
||||
impl VirtualMethods for HTMLHRElement {
|
||||
|
|
|
@ -12,14 +12,9 @@ interface HTMLHRElement : HTMLElement {
|
|||
|
||||
// https://html.spec.whatwg.org/multipage/#HTMLHRElement-partial
|
||||
partial interface HTMLHRElement {
|
||||
[CEReactions]
|
||||
attribute DOMString align;
|
||||
[CEReactions]
|
||||
attribute DOMString color;
|
||||
// [CEReactions]
|
||||
// attribute boolean noShade;
|
||||
// [CEReactions]
|
||||
// attribute DOMString size;
|
||||
[CEReactions]
|
||||
attribute DOMString width;
|
||||
[CEReactions] attribute DOMString align;
|
||||
[CEReactions] attribute DOMString color;
|
||||
[CEReactions] attribute boolean noShade;
|
||||
[CEReactions] attribute DOMString size;
|
||||
[CEReactions] attribute DOMString width;
|
||||
};
|
||||
|
|
34
tests/wpt/meta/MANIFEST.json
vendored
34
tests/wpt/meta/MANIFEST.json
vendored
|
@ -351937,6 +351937,32 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"size-with-color-or-noshade.html": [
|
||||
"db1d583934e6df482cde846eda757e010e7d0310",
|
||||
[
|
||||
null,
|
||||
[
|
||||
[
|
||||
"/html/rendering/non-replaced-elements/the-hr-element-0/size-with-color-or-noshade-ref.html",
|
||||
"=="
|
||||
]
|
||||
],
|
||||
{}
|
||||
]
|
||||
],
|
||||
"size.html": [
|
||||
"2162131b853ed77917ab373f4fb2c70c536e453c",
|
||||
[
|
||||
null,
|
||||
[
|
||||
[
|
||||
"/html/rendering/non-replaced-elements/the-hr-element-0/size-ref.html",
|
||||
"=="
|
||||
]
|
||||
],
|
||||
{}
|
||||
]
|
||||
],
|
||||
"width.html": [
|
||||
"a436d2ae25a6b03f320bda066f32c374b84e0d92",
|
||||
[
|
||||
|
@ -480431,6 +480457,14 @@
|
|||
"5cd35c83ada3470ad7a16d14a5028b01596bb60c",
|
||||
[]
|
||||
],
|
||||
"size-ref.html": [
|
||||
"03a21eb45737ef46247d8bdd61fe5ea0dcefef3e",
|
||||
[]
|
||||
],
|
||||
"size-with-color-or-noshade-ref.html": [
|
||||
"d6300e250d97d113e9ef358daa300de4bd593850",
|
||||
[]
|
||||
],
|
||||
"width-ref.html": [
|
||||
"71e7651c1ab6927f1be436ef8ff749f920924562",
|
||||
[]
|
||||
|
|
|
@ -5455,18 +5455,6 @@
|
|||
[HTMLHeadingElement interface: document.createElement("h1") must inherit property "align" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLHRElement interface: attribute noShade]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLHRElement interface: attribute size]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLHRElement interface: document.createElement("hr") must inherit property "noShade" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLHRElement interface: document.createElement("hr") must inherit property "size" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLOListElement interface: attribute reversed]
|
||||
expected: FAIL
|
||||
|
||||
|
|
228
tests/wpt/meta/html/dom/reflection-grouping.html.ini
vendored
228
tests/wpt/meta/html/dom/reflection-grouping.html.ini
vendored
|
@ -383,234 +383,6 @@
|
|||
[hr.tabIndex: IDL set to -2147483648]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: typeof IDL attribute]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: IDL get with DOM attribute unset]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: setAttribute() to ""]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: setAttribute() to " foo "]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: setAttribute() to undefined]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: setAttribute() to null]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: setAttribute() to 7]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: setAttribute() to 1.5]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: setAttribute() to "5%"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: setAttribute() to "+100"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: setAttribute() to ".5"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: setAttribute() to true]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: setAttribute() to false]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: setAttribute() to object "[object Object\]"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: setAttribute() to NaN]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: setAttribute() to Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: setAttribute() to -Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: setAttribute() to "\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: setAttribute() to object "test-toString"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: setAttribute() to object "test-valueOf"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: setAttribute() to "noShade"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: IDL set to ""]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: IDL set to " foo "]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: IDL set to undefined]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: IDL set to null]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: IDL set to 7]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: IDL set to 1.5]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: IDL set to "5%"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: IDL set to "+100"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: IDL set to ".5"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: IDL set to false]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: IDL set to object "[object Object\]"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: IDL set to NaN]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: IDL set to Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: IDL set to -Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: IDL set to "\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: IDL set to object "test-toString"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.noShade: IDL set to object "test-valueOf"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: typeof IDL attribute]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: IDL get with DOM attribute unset]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: setAttribute() to ""]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: setAttribute() to undefined]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: setAttribute() to 7]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: setAttribute() to 1.5]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: setAttribute() to "5%"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: setAttribute() to "+100"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: setAttribute() to ".5"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: setAttribute() to true]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: setAttribute() to false]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: setAttribute() to object "[object Object\]"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: setAttribute() to NaN]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: setAttribute() to Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: setAttribute() to -Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: setAttribute() to "\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: setAttribute() to null]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: setAttribute() to object "test-toString"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: setAttribute() to object "test-valueOf"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: IDL set to ""]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: IDL set to undefined]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: IDL set to 7]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: IDL set to 1.5]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: IDL set to "5%"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: IDL set to "+100"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: IDL set to ".5"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: IDL set to true]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: IDL set to false]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: IDL set to object "[object Object\]"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: IDL set to NaN]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: IDL set to Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: IDL set to -Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: IDL set to "\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: IDL set to null]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: IDL set to object "test-toString"]
|
||||
expected: FAIL
|
||||
|
||||
[hr.size: IDL set to object "test-valueOf"]
|
||||
expected: FAIL
|
||||
|
||||
[pre.accessKey: typeof IDL attribute]
|
||||
expected: FAIL
|
||||
|
||||
|
|
20
tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size-ref.html
vendored
Normal file
20
tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size-ref.html
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
#foo {
|
||||
height: 50px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
#bar {
|
||||
border-bottom-width: 0px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<hr id="foo">
|
||||
<hr id="bar">
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
hr {
|
||||
border-width: 25px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<hr color="black">
|
||||
<hr color="totally-not-a-color">
|
||||
<hr noshade>
|
||||
<hr color="black" noshade>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-hr-element-2" />
|
||||
<title>hr elements: Tests behaviour of a size attribute with color/noshade attributes present</title>
|
||||
<link rel="author" title="Simon Wülker" href="mailto:simon.wuelker@arcor.de">
|
||||
<link rel="match" href="/html/rendering/non-replaced-elements/the-hr-element-0/size-with-color-or-noshade-ref.html">
|
||||
<meta name="assert" content="This checks that the size attribute of a hr element changes the border widths when color/noshade attributes are present">
|
||||
<body>
|
||||
<hr size=50 color="black">
|
||||
<hr size=50 color="totally-not-a-color">
|
||||
<hr size=50 noshade>
|
||||
<hr size=50 color="black" noshade>
|
||||
</body>
|
||||
</html>
|
||||
|
13
tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size.html
vendored
Normal file
13
tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size.html
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-hr-element-2" />
|
||||
<title>hr elements: Tests behaviour of a size attribute without color/noshade attributes</title>
|
||||
<link rel="author" title="Simon Wülker" href="mailto:simon.wuelker@arcor.de">
|
||||
<link rel="match" href="/html/rendering/non-replaced-elements/the-hr-element-0/size-ref.html">
|
||||
<meta name="assert" content="This checks that the size attribute of a hr element changes its height.">
|
||||
<body>
|
||||
<hr size=50>
|
||||
<hr size=1>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue