Closed Bug 1708045 Opened 3 years ago Closed 3 years ago

assigning a title to HTMLStyleElement will change _disable_ property to true (disabling the style)

Categories

(Core :: CSS Parsing and Computation, defect)

Firefox 88
defect

Tracking

()

RESOLVED INVALID

People

(Reporter: palo.hmm, Unassigned)

References

Details

Attachments

(2 files, 1 obsolete file)

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.0

Steps to reproduce:

This error only happens on second and following time. Creating first style, adding title to it and injecting it to DOM works OK, doing so first time (after page load) does not disable the style and produce this error.

The disable property is turned to enable only after injecting the element.
Not right after assigning title to it.

This is a complete sample ready to be pasted to a console.
It prints disable property states at various points during the creation, edit and injection of two STYLE elements.

var elStyle1 = document.createElement('STYLE');
elStyle1.type = 'text/css';

console.log('disabled state before adding title: ' + elStyle1.disabled); // false
elStyle1.title = 'foo1';
console.log('disabled state after adding title: ' + elStyle1.disabled); // false

elStyle1.appendChild(document.createTextNode('.foo1 { color: red; }'));

var head = document.head || document.getElementsByTagName('head')[0];
head.appendChild(elStyle1);
console.log('disabled state after injecting the element: ' + elStyle1.disabled); // true second time


for (let i = 0; i < document.styleSheets.length; i++) {
  let styleSheet = document.styleSheets[i];
  if (styleSheet.title) {
	  console.log('title: ' + styleSheet.title + ' | disabled state of StyleSheet object: ' + styleSheet.disabled);
  }
}


var elStyle2 = document.createElement('STYLE');
elStyle2.type = 'text/css';

console.log('disabled state before adding title: ' + elStyle2.disabled); // false
elStyle2.title = 'foo2';
console.log('disabled state after adding title: ' + elStyle2.disabled); // false

elStyle2.appendChild(document.createTextNode('.foo2 { color: red; }'));

var head = document.head || document.getElementsByTagName('head')[0];
head.appendChild(elStyle2);
console.log('disabled state after injecting the element: ' + elStyle2.disabled); // true second time


for (let i = 0; i < document.styleSheets.length; i++) {
  let styleSheet = document.styleSheets[i];
  if (styleSheet.title) {
	  console.log('title: ' + styleSheet.title + ' | disabled state of StyleSheet object: ' + styleSheet.disabled);
  }
}

Actual results:

Second style is added as disabled. The style is not acting on elements whose attributes match the style's selector.
Unsuspecting user would check DOM, see the STYLE element added, but with the browser correctly ignoring it, will not see the results of it.

Just as a side note:
Using this method is quite painful, as can be seen in the sample, accessing the element this way is not practical. This method is described here:
https://www.w3.org/wiki/Dynamic_style_-_manipulating_CSS_with_JavaScript
It's more productive to use id property of a style element instead of a title, then access it by getElementById and sheet property, or just keep the whole element in a variable.
I didn't yet get to comparing methods of toggling disabled attribute to removing the element from DOM for the purpose of turning a style ON/OFF.

Expected results:

There is no reason the StyleSheet should be added as disabled.
And if that was on a purpose, like a feature,

  • it's not documented
  • it's not consistent. The first time a style is added this way, it's enabled.
  • other browsers do not do this

The Bugbug bot thinks this bug should belong to the 'Core::CSS Parsing and Computation' component, and is moving the bug to that component. Please revert this change in case you think the bot is wrong.

Component: Untriaged → CSS Parsing and Computation
Product: Firefox → Core

I am not an expert on this area, but it seems it's documented in the CSSOM spec?

emilio or boris, maybe you could take a look and judge the severity? (or even suggest a fix/diagnosis?)

This is invalid. title in stylesheets are the "style sheet set" name: https://drafts.csswg.org/cssom/#css-style-sheet-set / https://html.spec.whatwg.org/#attr-style-title.

The first time a stylesheet with title is inserted, we get through step 3 in https://drafts.csswg.org/cssom/#add-a-css-style-sheet, and set that as the "preferred style sheet set". Thus, the stylesheet is enabled. The second time we get through we already have a preferred style sheet set, and thus the sheet is disabled. disabled is only relevant once the element has been inserted in the document, because otherwise update a style block hasn't run.

This behavior matches other browsers:

<!doctype html>
<style title="preferred">
  :root { background: green }
</style>
<style title="other">
  :root { background: red }
</style>
<p>My background should be green</p>

But let me know if I'm misunderstanding the report.

Status: UNCONFIRMED → RESOLVED
Closed: 3 years ago
Resolution: --- → INVALID

On the attached testcase (from the reporter), there's one console.log logging statement where we log true and Chrome logs false.

We log:

disabled state after injecting the element: true

Chrome logs:

disabled state after injecting the element: false

I think that's the discrepancy that this bug was filed about. Do you know if that behavior-difference is a Firefox bug or a Chrome bug? (Or are both behaviors somehow allowed?)

Flags: needinfo?(emilio)

It's a chrome bug, see https://bugs.chromium.org/p/chromium/issues/detail?id=1205488

Chrome is not setting the disabled flag in step 5 of https://drafts.csswg.org/cssom/#add-a-css-style-sheet.

Flags: needinfo?(emilio)

Just noticed that Safari 14 fails (and throws an exception) in this testcase, for a different reason from Chrome -- Safari only reports one stylesheet for this document.

Updating testcase to account for that.

Attachment #9220198 - Attachment is obsolete: true

Thanks in any case for the bug report, papo -- it's good to know about the difference in behavior here -- and thanks Emilio for getting to the bottom of it & for filing the Chrome bug!

I filed https://bugs.webkit.org/show_bug.cgi?id=225363 on the Safari/WebKit issue (where the disabled stylesheets are entirely missing from document.styleSheets).

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: