-
Notifications
You must be signed in to change notification settings - Fork 711
[cssom-1] Ensure inline style and corresponding declaration block updates each other properly #2269
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
cc @bzbarsky |
Note that this cannot bikeshed correctly at this moment, because "attribute change steps" wasn't actually exported from the DOM spec until whatwg/dom#567 which was merged several hours ago. |
WebKit and Blink don't agree with the part of Also, if we follow the resolution in #1898 to make |
Also wpt test for this change: web-platform-tests/wpt#9376. |
cssom-1/Overview.bs
Outdated
|
||
When a <a>CSS declaration block</a> object is created, then: | ||
<ol> | ||
<li>Let <var>owner node</var> be the <a for="CSSStyleDeclaration">owner node</a>. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to also check if the readonly flag is set. Now this will try to get an attribute when doing getComputedStyle(elm)
I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, you're right. The algorithm for attribute change steps
also need updates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to make this algorithm and attribute change steps
check readonly flag
.
We don't I think. But maybe figuring this out can be part of #1898 ? |
Yeah, sure, I guess |
cssom-1/Overview.bs
Outdated
@@ -2034,6 +2034,25 @@ Note: The serialization of an empty CSS declaration block is the empty string. | |||
Note: The serialization of a non-empty CSS declaration block does not include any surrounding whitespace, i.e., no whitespace appears | |||
before the first property name and no whitespace appears after the final semicolon delimiter that follows the last property value. | |||
|
|||
A <a>CSS declaration block</a> has these <a>attribute change steps</a> for its <a for="CSSStyleDeclaration">owner node</a>: | |||
<ol> | |||
<li>If the <a for="CSSStyleDeclaration">readonly flag</a> is set, terminate these steps. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How can this even happen? The cases when there is an owner node are currently not readonly and there are no plans I am aware of to make them readonly...
There should probably be a note here explaining what this test is about, because it's pretty confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getComputedStyle sets owner node per the spec. But maybe that is a spec bug?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I missed that somehow. OK, then this is probably fine. That said, this is the first actual use of owner node that I can see. So if it simplifies things, we could probably avoid setting owner node in getComputedStyle
instead of dealing with it here....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I think we can set it to null there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can discuss this in a separate PR. I don't think that needs to block this change.
Actually, I have a feeling that having the declaration block from getComputedStyle
have the owner node set makes sense. Not sure how useful it is, though.
<li>If <var>owner node</var> is null, or the <a for="CSSStyleDeclaration">readonly flag</a> is set, terminate these steps. | ||
<li>Let <var>value</var> be the result of <a lt="get an attribute by namespace and local name">getting an attribute</a> | ||
given null, "<code>style</code>", and <var>owner node</var>. | ||
<li>If <var>value</var> is not null, let the <a for="CSSStyleDeclaration">declarations</a> be the result of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/let the/let/ ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to me that there is a convention that we use "the" before associated properties, and no "the" before variables, so I add "the" here. Not sure if my understanding is correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something like that, yeah, though probably not entirely consistent. But we should probably adopt Infra Standard conventions when we update things or write new material for CSSOM (like saying "then return" instead of "terminate these steps").
cssom-1/Overview.bs
Outdated
@@ -2079,6 +2098,8 @@ Setting the {{CSSStyleDeclaration/cssText}} attribute must run these steps: | |||
<li>Empty the <a for="CSSStyleDeclaration">declarations</a>. | |||
<li><a lt="Parse a CSS declaration block">Parse</a> the given value and, if the return value is not the empty list, insert the items in the list | |||
into the <a for="CSSStyleDeclaration">declarations</a>, in <a>specified order</a>. | |||
<li>If the <a for="CSSStyleDeclaration">owner node</a> is not null, <a>set an attribute value</a> for <a for="CSSStyleDeclaration">owner node</a> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really think we should prevent this attribute set from leading to a re-parse. It's a much simpler model than having it re-parse, because in the presence of CSP parsing from the string does NOT give the same results as the thing that was serialized to the string, in general. And since UAs are going to optimize out the reparsing for basic sanity reasons, this is likely to lead to divergence between what the spec theoretically says (but no one would ever do) and what UAs do.
There are also issues around base URIs: set vs serialize-and-reparse treat them differently. I did explicitly mention this in #1559 as a problem with the serialize-and-reparse approach.
Not reviewing the rest of the changes for now given that, because they will need to be modified anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have any suggestion for how can we avoid serialize-and-reparse? It seems to me if we want to avoid that, we would need to duplicate many definitions from the DOM spec just for getting rid of the "run attribute change steps" part.
Is there any existing algorithm in the DOM spec helps doing that? If not, I suggest we merge this change to get the spec closer to what browsers do currently, and file a new issue to address the serialize-and-reparse issue, which may need some help from the DOM spec side.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could set a flag while you are setting the attribute, and not do any attribute change steps while that flag is set, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm, okay, fair. Thanks for the suggestion.
…ates each other properly. This mostly follows how `DOMTokenList` works in the DOM spec, which has a similar situation that having a live object reflecting an attribute. This should fix #1559.
…ze-and-reparse on style attribute.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I glossed over the serialize-and-reparse issue in my first review, sorry about that. I think the fix looks good. I added a test for it in web-platform-tests/wpt@dc41ada
Thanks for the review and the new test :) |
Browser bugs |
Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=1197705 I removed the test of setting identical value triggering mutation record. That test would fail Chrome as well, but anyway... We can add that later after we address #1898. |
from a string <var>value</var>. | ||
</ol> | ||
|
||
When a <a>CSS declaration block</a> object is created, then: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@upsuper Why is this timing correct? Especially since nothing specifies when these objects are actually created, last I checked...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as it is returned from Element.style
, does it matter when the objects are actually created? Browser needs to create it at some point, but before script gets it somehow, whether it exists doesn't really matter, does it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It matters because the base URI is different at different points in time, depending on what the node document of the element is. So depending on exactly when the creation/parsing happen you will get different behavior for relative URIs in property values....
Maybe that doesn't affect what CSSOM sees, just the actual styling behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm... okay. Sounds like something worth raising for css-style-attr I guess... The interaction between the two specs would be fun...
<li>Let <var>owner node</var> be <var>declaration block</var>'s <a for="CSSStyleDeclaration">owner node</a>. | ||
<li>If <var>owner node</var> is null, terminate these steps. | ||
<li>Set <var>declaration block</var>'s <a for="CSSStyleDeclaration">updating flag</a>. | ||
<li><a>Set an attribute value</a> for <var>owner node</var> using "<code>style</code>" and the result of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't handle mutation events right, but I guess neither does anything else....
This mostly follows how
DOMTokenList
works in the DOM spec, which has a similar situation that having a live object reflecting an attribute.This should fix #1559.