зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1562257 part 4. Fix style mapping of hspace and vspace attributes to match the spec. r=mccr8
Per spec, "hspace" and "vspace" are parsed as dimension attributes and are supported on the following elements: embed, iframe, img, object, <input type="image">, marquee. Except no one implements this for iframe. https://github.com/whatwg/html/issues/4742 tracks the spec changing accordingly. As far as hspace/vpace on <table> go, Safari supports them in both quirks and standards mode, while Chrome doesn't support them in either mode. The HTML spec doesn't have them supported at all, and neither does the quirks mode spec, so I'm removing the quirks-only support we had to align with the specs and Chrome. Differential Revision: https://phabricator.services.mozilla.com/D36375 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
6391a08bef
Коммит
1725cec1ac
|
@ -100,11 +100,15 @@ class HTMLImageElement final : public nsGenericHTMLElement,
|
|||
uint32_t NaturalWidth();
|
||||
uint32_t NaturalHeight();
|
||||
bool Complete();
|
||||
uint32_t Hspace() { return GetUnsignedIntAttr(nsGkAtoms::hspace, 0); }
|
||||
uint32_t Hspace() {
|
||||
return GetDimensionAttrAsUnsignedInt(nsGkAtoms::hspace, 0);
|
||||
}
|
||||
void SetHspace(uint32_t aHspace, ErrorResult& aError) {
|
||||
SetUnsignedIntAttr(nsGkAtoms::hspace, aHspace, 0, aError);
|
||||
}
|
||||
uint32_t Vspace() { return GetUnsignedIntAttr(nsGkAtoms::vspace, 0); }
|
||||
uint32_t Vspace() {
|
||||
return GetDimensionAttrAsUnsignedInt(nsGkAtoms::vspace, 0);
|
||||
}
|
||||
void SetVspace(uint32_t aVspace, ErrorResult& aError) {
|
||||
SetUnsignedIntAttr(nsGkAtoms::vspace, aVspace, 0, aError);
|
||||
}
|
||||
|
|
|
@ -97,9 +97,8 @@ bool HTMLMarqueeElement::ParseAttribute(int32_t aNamespaceID,
|
|||
return aResult.ParseEnumValue(aValue, kDirectionTable, false,
|
||||
kDefaultDirection);
|
||||
}
|
||||
if ((aAttribute == nsGkAtoms::hspace) ||
|
||||
(aAttribute == nsGkAtoms::vspace)) {
|
||||
return aResult.ParseIntWithBounds(aValue, 0);
|
||||
if (aAttribute == nsGkAtoms::hspace || aAttribute == nsGkAtoms::vspace) {
|
||||
return aResult.ParseHTMLDimension(aValue);
|
||||
}
|
||||
|
||||
if (aAttribute == nsGkAtoms::loop) {
|
||||
|
|
|
@ -48,7 +48,9 @@ class HTMLMarqueeElement final : public nsGenericHTMLElement {
|
|||
void SetHeight(const nsAString& aHeight, ErrorResult& aError) {
|
||||
SetHTMLAttr(nsGkAtoms::height, aHeight, aError);
|
||||
}
|
||||
uint32_t Hspace() { return GetUnsignedIntAttr(nsGkAtoms::hspace, 0); }
|
||||
uint32_t Hspace() {
|
||||
return GetDimensionAttrAsUnsignedInt(nsGkAtoms::hspace, 0);
|
||||
}
|
||||
void SetHspace(uint32_t aValue, ErrorResult& aError) {
|
||||
SetUnsignedIntAttr(nsGkAtoms::hspace, aValue, 0, aError);
|
||||
}
|
||||
|
@ -87,7 +89,9 @@ class HTMLMarqueeElement final : public nsGenericHTMLElement {
|
|||
void SetWidth(const nsAString& aWidth, ErrorResult& aError) {
|
||||
SetHTMLAttr(nsGkAtoms::width, aWidth, aError);
|
||||
}
|
||||
uint32_t Vspace() { return GetUnsignedIntAttr(nsGkAtoms::vspace, 0); }
|
||||
uint32_t Vspace() {
|
||||
return GetDimensionAttrAsUnsignedInt(nsGkAtoms::vspace, 0);
|
||||
}
|
||||
void SetVspace(uint32_t aValue, ErrorResult& aError) {
|
||||
SetUnsignedIntAttr(nsGkAtoms::vspace, aValue, 0, aError);
|
||||
}
|
||||
|
|
|
@ -140,7 +140,9 @@ class HTMLObjectElement final : public nsGenericHTMLFormElement,
|
|||
void SetDeclare(bool aValue, ErrorResult& aRv) {
|
||||
SetHTMLBoolAttr(nsGkAtoms::declare, aValue, aRv);
|
||||
}
|
||||
uint32_t Hspace() { return GetUnsignedIntAttr(nsGkAtoms::hspace, 0); }
|
||||
uint32_t Hspace() {
|
||||
return GetDimensionAttrAsUnsignedInt(nsGkAtoms::hspace, 0);
|
||||
}
|
||||
void SetHspace(uint32_t aValue, ErrorResult& aRv) {
|
||||
SetUnsignedIntAttr(nsGkAtoms::hspace, aValue, 0, aRv);
|
||||
}
|
||||
|
@ -150,7 +152,9 @@ class HTMLObjectElement final : public nsGenericHTMLFormElement,
|
|||
void SetStandby(const nsAString& aValue, ErrorResult& aRv) {
|
||||
SetHTMLAttr(nsGkAtoms::standby, aValue, aRv);
|
||||
}
|
||||
uint32_t Vspace() { return GetUnsignedIntAttr(nsGkAtoms::vspace, 0); }
|
||||
uint32_t Vspace() {
|
||||
return GetDimensionAttrAsUnsignedInt(nsGkAtoms::vspace, 0);
|
||||
}
|
||||
void SetVspace(uint32_t aValue, ErrorResult& aRv) {
|
||||
SetUnsignedIntAttr(nsGkAtoms::vspace, aValue, 0, aRv);
|
||||
}
|
||||
|
|
|
@ -832,9 +832,6 @@ bool HTMLTableElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
|||
aAttribute == nsGkAtoms::bordercolor) {
|
||||
return aResult.ParseColor(aValue);
|
||||
}
|
||||
if (aAttribute == nsGkAtoms::hspace || aAttribute == nsGkAtoms::vspace) {
|
||||
return aResult.ParseIntWithBounds(aValue, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return nsGenericHTMLElement::ParseBackgroundAttribute(
|
||||
|
@ -855,8 +852,6 @@ void HTMLTableElement::MapAttributesIntoRule(
|
|||
// which *element* it's matching (style rules should not stop matching
|
||||
// when the display type is changed).
|
||||
|
||||
nsCompatibility mode = aDecls.Document()->GetCompatibilityMode();
|
||||
|
||||
// cellspacing
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::cellspacing);
|
||||
if (value && value->Type() == nsAttrValue::eInteger &&
|
||||
|
@ -875,28 +870,6 @@ void HTMLTableElement::MapAttributesIntoRule(
|
|||
}
|
||||
}
|
||||
|
||||
// hspace is mapped into left and right margin,
|
||||
// vspace is mapped into top and bottom margins
|
||||
// - *** Quirks Mode only ***
|
||||
if (eCompatibility_NavQuirks == mode) {
|
||||
value = aAttributes->GetAttr(nsGkAtoms::hspace);
|
||||
|
||||
if (value && value->Type() == nsAttrValue::eInteger) {
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_margin_left,
|
||||
(float)value->GetIntegerValue());
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_margin_right,
|
||||
(float)value->GetIntegerValue());
|
||||
}
|
||||
|
||||
value = aAttributes->GetAttr(nsGkAtoms::vspace);
|
||||
|
||||
if (value && value->Type() == nsAttrValue::eInteger) {
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_margin_top,
|
||||
(float)value->GetIntegerValue());
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_margin_bottom,
|
||||
(float)value->GetIntegerValue());
|
||||
}
|
||||
}
|
||||
// bordercolor
|
||||
value = aAttributes->GetAttr(nsGkAtoms::bordercolor);
|
||||
nscolor color;
|
||||
|
@ -937,8 +910,7 @@ HTMLTableElement::IsAttributeMapped(const nsAtom* aAttribute) const {
|
|||
static const MappedAttributeEntry attributes[] = {
|
||||
{nsGkAtoms::cellpadding}, {nsGkAtoms::cellspacing},
|
||||
{nsGkAtoms::border}, {nsGkAtoms::width},
|
||||
{nsGkAtoms::height}, {nsGkAtoms::hspace},
|
||||
{nsGkAtoms::vspace},
|
||||
{nsGkAtoms::height},
|
||||
|
||||
{nsGkAtoms::bordercolor},
|
||||
|
||||
|
|
|
@ -1038,11 +1038,11 @@ bool nsGenericHTMLElement::ParseDivAlignValue(const nsAString& aString,
|
|||
bool nsGenericHTMLElement::ParseImageAttribute(nsAtom* aAttribute,
|
||||
const nsAString& aString,
|
||||
nsAttrValue& aResult) {
|
||||
if ((aAttribute == nsGkAtoms::width) || (aAttribute == nsGkAtoms::height)) {
|
||||
if (aAttribute == nsGkAtoms::width || aAttribute == nsGkAtoms::height ||
|
||||
aAttribute == nsGkAtoms::hspace || aAttribute == nsGkAtoms::vspace) {
|
||||
return aResult.ParseHTMLDimension(aString);
|
||||
}
|
||||
if ((aAttribute == nsGkAtoms::hspace) || (aAttribute == nsGkAtoms::vspace) ||
|
||||
(aAttribute == nsGkAtoms::border)) {
|
||||
if (aAttribute == nsGkAtoms::border) {
|
||||
return aResult.ParseIntWithBounds(aString, 0);
|
||||
}
|
||||
return false;
|
||||
|
@ -1247,33 +1247,15 @@ void nsGenericHTMLElement::MapImageMarginAttributeInto(
|
|||
// hspace: value
|
||||
value = aAttributes->GetAttr(nsGkAtoms::hspace);
|
||||
if (value) {
|
||||
if (value->Type() == nsAttrValue::eInteger) {
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_margin_left,
|
||||
(float)value->GetIntegerValue());
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_margin_right,
|
||||
(float)value->GetIntegerValue());
|
||||
} else if (value->Type() == nsAttrValue::ePercent) {
|
||||
aDecls.SetPercentValueIfUnset(eCSSProperty_margin_left,
|
||||
value->GetPercentValue());
|
||||
aDecls.SetPercentValueIfUnset(eCSSProperty_margin_right,
|
||||
value->GetPercentValue());
|
||||
}
|
||||
MapDimensionAttributeInto(aDecls, eCSSProperty_margin_left, *value);
|
||||
MapDimensionAttributeInto(aDecls, eCSSProperty_margin_right, *value);
|
||||
}
|
||||
|
||||
// vspace: value
|
||||
value = aAttributes->GetAttr(nsGkAtoms::vspace);
|
||||
if (value) {
|
||||
if (value->Type() == nsAttrValue::eInteger) {
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_margin_top,
|
||||
(float)value->GetIntegerValue());
|
||||
aDecls.SetPixelValueIfUnset(eCSSProperty_margin_bottom,
|
||||
(float)value->GetIntegerValue());
|
||||
} else if (value->Type() == nsAttrValue::ePercent) {
|
||||
aDecls.SetPercentValueIfUnset(eCSSProperty_margin_top,
|
||||
value->GetPercentValue());
|
||||
aDecls.SetPercentValueIfUnset(eCSSProperty_margin_bottom,
|
||||
value->GetPercentValue());
|
||||
}
|
||||
MapDimensionAttributeInto(aDecls, eCSSProperty_margin_top, *value);
|
||||
MapDimensionAttributeInto(aDecls, eCSSProperty_margin_bottom, *value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -142,3 +142,83 @@
|
|||
[<tr height="0px"> mapping to height]
|
||||
expected: FAIL
|
||||
bug: https://github.com/whatwg/html/issues/4716
|
||||
|
||||
[<embed hspace="200.%"> mapping to marginLeft]
|
||||
expected: FAIL
|
||||
bug: https://github.com/whatwg/html/issues/4736
|
||||
|
||||
[<embed hspace="200.%"> mapping to marginRight]
|
||||
expected: FAIL
|
||||
bug: https://github.com/whatwg/html/issues/4736
|
||||
|
||||
[<embed vspace="200.%"> mapping to marginTop]
|
||||
expected: FAIL
|
||||
bug: https://github.com/whatwg/html/issues/4736
|
||||
|
||||
[<embed vspace="200.%"> mapping to marginBottom]
|
||||
expected: FAIL
|
||||
bug: https://github.com/whatwg/html/issues/4736
|
||||
|
||||
[<img hspace="200.%"> mapping to marginLeft]
|
||||
expected: FAIL
|
||||
bug: https://github.com/whatwg/html/issues/4736
|
||||
|
||||
[<img hspace="200.%"> mapping to marginRight]
|
||||
expected: FAIL
|
||||
bug: https://github.com/whatwg/html/issues/4736
|
||||
|
||||
[<img vspace="200.%"> mapping to marginTop]
|
||||
expected: FAIL
|
||||
bug: https://github.com/whatwg/html/issues/4736
|
||||
|
||||
[<img vspace="200.%"> mapping to marginBottom]
|
||||
expected: FAIL
|
||||
bug: https://github.com/whatwg/html/issues/4736
|
||||
|
||||
[<object hspace="200.%"> mapping to marginLeft]
|
||||
expected: FAIL
|
||||
bug: https://github.com/whatwg/html/issues/4736
|
||||
|
||||
[<object hspace="200.%"> mapping to marginRight]
|
||||
expected: FAIL
|
||||
bug: https://github.com/whatwg/html/issues/4736
|
||||
|
||||
[<object vspace="200.%"> mapping to marginTop]
|
||||
expected: FAIL
|
||||
bug: https://github.com/whatwg/html/issues/4736
|
||||
|
||||
[<object vspace="200.%"> mapping to marginBottom]
|
||||
expected: FAIL
|
||||
bug: https://github.com/whatwg/html/issues/4736
|
||||
|
||||
[<input hspace="200.%"> mapping to marginLeft]
|
||||
expected: FAIL
|
||||
bug: https://github.com/whatwg/html/issues/4736
|
||||
|
||||
[<input hspace="200.%"> mapping to marginRight]
|
||||
expected: FAIL
|
||||
bug: https://github.com/whatwg/html/issues/4736
|
||||
|
||||
[<input vspace="200.%"> mapping to marginTop]
|
||||
expected: FAIL
|
||||
bug: https://github.com/whatwg/html/issues/4736
|
||||
|
||||
[<input vspace="200.%"> mapping to marginBottom]
|
||||
expected: FAIL
|
||||
bug: https://github.com/whatwg/html/issues/4736
|
||||
|
||||
[<marquee hspace="200.%"> mapping to marginLeft]
|
||||
expected: FAIL
|
||||
bug: https://github.com/whatwg/html/issues/4736
|
||||
|
||||
[<marquee hspace="200.%"> mapping to marginRight]
|
||||
expected: FAIL
|
||||
bug: https://github.com/whatwg/html/issues/4736
|
||||
|
||||
[<marquee vspace="200.%"> mapping to marginTop]
|
||||
expected: FAIL
|
||||
bug: https://github.com/whatwg/html/issues/4736
|
||||
|
||||
[<marquee vspace="200.%"> mapping to marginBottom]
|
||||
expected: FAIL
|
||||
bug: https://github.com/whatwg/html/issues/4736
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
[table-vspace-hspace.html]
|
||||
[table vspace hspace (quirks mode)]
|
||||
expected: FAIL
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[space.html]
|
||||
expected: FAIL
|
|
@ -134,6 +134,26 @@ const tests = [
|
|||
// https://github.com/whatwg/html/issues/4717 tracks the fact that for the
|
||||
// <col width> case that "0 is valid" boolean should probably be true.
|
||||
[ newElem("col"), "width", "width", false ],
|
||||
[ newElem("embed"), "hspace", "marginLeft", true ],
|
||||
[ newElem("embed"), "hspace", "marginRight", true ],
|
||||
[ newElem("embed"), "vspace", "marginTop", true ],
|
||||
[ newElem("embed"), "vspace", "marginBottom", true ],
|
||||
[ newElem("img"), "hspace", "marginLeft", true ],
|
||||
[ newElem("img"), "hspace", "marginRight", true ],
|
||||
[ newElem("img"), "vspace", "marginTop", true ],
|
||||
[ newElem("img"), "vspace", "marginBottom", true ],
|
||||
[ newElem("object"), "hspace", "marginLeft", true ],
|
||||
[ newElem("object"), "hspace", "marginRight", true ],
|
||||
[ newElem("object"), "vspace", "marginTop", true ],
|
||||
[ newElem("object"), "vspace", "marginBottom", true ],
|
||||
[ newImageInput(), "hspace", "marginLeft", true ],
|
||||
[ newImageInput(), "hspace", "marginRight", true ],
|
||||
[ newImageInput(), "vspace", "marginTop", true ],
|
||||
[ newImageInput(), "vspace", "marginBottom", true ],
|
||||
[ newElem("marquee"), "hspace", "marginLeft", true ],
|
||||
[ newElem("marquee"), "hspace", "marginRight", true ],
|
||||
[ newElem("marquee"), "vspace", "marginTop", true ],
|
||||
[ newElem("marquee"), "vspace", "marginBottom", true ],
|
||||
];
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>Test handling of attributes that should not be mapped into style, but
|
||||
incorrectly were in some browsers</title>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<body>
|
||||
<div id="container" style="display: none"></div>
|
||||
<iframe></iframe>
|
||||
<script>
|
||||
/*
|
||||
* We wand to test both quirks and standards mode. We can use the fact that
|
||||
* our document is in standards mode and the about:blank iframe we have is in
|
||||
* quirks mode.
|
||||
*/
|
||||
test(() => {
|
||||
assert_equals(document.compatMode, "CSS1Compat")
|
||||
}, "We should be in standards mode");
|
||||
const container = document.getElementById("container");
|
||||
|
||||
const frameDoc = document.querySelector("iframe").contentDocument;
|
||||
test(() => {
|
||||
assert_equals(frameDoc.compatMode, "BackCompat")
|
||||
}, "Subframe should be in quirks mode");
|
||||
const frameContainer = frameDoc.createElement("div");
|
||||
frameContainer.style.display = "none";
|
||||
frameDoc.body.appendChild(frameContainer);
|
||||
|
||||
function newElem(name) {
|
||||
return (parent) =>
|
||||
parent.appendChild(parent.ownerDocument.createElement(name));
|
||||
}
|
||||
|
||||
/*
|
||||
* Array of tests. Each test consists of the following information:
|
||||
*
|
||||
* 1) An element creation function, which takes a parent element as an
|
||||
* argument.
|
||||
* 2) The name of the attribute to set
|
||||
* 3) The name of the CSS property to get.
|
||||
*/
|
||||
const tests = [
|
||||
[ newElem("table"), "hspace", "marginLeft" ],
|
||||
[ newElem("table"), "hspace", "marginRight" ],
|
||||
[ newElem("table"), "vspace", "marginTop" ],
|
||||
[ newElem("table"), "vspace", "marginBottom" ],
|
||||
];
|
||||
|
||||
function style(element) {
|
||||
return element.ownerDocument.defaultView.getComputedStyle(element);
|
||||
}
|
||||
|
||||
for (let [ctor, attr, prop] of tests) {
|
||||
for (let parent of [container, frameContainer]) {
|
||||
let elem = ctor(parent);
|
||||
test(function() {
|
||||
let default_elem = ctor(parent);
|
||||
this.add_cleanup(() => {
|
||||
elem.remove();
|
||||
default_elem.remove();
|
||||
});
|
||||
elem.setAttribute(attr, "200");
|
||||
assert_equals(elem.getAttribute(attr), "200");
|
||||
assert_equals(style(elem)[prop], style(default_elem)[prop]);
|
||||
}, `<${elem.localName} ${attr}> should not be mapped to style ${prop} in ${parent.ownerDocument.compatMode} mode`);
|
||||
}
|
||||
}
|
||||
</script>
|
Загрузка…
Ссылка в новой задаче