Skip to content

Commit

Permalink
Add width and height content attributes to <model>
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=243974
rdar://99014926

Reviewed by Antoine Quint.

For consistency with <img> and <video>, <model> should have width and
height content attributes that set presentational style for the width
and height properties.

* LayoutTests/model-element/model-element-width-height-expected.txt: Added.
* LayoutTests/model-element/model-element-width-height-visual-expected.html: Added.
* LayoutTests/model-element/model-element-width-height-visual.html: Added.
* LayoutTests/model-element/model-element-width-height.html: Added.
* Source/WebCore/Modules/model-element/HTMLModelElement.cpp:
(WebCore::HTMLModelElement::collectPresentationalHintsForAttribute):
(WebCore::HTMLModelElement::hasPresentationalHintsForAttribute const):
* Source/WebCore/Modules/model-element/HTMLModelElement.h:
* Source/WebCore/Modules/model-element/HTMLModelElement.idl:

Canonical link: https://commits.webkit.org/257294@main
  • Loading branch information
heycam committed Dec 2, 2022
1 parent a9cc8e3 commit cf600d6
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

PASS HTMLModelElement has width and height properties
PASS HTMLModelElement width and height properties reflect width and height attribute values
PASS <model> width and height attributes reflect HTMLModelElement width and height properties
PASS <model> has default CSS size when no width or height attribute is used
PASS <model> width and height attributes influence automatic size
PASS <model> width and height attributes do not win over non-auto width and height property values
PASS <model> size computation takes aspect-ratio property into account

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!DOCTYPE html>
<model style="width: 200px; height: 400px; background-color: blue;"></model>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!DOCTYPE html>
<model width="200" height="400" style="background-color: blue;"></model>
66 changes: 66 additions & 0 deletions LayoutTests/model-element/model-element-width-height.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<!DOCTYPE html><!-- webkit-test-runner [ ModelElementEnabled=true ] -->
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<body>
<script>
test(() => {
const model = document.createElement("model");
assert_idl_attribute(model, "width", "width is defined");
assert_idl_attribute(model, "height", "width is defined");
}, "HTMLModelElement has width and height properties");

test(() => {
const model = document.createElement("model");
model.setAttribute("width", "100");
model.setAttribute("height", "200");
assert_equals(model.width, 100, "width attribute value is reflected by HTMLModelElement width property");
assert_equals(model.height, 200, "height attribute value is reflected by HTMLModelElement height property");
}, "HTMLModelElement width and height properties reflect width and height attribute values");

test(() => {
const model = document.createElement("model");
model.width = 100;
model.height = 200;
assert_equals(model.getAttribute("width"), "100", "HTMLModelElement width property value is reflected by width attribute");
assert_equals(model.getAttribute("height"), "200", "HTMLModelElement height property value is reflected by height attribute");
}, "<model> width and height attributes reflect HTMLModelElement width and height properties");

test(() => {
const model = document.createElement("model");
document.body.append(model);
assert_equals(getComputedStyle(model).width, "300px", "default width is 300");
assert_equals(getComputedStyle(model).height, "150px", "default height is 150");
model.remove();
}, "<model> has default CSS size when no width or height attribute is used");

test(() => {
const model = document.createElement("model");
model.width = "400";
model.height = "100";
document.body.append(model);
assert_equals(getComputedStyle(model).width, "400px", "automatic size is influenced by width attribute");
assert_equals(getComputedStyle(model).height, "100px", "automatic size is influenced by height attribute");
model.remove();
}, "<model> width and height attributes influence automatic size");

test(() => {
const model = document.createElement("model");
model.style.width = "200px";
model.style.height = "50px";
model.width = "400";
model.height = "100";
document.body.append(model);
assert_equals(getComputedStyle(model).width, "200px", "non-auto width value wins over width attribute");
assert_equals(getComputedStyle(model).height, "50px", "non-auto height value wins over height attribute");
model.remove();
}, "<model> width and height attributes do not win over non-auto width and height property values");

test(() => {
const model = document.createElement("model");
model.width = 200;
model.style.aspectRatio = "1 / 2";
document.body.append(model);
assert_equals(getComputedStyle(model).height, "400px", "aspect-ratio influences size");
model.remove();
}, "<model> size computation takes aspect-ratio property into account");
</script>
21 changes: 21 additions & 0 deletions Source/WebCore/Modules/model-element/HTMLModelElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@

namespace WebCore {

using namespace HTMLNames;

WTF_MAKE_ISO_ALLOCATED_IMPL(HTMLModelElement);

HTMLModelElement::HTMLModelElement(const QualifiedName& tagName, Document& document)
Expand Down Expand Up @@ -678,6 +680,25 @@ String HTMLModelElement::inlinePreviewUUIDForTesting() const
}
#endif

void HTMLModelElement::collectPresentationalHintsForAttribute(const QualifiedName& name, const AtomString& value, MutableStyleProperties& style)
{
if (name == widthAttr) {
addHTMLLengthToStyle(style, CSSPropertyWidth, value);
applyAspectRatioFromWidthAndHeightAttributesToStyle(value, attributeWithoutSynchronization(heightAttr), style);
} else if (name == heightAttr) {
addHTMLLengthToStyle(style, CSSPropertyHeight, value);
applyAspectRatioFromWidthAndHeightAttributesToStyle(attributeWithoutSynchronization(widthAttr), value, style);
} else
HTMLElement::collectPresentationalHintsForAttribute(name, value, style);
}

bool HTMLModelElement::hasPresentationalHintsForAttribute(const QualifiedName& name) const
{
if (name == widthAttr || name == heightAttr)
return true;
return HTMLElement::hasPresentationalHintsForAttribute(name);
}

}

#endif // ENABLE(MODEL_ELEMENT)
4 changes: 4 additions & 0 deletions Source/WebCore/Modules/model-element/HTMLModelElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ class HTMLModelElement final : public HTMLElement, private CachedRawResourceClie
void didMoveToNewDocument(Document& oldDocument, Document& newDocument) final;
void attributeChanged(const QualifiedName&, const AtomString& oldValue, const AtomString& newValue, AttributeModificationReason) final;

// StyledElement
bool hasPresentationalHintsForAttribute(const QualifiedName&) const final;
void collectPresentationalHintsForAttribute(const QualifiedName&, const AtomString&, MutableStyleProperties&) final;

// Rendering overrides.
RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final;
void didAttachRenderers() final;
Expand Down
2 changes: 2 additions & 0 deletions Source/WebCore/Modules/model-element/HTMLModelElement.idl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
Exposed=Window,
JSGenerateToNativeObject
] interface HTMLModelElement : HTMLElement {
[CEReactions=NotNeeded, Reflect] attribute unsigned long width;
[CEReactions=NotNeeded, Reflect] attribute unsigned long height;
[URL] readonly attribute USVString currentSrc;

readonly attribute boolean complete;
Expand Down

0 comments on commit cf600d6

Please sign in to comment.