Bug 1281135 - Make <link disabled> work and HTMLLinkElement.disabled reflect that attribute. r=bzbarsky

...instead of forwarding to the sheet like HTMLStyleElement does.

I've proposed this behavior in:

  https://github.com/whatwg/html/issues/3840#issuecomment-480894419

I think this is one of the sane behaviors we can have, what Blink / WebKit do
makes no sense to me.

Alternative potentially-sane behavior is making the initial value of the
stylesheet's disabled bit the same as the content attribute, and both reflect
and forward the attribute from the setter.

That means that setAttribute does something different than setting `disabled`,
which means that you can get into all sorts of funny states when reloading the
sheet... So I rather not do that.

Differential Revision: https://phabricator.services.mozilla.com/D26573

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Emilio Cobos Álvarez 2019-04-19 13:31:05 +00:00
Родитель 6828479873
Коммит ca33d8548f
24 изменённых файлов: 361 добавлений и 46 удалений

Просмотреть файл

@ -59,7 +59,7 @@ async function testBody(testRoot) {
stateChanged =
ContentTaskUtils.waitForEvent(this, "StyleSheetApplicableStateChanged", true);
link.disabled = true;
link.sheet.disabled = true;
evt = await stateChanged;
is(evt.type, "StyleSheetApplicableStateChanged", "evt.type has expected value");

Просмотреть файл

@ -758,6 +758,7 @@ nsresult nsContentSink::ProcessStyleLinkFromHeader(
aMedia,
aAlternate ? Loader::HasAlternateRel::Yes : Loader::HasAlternateRel::No,
Loader::IsInline::No,
Loader::IsExplicitlyEnabled::No,
};
auto loadResultOrErr =

Просмотреть файл

@ -24,26 +24,37 @@ class nsIURI;
class nsIStyleSheetLinkingElement : public nsISupports {
public:
enum class ForceUpdate {
Yes,
enum class ForceUpdate : uint8_t {
No,
Yes,
};
enum class Completed {
Yes,
enum class Completed : uint8_t {
No,
Yes,
};
enum class HasAlternateRel { Yes, No };
enum class IsAlternate {
Yes,
enum class HasAlternateRel : uint8_t {
No,
Yes,
};
enum class IsInline { Yes, No };
enum class IsAlternate : uint8_t {
No,
Yes,
};
enum class MediaMatched {
enum class IsInline : uint8_t {
No,
Yes,
};
enum class IsExplicitlyEnabled : uint8_t {
No,
Yes,
};
enum class MediaMatched : uint8_t {
Yes,
No,
};
@ -90,14 +101,14 @@ class nsIStyleSheetLinkingElement : public nsISupports {
bool mHasAlternateRel;
bool mIsInline;
IsExplicitlyEnabled mIsExplicitlyEnabled;
SheetInfo(const mozilla::dom::Document&, nsIContent*,
already_AddRefed<nsIURI> aURI,
already_AddRefed<nsIPrincipal> aTriggeringPrincipal,
mozilla::net::ReferrerPolicy aReferrerPolicy,
mozilla::CORSMode aCORSMode, const nsAString& aTitle,
const nsAString& aMedia, HasAlternateRel aHasAlternateRel,
IsInline aIsInline);
mozilla::net::ReferrerPolicy aReferrerPolicy, mozilla::CORSMode,
const nsAString& aTitle, const nsAString& aMedia, HasAlternateRel,
IsInline, IsExplicitlyEnabled);
~SheetInfo();
};

Просмотреть файл

@ -40,7 +40,8 @@ nsStyleLinkElement::SheetInfo::SheetInfo(
already_AddRefed<nsIPrincipal> aTriggeringPrincipal,
mozilla::net::ReferrerPolicy aReferrerPolicy, mozilla::CORSMode aCORSMode,
const nsAString& aTitle, const nsAString& aMedia,
HasAlternateRel aHasAlternateRel, IsInline aIsInline)
HasAlternateRel aHasAlternateRel, IsInline aIsInline,
IsExplicitlyEnabled aIsExplicitlyEnabled)
: mContent(aContent),
mURI(aURI),
mTriggeringPrincipal(aTriggeringPrincipal),
@ -49,7 +50,8 @@ nsStyleLinkElement::SheetInfo::SheetInfo(
mTitle(aTitle),
mMedia(aMedia),
mHasAlternateRel(aHasAlternateRel == HasAlternateRel::Yes),
mIsInline(aIsInline == IsInline::Yes) {
mIsInline(aIsInline == IsInline::Yes),
mIsExplicitlyEnabled(aIsExplicitlyEnabled) {
MOZ_ASSERT(!mIsInline || aContent);
MOZ_ASSERT_IF(aContent, aContent->OwnerDoc() == &aDocument);

Просмотреть файл

@ -85,12 +85,18 @@ NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(HTMLLinkElement,
NS_IMPL_ELEMENT_CLONE(HTMLLinkElement)
bool HTMLLinkElement::Disabled() {
bool HTMLLinkElement::Disabled() const {
if (StaticPrefs::dom_link_disabled_attribute_enabled()) {
return GetBoolAttr(nsGkAtoms::disabled);
}
StyleSheet* ss = GetSheet();
return ss && ss->Disabled();
}
void HTMLLinkElement::SetDisabled(bool aDisabled) {
void HTMLLinkElement::SetDisabled(bool aDisabled, ErrorResult& aRv) {
if (StaticPrefs::dom_link_disabled_attribute_enabled()) {
return SetHTMLBoolAttr(nsGkAtoms::disabled, aDisabled, aRv);
}
if (StyleSheet* ss = GetSheet()) {
ss->SetDisabled(aDisabled);
}
@ -314,7 +320,9 @@ nsresult HTMLLinkElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
(aName == nsGkAtoms::href || aName == nsGkAtoms::rel ||
aName == nsGkAtoms::title || aName == nsGkAtoms::media ||
aName == nsGkAtoms::type || aName == nsGkAtoms::as ||
aName == nsGkAtoms::crossorigin)) {
aName == nsGkAtoms::crossorigin ||
(aName == nsGkAtoms::disabled &&
StaticPrefs::dom_link_disabled_attribute_enabled()))) {
bool dropSheet = false;
if (aName == nsGkAtoms::rel) {
nsAutoString value;
@ -338,18 +346,25 @@ nsresult HTMLLinkElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
const bool forceUpdate = dropSheet || aName == nsGkAtoms::title ||
aName == nsGkAtoms::media ||
aName == nsGkAtoms::type;
aName == nsGkAtoms::type ||
aName == nsGkAtoms::disabled;
Unused << UpdateStyleSheetInternal(
nullptr, nullptr, forceUpdate ? ForceUpdate::Yes : ForceUpdate::No);
}
} else {
// Since removing href or rel makes us no longer link to a
// stylesheet, force updates for those too.
if (aNameSpaceID == kNameSpaceID_None) {
if (aName == nsGkAtoms::disabled &&
StaticPrefs::dom_link_disabled_attribute_enabled()) {
mExplicitlyEnabled = true;
}
// Since removing href or rel makes us no longer link to a stylesheet,
// force updates for those too.
if (aName == nsGkAtoms::href || aName == nsGkAtoms::rel ||
aName == nsGkAtoms::title || aName == nsGkAtoms::media ||
aName == nsGkAtoms::type) {
aName == nsGkAtoms::type ||
(aName == nsGkAtoms::disabled &&
StaticPrefs::dom_link_disabled_attribute_enabled())) {
Unused << UpdateStyleSheetInternal(nullptr, nullptr, ForceUpdate::Yes);
}
if ((aName == nsGkAtoms::as || aName == nsGkAtoms::type ||
@ -415,6 +430,10 @@ Maybe<nsStyleLinkElement::SheetInfo> HTMLLinkElement::GetStyleSheetInfo() {
return Nothing();
}
if (StaticPrefs::dom_link_disabled_attribute_enabled() && Disabled()) {
return Nothing();
}
nsAutoString title;
nsAutoString media;
GetTitleAndMediaForElement(*this, title, media);
@ -444,6 +463,7 @@ Maybe<nsStyleLinkElement::SheetInfo> HTMLLinkElement::GetStyleSheetInfo() {
media,
alternate ? HasAlternateRel::Yes : HasAlternateRel::No,
IsInline::No,
mExplicitlyEnabled ? IsExplicitlyEnabled::Yes : IsExplicitlyEnabled::No,
});
}

Просмотреть файл

@ -78,8 +78,8 @@ class HTMLLinkElement final : public nsGenericHTMLElement,
virtual bool HasDeferredDNSPrefetchRequest() override;
// WebIDL
bool Disabled();
void SetDisabled(bool aDisabled);
bool Disabled() const;
void SetDisabled(bool aDisabled, ErrorResult& aRv);
void GetHref(nsAString& aValue) {
GetURIAttr(nsGkAtoms::href, nullptr, aValue);
@ -170,8 +170,14 @@ class HTMLLinkElement final : public nsGenericHTMLElement,
// nsStyleLinkElement
Maybe<SheetInfo> GetStyleSheetInfo() final;
protected:
RefPtr<nsDOMTokenList> mRelList;
// The "explicitly enabled" flag. This flag is set whenever the `disabled`
// attribute is explicitly unset, and makes alternate stylesheets not be
// disabled by default anymore.
//
// See https://github.com/whatwg/html/issues/3840#issuecomment-481034206.
bool mExplicitlyEnabled = false;
};
} // namespace dom

Просмотреть файл

@ -45,7 +45,7 @@ NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(HTMLStyleElement,
NS_IMPL_ELEMENT_CLONE(HTMLStyleElement)
bool HTMLStyleElement::Disabled() {
bool HTMLStyleElement::Disabled() const {
StyleSheet* ss = GetSheet();
return ss && ss->Disabled();
}
@ -186,6 +186,7 @@ Maybe<nsStyleLinkElement::SheetInfo> HTMLStyleElement::GetStyleSheetInfo() {
media,
HasAlternateRel::No,
IsInline::Yes,
IsExplicitlyEnabled::No,
});
}

Просмотреть файл

@ -56,7 +56,7 @@ class HTMLStyleElement final : public nsGenericHTMLElement,
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
bool Disabled();
bool Disabled() const;
void SetDisabled(bool aDisabled);
void GetMedia(nsAString& aValue) { GetHTMLAttr(nsGkAtoms::media, aValue); }
void SetMedia(const nsAString& aMedia, ErrorResult& aError) {

Просмотреть файл

@ -197,6 +197,7 @@ Maybe<nsStyleLinkElement::SheetInfo> SVGStyleElement::GetStyleSheetInfo() {
media,
HasAlternateRel::No,
IsInline::Yes,
IsExplicitlyEnabled::No,
});
}

Просмотреть файл

@ -14,7 +14,7 @@
// http://www.whatwg.org/specs/web-apps/current-work/#the-link-element
[HTMLConstructor]
interface HTMLLinkElement : HTMLElement {
[Pure]
[CEReactions, SetterThrows, Pure]
attribute boolean disabled;
[CEReactions, SetterNeedsSubjectPrincipal=NonSystem, SetterThrows, Pure]
attribute DOMString href;

Просмотреть файл

@ -137,6 +137,7 @@ XMLStylesheetProcessingInstruction::GetStyleSheetInfo() {
media,
alternate ? HasAlternateRel::Yes : HasAlternateRel::No,
IsInline::No,
IsExplicitlyEnabled::No,
});
}

Просмотреть файл

@ -4,7 +4,7 @@
<style>
div { height: 20px }
#test1 {
background-color: red;
background-color: green;
}
#test2 {
background-color: red;
@ -17,7 +17,7 @@
}
</style>
<link href="data:text/css;charset=utf-8," title="narrow" rel="stylesheet" type="text/css" />
<link href="data:text/css;charset=utf-8,%23test1%20%7Bbackground-color%3A%20green%3B%7D" title="medium" rel="alternate stylesheet" type="text/css" />
<link href="data:text/css;charset=utf-8,%23test1%20%7Bbackground-color%3A%20red%3B%7D" title="medium" rel="alternate stylesheet" type="text/css" />
<link href="data:text/css;charset=utf-8,%23test2%20%7Bbackground-color%3A%20green%3B%7D" type="text/css" />
<link href="data:text/css;charset=utf-8,%23test3%20%7Bbackground-color%3A%20red%3B%7D" rel="stylesheet" type="text/css" />
<link href="data:text/css;charset=utf-8,%23test4%20%7Bbackground-color%3A%20red%3B%7D" rel="stylesheet" type="text/css" />

Просмотреть файл

@ -1088,11 +1088,10 @@ static Loader::MediaMatched MediaListMatches(const MediaList* aMediaList,
* well as setting the enabled state based on the title and whether
* the sheet had "alternate" in its rel.
*/
Loader::MediaMatched Loader::PrepareSheet(StyleSheet* aSheet,
const nsAString& aTitle,
const nsAString& aMediaString,
MediaList* aMediaList,
IsAlternate aIsAlternate) {
Loader::MediaMatched Loader::PrepareSheet(
StyleSheet* aSheet, const nsAString& aTitle, const nsAString& aMediaString,
MediaList* aMediaList, IsAlternate aIsAlternate,
IsExplicitlyEnabled aIsExplicitlyEnabled) {
MOZ_ASSERT(aSheet, "Must have a sheet!");
RefPtr<MediaList> mediaList(aMediaList);
@ -1106,7 +1105,8 @@ Loader::MediaMatched Loader::PrepareSheet(StyleSheet* aSheet,
aSheet->SetMedia(mediaList);
aSheet->SetTitle(aTitle);
aSheet->SetEnabled(aIsAlternate == IsAlternate::No);
aSheet->SetEnabled(aIsAlternate == IsAlternate::No ||
aIsExplicitlyEnabled == IsExplicitlyEnabled::Yes);
return MediaListMatches(mediaList, mDocument);
}
@ -1835,8 +1835,8 @@ Result<Loader::LoadSheetResult, nsresult> Loader::LoadInlineStyle(
LOG((" Sheet is alternate: %d", static_cast<int>(isAlternate)));
auto matched =
PrepareSheet(sheet, aInfo.mTitle, aInfo.mMedia, nullptr, isAlternate);
auto matched = PrepareSheet(sheet, aInfo.mTitle, aInfo.mMedia, nullptr,
isAlternate, aInfo.mIsExplicitlyEnabled);
InsertSheetInTree(*sheet, aInfo.mContent);
@ -1940,8 +1940,8 @@ Result<Loader::LoadSheetResult, nsresult> Loader::LoadStyleLink(
LOG((" Sheet is alternate: %d", static_cast<int>(isAlternate)));
auto matched =
PrepareSheet(sheet, aInfo.mTitle, aInfo.mMedia, nullptr, isAlternate);
auto matched = PrepareSheet(sheet, aInfo.mTitle, aInfo.mMedia, nullptr,
isAlternate, aInfo.mIsExplicitlyEnabled);
InsertSheetInTree(*sheet, aInfo.mContent);
@ -2107,7 +2107,8 @@ nsresult Loader::LoadChildSheet(StyleSheet* aParentSheet,
&sheet);
NS_ENSURE_SUCCESS(rv, rv);
PrepareSheet(sheet, empty, empty, aMedia, IsAlternate::No);
PrepareSheet(sheet, empty, empty, aMedia, IsAlternate::No,
IsExplicitlyEnabled::No);
}
MOZ_ASSERT(sheet);
@ -2218,7 +2219,8 @@ nsresult Loader::InternalLoadNonDocumentSheet(
aReferrerPolicy, aIntegrity, syncLoad, state, &sheet);
NS_ENSURE_SUCCESS(rv, rv);
PrepareSheet(sheet, empty, empty, nullptr, IsAlternate::No);
PrepareSheet(sheet, empty, empty, nullptr, IsAlternate::No,
IsExplicitlyEnabled::No);
if (state == eSheetComplete) {
LOG((" Sheet already complete"));

Просмотреть файл

@ -199,6 +199,7 @@ class Loader final {
typedef nsIStyleSheetLinkingElement::HasAlternateRel HasAlternateRel;
typedef nsIStyleSheetLinkingElement::IsAlternate IsAlternate;
typedef nsIStyleSheetLinkingElement::IsInline IsInline;
typedef nsIStyleSheetLinkingElement::IsExplicitlyEnabled IsExplicitlyEnabled;
typedef nsIStyleSheetLinkingElement::MediaMatched MediaMatched;
typedef nsIStyleSheetLinkingElement::Update LoadSheetResult;
typedef nsIStyleSheetLinkingElement::SheetInfo SheetInfo;
@ -480,8 +481,8 @@ class Loader final {
//
// This method will set the sheet's enabled state based on aIsAlternate
MediaMatched PrepareSheet(StyleSheet* aSheet, const nsAString& aTitle,
const nsAString& aMediaString,
dom::MediaList* aMediaList, IsAlternate);
const nsAString& aMediaString, dom::MediaList*,
IsAlternate, IsExplicitlyEnabled);
// Inserts a style sheet in a document or a ShadowRoot.
void InsertSheetInTree(StyleSheet& aSheet, nsIContent* aLinkingContent);

Просмотреть файл

@ -253,6 +253,18 @@ VARCACHE_PREF(
bool, true
)
// Whether the disabled attribute in HTMLLinkElement disables the sheet loading
// altogether, or forwards to the inner stylesheet method without attribute
// reflection.
//
// Historical behavior is the second, the first is being discussed at:
// https://github.com/whatwg/html/issues/3840
VARCACHE_PREF(
"dom.link.disabled_attribute.enabled",
dom_link_disabled_attribute_enabled,
bool, true
)
VARCACHE_PREF(
"dom.performance.enable_scheduler_timing",
dom_performance_enable_scheduler_timing,

Просмотреть файл

@ -0,0 +1,45 @@
<!doctype html>
<title>&lt;link disabled&gt;, HTMLLinkElement.disabled and CSSStyleSheet.disabled interactions</title>
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<link rel="author" title="Mozilla" href="https://mozilla.org">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1281135">
<link rel="help" href="https://github.com/whatwg/html/issues/3840">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<link title="alt" rel="stylesheet" disabled href="data:text/css,html { background: green }">
<script>
function assert_applies(applies) {
(applies ? assert_equals : assert_not_equals)(getComputedStyle(document.documentElement).backgroundColor, "rgb(0, 128, 0)");
}
const link = document.querySelector("link[disabled]");
test(function() {
assert_equals(document.styleSheets.length, 0);
assert_applies(false);
}, "<link disabled> prevents the stylesheet from being in document.styleSheets (from parser)");
async_test(function(t) {
assert_true(link.disabled);
link.onload = t.step_func_done(function() {
assert_equals(document.styleSheets.length, 1);
let sheet = document.styleSheets[0];
assert_equals(sheet.ownerNode, link);
assert_applies(true);
link.disabled = true;
assert_equals(sheet.ownerNode, null);
assert_false(sheet.disabled);
assert_applies(false);
assert_true(link.hasAttribute("disabled"));
assert_equals(document.styleSheets.length, 0);
assert_applies(false);
});
link.disabled = false;
assert_true(!link.hasAttribute("disabled"));
assert_false(link.disabled);
}, "HTMLLinkElement.disabled reflects the <link disabled> attribute, and behaves consistently");
</script>

Просмотреть файл

@ -0,0 +1,38 @@
<!doctype html>
<title>&lt;link disabled&gt;, HTMLLinkElement.disabled and CSSStyleSheet.disabled interactions (alternate)</title>
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<link rel="author" title="Mozilla" href="https://mozilla.org">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1281135">
<link rel="help" href="https://github.com/whatwg/html/issues/3840">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<link title="alt" rel="alternate stylesheet" disabled href="data:text/css,html { background: green }">
<script>
function assert_applies(applies) {
(applies ? assert_equals : assert_not_equals)(getComputedStyle(document.documentElement).backgroundColor, "rgb(0, 128, 0)");
}
const link = document.querySelector("link[disabled]");
async_test(function(t) {
assert_true(link.disabled);
link.onload = t.step_func_done(function() {
assert_equals(document.styleSheets.length, 1);
let sheet = document.styleSheets[0];
assert_equals(sheet.ownerNode, link);
assert_applies(true);
link.disabled = true;
assert_equals(sheet.ownerNode, null);
assert_false(sheet.disabled);
assert_applies(false);
assert_true(link.hasAttribute("disabled"));
assert_equals(document.styleSheets.length, 0);
});
link.disabled = false;
assert_true(!link.hasAttribute("disabled"));
assert_false(link.disabled);
}, "HTMLLinkElement.disabled reflects the <link disabled> attribute, and behaves consistently, when the sheet is an alternate");
</script>

Просмотреть файл

@ -0,0 +1,32 @@
<!doctype html>
<title>&lt;link disabled&gt;'s "explicitly enabled" state persists after getting disconnected from the tree</title>
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<link rel="author" title="Mozilla" href="https://mozilla.org">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1281135">
<link rel="help" href="https://github.com/whatwg/html/issues/3840">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<link title="alt" rel="alternate stylesheet" disabled href="data:text/css,html { background: green }">
<script>
function assert_applies(applies) {
(applies ? assert_equals : assert_not_equals)(getComputedStyle(document.documentElement).backgroundColor, "rgb(0, 128, 0)");
}
const link = document.querySelector("link[disabled]");
async_test(function(t) {
assert_true(link.disabled);
link.disabled = false;
assert_false(link.disabled);
assert_true(!link.hasAttribute("disabled"));
link.remove();
link.onload = t.step_func_done(function() {
assert_equals(document.styleSheets.length, 1);
let sheet = document.styleSheets[0];
assert_equals(sheet.ownerNode, link);
assert_applies(true);
});
document.head.appendChild(link);
}, "HTMLLinkElement.disabled's explicitly enabled state persists when disconnected and connected again");
</script>

Просмотреть файл

@ -0,0 +1,40 @@
<!doctype html>
<title>&lt;link disabled&gt;'s "explicitly enabled" state doesn't persist for clones</title>
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<link rel="author" title="Mozilla" href="https://mozilla.org">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1281135">
<link rel="help" href="https://github.com/whatwg/html/issues/3840">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<link title="alt" rel="alternate stylesheet" disabled href="data:text/css,html { background: green }">
<script>
function assert_applies(applies) {
(applies ? assert_equals : assert_not_equals)(getComputedStyle(document.documentElement).backgroundColor, "rgb(0, 128, 0)");
}
const link = document.querySelector("link[disabled]");
async_test(function(t) {
link.remove();
link.disabled = false; // `link` is explicitly enabled.
let clonesLoaded = 0;
for (let shallow of [true, false]) {
const clone = link.cloneNode(shallow);
clone.onload = t.step_func(function() {
assert_false(link.disabled);
// Even though it's not disabled, it still doesn't apply, since it's an alternate.
assert_applies(false);
if (++clonesLoaded == 2) {
link.onload = t.step_func_done(function() {
assert_false(link.disabled);
assert_applies(true); // `link` is still explicitly enabled.
});
document.head.appendChild(link);
}
});
document.head.appendChild(clone);
}
}, "HTMLLinkElement.disabled's explicitly enabled state doesn't persist on clones");
</script>

Просмотреть файл

@ -0,0 +1,27 @@
<!doctype html>
<title>&lt;link disabled&gt;'s "explicitly enabled" persists across rel changes</title>
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<link rel="author" title="Mozilla" href="https://mozilla.org">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1281135">
<link rel="help" href="https://github.com/whatwg/html/issues/3840">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<link title="alt" rel="yadayada" disabled href="data:text/css,html { background: green }">
<script>
function assert_applies(applies) {
(applies ? assert_equals : assert_not_equals)(getComputedStyle(document.documentElement).backgroundColor, "rgb(0, 128, 0)");
}
const link = document.querySelector("link[disabled]");
async_test(function(t) {
link.onload = t.step_func_done(function() {
assert_applies(true);
link.setAttribute("rel", "alternate stylesheet");
assert_applies(true);
assert_false(link.disabled);
});
link.disabled = false;
link.setAttribute("rel", "stylesheet");
}, "HTMLLinkElement.disabled's explicitly enabled state persists regardless of rel");
</script>

Просмотреть файл

@ -0,0 +1,26 @@
<!doctype html>
<title>&lt;link disabled&gt;'s "explicitly enabled" state isn't magically set from the setter</title>
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<link rel="author" title="Mozilla" href="https://mozilla.org">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1281135">
<link rel="help" href="https://github.com/whatwg/html/issues/3840">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
function assert_applies(applies) {
(applies ? assert_equals : assert_not_equals)(getComputedStyle(document.documentElement).backgroundColor, "rgb(0, 128, 0)");
}
async_test(function(t) {
const link = document.createElement("link");
link.setAttribute("rel", "alternate stylesheet");
link.setAttribute("title", "alt");
link.href = "data:text/css,html { background: green }";
link.disabled = false; // This should do nothing, and is the point of this test.
link.onload = t.step_func_done(function() {
assert_applies(false); // Should not apply, since it's an alternate that hasn't been enabled.
assert_false(link.disabled);
});
document.head.appendChild(link);
}, "HTMLLinkElement.disabled setter does nothing if the attribute isn't present already.");
</script>

Просмотреть файл

@ -0,0 +1,27 @@
<!doctype html>
<title>&lt;link disabled&gt;'s "explicitly enabled" state works when set explicitly back and forth</title>
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<link rel="author" title="Mozilla" href="https://mozilla.org">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1281135">
<link rel="help" href="https://github.com/whatwg/html/issues/3840">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
function assert_applies(applies) {
(applies ? assert_equals : assert_not_equals)(getComputedStyle(document.documentElement).backgroundColor, "rgb(0, 128, 0)");
}
async_test(function(t) {
const link = document.createElement("link");
link.setAttribute("rel", "alternate stylesheet");
link.setAttribute("title", "alt");
link.href = "data:text/css,html { background: green }";
link.disabled = true;
link.disabled = false; // This should make it "explicitly enabled".
link.onload = t.step_func_done(function() {
assert_applies(true); // Should apply, since it's explicitly enabled.
assert_false(link.disabled);
});
document.head.appendChild(link);
}, "HTMLLinkElement.disabled setter sets the explicitly enabled state if toggled back and forth.");
</script>

Просмотреть файл

@ -0,0 +1,7 @@
<!DOCTYPE html>
<title>CSS Test Reference</title>
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<link rel="author" title="Mozilla" href="https://mozilla.org">
<style>
html { background: green }
</style>

Просмотреть файл

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>CSS Test: alternate stylesheets can be disabled by HTMLLinkElement.disabled if they have the disabled attribute already</title>
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<link rel="author" title="Mozilla" href="https://mozilla.org">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1281135">
<link rel="help" href="https://github.com/whatwg/html/issues/3840">
<link rel="match" href="HTMLLinkElement-disabled-alternate-ref.html">
<link title="alt" rel="alternate stylesheet" href="data:text/css,html { background: green }" disabled onload="document.documentElement.className = ''">
<script>
onload = function() {
const link = document.querySelector("link[rel='alternate stylesheet']");
link.disabled = false;
}
</script>