Bug 1467722: Do not throw when we don't have a style, but just return an empty style. r?heycam
We return '0' for the length, and "" for every declaration. This matches other
browsers and the spec in the "no style" behavior.
Of course we don't claim not to have a style for every case the spec says, but
that will come later, given that's a much more risky change.
This doesn't make any case where we returned something useful return something
less useful, but stops null from getting returned, and returns the empty string
which matches other browsers when they cannot return a style.
MozReview-Commit-ID: 7Sc7HL5CgZU
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -404,24 +404,26 @@ nsComputedDOMStyle::SetCssText(const nsA
ErrorResult& aRv)
{
aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
}
uint32_t
nsComputedDOMStyle::Length()
{
- uint32_t length = GetComputedStyleMap()->Length();
-
// Make sure we have up to date style so that we can include custom
// properties.
UpdateCurrentStyleSources(false);
- if (mComputedStyle) {
- length += Servo_GetCustomPropertiesCount(mComputedStyle);
- }
+ if (!mComputedStyle) {
+ return 0;
+ }
+
+ uint32_t length =
+ GetComputedStyleMap()->Length() +
+ Servo_GetCustomPropertiesCount(mComputedStyle);
ClearCurrentStyleSources();
return length;
}
css::Rule*
nsComputedDOMStyle::GetParentRule()
@@ -444,17 +446,17 @@ nsComputedDOMStyle::GetPropertyValue(con
if (!entry) {
return NS_OK;
}
}
const bool layoutFlushIsNeeded = entry && entry->IsLayoutFlushNeeded();
UpdateCurrentStyleSources(layoutFlushIsNeeded);
if (!mComputedStyle) {
- return NS_ERROR_NOT_AVAILABLE;
+ return NS_OK;
}
auto cleanup = mozilla::MakeScopeExit([&] {
ClearCurrentStyleSources();
});
if (!entry) {
MOZ_ASSERT(nsCSSProps::IsCustomPropertyName(aPropertyName));
--- a/testing/web-platform/tests/css/cssom/getComputedStyle-detached-subtree.html
+++ b/testing/web-platform/tests/css/cssom/getComputedStyle-detached-subtree.html
@@ -7,32 +7,36 @@
<script src=/resources/testharnessreport.js></script>
<div id="host">
<div id="non-slotted">
<div id="non-slotted-descendant"></div>
</div>
</div>
<iframe srcdoc="<html></html>" style="display: none"></iframe>
<script>
-function testNoComputedStyle(element, description) {
+function testNoComputedStyle(element, description, global) {
test(function() {
assert_true(!!element);
- let style = getComputedStyle(element);
+ let style = (global ? global : window).getComputedStyle(element);
assert_true(!!style);
assert_true(style.length === 0);
assert_equals(style.color, "");
}, `getComputedStyle returns no style for ${description}`);
}
let detached = document.createElement('div');
testNoComputedStyle(detached, "detached element");
testNoComputedStyle(document.querySelector('iframe').contentDocument.documentElement,
"element in non-rendered iframe (display: none)");
+testNoComputedStyle(document.querySelector('iframe').contentDocument.documentElement,
+ "element in non-rendered iframe (display: none) from iframe's window",
+ document.querySelector('iframe').contentWindow);
+
host.attachShadow({ mode: "open" });
testNoComputedStyle(document.getElementById('non-slotted'),
"element outside the flat tree");
testNoComputedStyle(document.getElementById('non-slotted-descendant'),
"descendant outside the flat tree");
let shadowRoot = detached.attachShadow({ mode: "open" });