Summary: Make the disabled attribute on link elements do something useful, and the disabled IDL attribute reflect this attribute instead of forwarding to the style sheet object (if present). This is mostly compat work, but should also do less work in pages that use it already. See below for the long story.
Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1281135 Link to standard: https://github.com/whatwg/html/pull/4519 There are two parts of this proposal. One is "implementing the disabled attribute". That's what that HTML spec PR is about. The other is about changing the behavior of HTMLLinkElement.disabled, which we do implement, to reflect the content attribute. This used to be spec'd like what Gecko does, but was removed from the spec. New thing matches WebKit / Blink. See the "Do other browser engines implement this?" for all details you may want to know (and probably more) about this situation. Platform coverage: All Estimated or target release: 68 Preference behind which this will be implemented: dom.link.disabled_attribute.enabled Is this feature enabled by default in sandboxed iframes? Yes DevTools bug: I don't think it's needed, but please file if you think otherwise. Do other browser engines implement this? All other engines implement the disabled attribute in one way or another. See below for the details of what WebKit and Blink do. Edge looks like they implemented the `disabled` attribute as a "default value for the stylesheet disabled flag" kind of thing. That has the downside of still downloading the stylesheet in a case where WebKit and Blink don't right now, and thus I don't think WebKit or Blink would be interested in switching to such a model. Regarding HTMLLinkElement.disabled, also all engines implement it, with two different behaviors right now: * Gecko (before my patch) and Edge implement the old spec for this, where it forwards to the stylesheet's disabled flag. * Blink / WebKit implement it as reflecting the disabled attribute (I'm not aware of any spec reference, historical or not, for this behavior, but I'd be interested in knowing about it). Now the long story, which is mostly in [1]. The TL;DR: is written in [2], and that contains the proposed behavior that my change implements. Feel free to skip to the "web-platform-tests" section below if you're not interested on the details. Blink and WebKit implement the `disabled` attribute on stylesheets, and it's the only way to enable alternate stylesheets there. There's no spec for that of course, and the behavior of this attribute in those engines is quite bizarre (see [1] for reference). Separately, there's the HTMLLinkElement.disabled setter and getters, which were removed from the spec, but that everyone still implements (and I'm pretty sure it'd not be compatible to remove it). Spec-wise, the spec says that alternate stylesheets are supposed to be implemented using the disabled flag on the stylesheet [3]. Edge and Gecko do that, and make HTMLLinkElement.disabled forward to the stylesheet. In WebKit / Blink, this is not the case. An alternate stylesheet is not disabled (as in `link.sheet` is non-null, `link.sheet.disabled` returns false, but still magically does not apply to the page). The only way to enable such an stylesheet in Blink and WebKit is removing the `disabled` attribute on the link. This means that the only way to have a cross-browser alternate stylesheet is: <link rel="alternate stylesheet" disabled ...> And the cross-browser way to enable is using `link.disabled`: * In Gecko and Edge, that setter will forward to the stylesheet, object (it's the same as saying `if (link.sheet) link.sheet.disabled = false;`. And given they implement alternate sheets according to the standard, then it'd enable the already loaded and parsed stylesheet. * In Blink and WebKit, this will remove the disabled attribute, which will load the stylesheet, and set a magic "explicitly enabled" bit that will make the stylesheet apply when it loads. Separately, some websites are starting to use: <link rel="stylesheet" disabled> And it's a common cause of confusion when people find that it doesn't work on Firefox. The disabled attribute on its own does nothing in Gecko and thus we apply the stylesheet when other browsers don't, and thus the website breaks. This is all quite sad and bizarre, and other that this move I don't see many other paths forwards to achieve interop in all this mess. Blink and WebKit could probably fix their alternate stylesheet implementation to properly use the disabled flag, but given their use counters [4][5] they'll probably not remove the disabled attribute regardless. Also, they have other incentives to keep the disabled attribute, like the fact that for them it's a performance boost (they don't have to download and parse potentially large stylesheets). So my proposed model aligns with WebKit and Blink as much as possible without implementing obvious bugs. The disabled attribute also causes the stylesheet to not be present / loaded at all. This makes sense, and Blink and WebKit do this when the disabled attribute is set from the parser. They have a bug where adding the disabled attribute to an already loaded stylesheet will not remove the sheet from document.styleSheets or link.sheet. That makes no sense and I hope they'll fix that (or I may have to go and do it myself and send them some patches, but I'd rather not...). Also, the `link.disabled = false` in an alternate sheet case needs to keep working. The sane thing if we were designing this from scratch would be probably "you remove the disabled attribute so the stylesheet is loaded, and once it's loaded you set sheet.disabled = false". But given it's the only thing people can use right now to toggle alternate stylesheets I'm pretty sure we can't break it if we want stuff to keep working. So in the proposed model you also need a magical "explicitly enabled" bit of the sorts when the disabled attribute is removed. Anyhow, this is the long explanation of me trying to improve interop in this dark corner of the web. Over with the tests. web-platform-tests: I've added 8 different web-platform tests, testing the basic model, the alternate stylesheet disabling bit (there was no test for that lol), and various edge cases regarding how the enabled bit is preserved or not when the node is cloned, rel or href change, the node is disconnected, etc. Except the two tests that test for the general model and some of the WebKit / Blink oddness here, WebKit passes all of the rest. The seventh test catches an interop issue between WebKit and Blink (toggling the disabled attribute on a disconnected, recently created element doesn't set the explicit state in Blink, but does in WebKit and my implementation). Sorry for the huge wall of text. Hope this all albeit sad makes some sort of sense. Let me know if you have any concerns with this. -- Emilio [1]: https://github.com/whatwg/html/issues/3840 [2]: https://github.com/whatwg/html/issues/3840#issuecomment-481034206 [3]: https://drafts.csswg.org/cssom/#concept-css-style-sheet-disabled-flag [4]: https://www.chromestatus.com/metrics/feature/timeline/popularity/809 [5]: https://www.chromestatus.com/metrics/feature/timeline/popularity/2516 _______________________________________________ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform