Calculate ancestorOrigins on document creation and store on document#12071
Calculate ancestorOrigins on document creation and store on document#12071
Conversation
When a Location object is created, a Document is not yet created. This is problematic for ancestorOrigins.
There was a problem hiding this comment.
I think this looks great, thanks! I have a question about the implications of moving from Location/Window to Document, since these are not always 1:1.
Example: you navigate an iframe from the initial about:blank Document to a same-origin one. I think neither the inner Window nor Location objects change, yet this PR would recalculate ancestor origins after the navigation, where as the current spec would not. Is that ever observable?
I envisioned a case where an iframe's ancestor used document.domain to change its origin before the navigation away from the initial about:blank Document. The current spec would not reflect the ancestor's origin change, since ancestorOrigins never gets recalculated. After this PR, the new document's ancestor origins list gets recalculated to its ancestor's "ancestor origins list" plus the ancestor's origin, which could have changed. On the other hand, we only ever expose its ASCII serialization, which never considers an origin's domain, so I guess it's not observable.
So basically after this PR, in the navigation scenario I described above, the "internal ancestor origins objects list" CAN change, but not in a way that is observable to script. Is that right?
Edit: Regarding the PR template, if there is indeed no observable change here, maybe the "At least two implementers are interested (and none opposed):" becomes "N/A"?
| <li><p><span data-x="list append">Append</span> <var>parentDoc</var>'s <span | ||
| data-x="concept-document-origin">origin</span> to <var>output</var>.</p></li> | ||
|
|
||
| <li> |
There was a problem hiding this comment.
Maybe we could use https://infra.spec.whatwg.org/#list-extend, instead of iterating manually?
There was a problem hiding this comment.
#11560 would need to change back to iterating the list though.
|
Without the There is an observable difference here though which is |
Right, well technically it changes its origin by virtue of changing its origin's domain with Even with #11560, there should be no observable change due to |
|
Yes, correct. Though with #11560 you can have an |
|
@annevk is this OK for WebKit? |
This term is now a list (not a DOMTokenList) on Document (not Location). See whatwg/html#12071
| @@ -97027,7 +96869,7 @@ interface <dfn interface>Location</dfn> { // but see also <a href="#the-location | |||
| [<span>LegacyUnforgeable</span>] undefined <span data-x="dom-location-replace">replace</span>(USVString url); | |||
| [<span>LegacyUnforgeable</span>] undefined <span data-x="dom-location-reload">reload</span>(); | |||
|
|
|||
| [<span>LegacyUnforgeable</span>, SameObject] readonly attribute <span>DOMStringList</span> <span data-x="dom-location-ancestorOrigins">ancestorOrigins</span>; | |||
| [<span>LegacyUnforgeable</span>] readonly attribute <span>DOMStringList</span> <span data-x="dom-location-ancestorOrigins">ancestorOrigins</span>; | |||
There was a problem hiding this comment.
Not returning the same object each time from a getter seems very surprising. Why would we want that? You don't want obj.x !== obj.x (there's a rule for this in the design principles as well).
There was a problem hiding this comment.
Step 1 says to return a an empty DOMStringList if this's relevant Document is null.
Since the relevant Document can change over time, I think we can't return the same object always. So options are:
- Cache whatever was returned the first time the getter is called. (This matches WebKit.)
- Return a new object every time. (Gecko, Chromium.)
- Maybe throw an
InvalidStateErrorin step 1?
The current spec is wrong since it says SameObject but then in step 1 sometimes returns an empty list (not a DOMStringList).
There was a problem hiding this comment.
We don't have to return the same object always to not violate obj.x !== obj.x. Caching or throwing would work. Caching is probably the most compatible. SameObject is indeed wrong if the returned value has to change at certain points in time though.
Can you observe the object changing in WebKit? Maybe with initial about:blank?
There was a problem hiding this comment.
Yes, for example removing an iframe. But since WebKit caches the return value from the first access, it's different if you call the getter first before or after the iframe is removed.
https://software.hixie.ch/utilities/js/live-dom-viewer/saved/14480
Maybe option 4 is to create an empty DOMStringList in step 1 but cache it, so there can be two separate objects returned.
There was a problem hiding this comment.
I think if you navigate an iframe its Location object stays the same, but the relevant Document changes as well. (Even across a cross-origin navigation I'm pretty sure as you're holding a proxy object, essentially.) We probably want to invalidate the list each time the relevant Document changes. Not a 100% sure how to best specify this though.
There was a problem hiding this comment.
This PR computes a new list when a Document is created and stores it on the Document object, so that is solved by this PR.
About the chaching or throwing issue, should we go with option 4?
There was a problem hiding this comment.
I don't quite follow here. If iframe can be removed, the location have it's relevant document null, then
let a = location.ancestorOrigins;
...
/* relevant document for location becomes null */
...
let b = location.ancestorOrigins;
a !== b; // trueAlso
let loc = i.location;
let list = loc.ancestorOrigins;
i.contentWindow.navigation.navigate("www.some.where.else-same-origin.com");
let whatIsThis = list !== loc.ancestorOrigins;What value does whatIsThis have?
Is there a reason why we can't make this attribute NewObject?
There was a problem hiding this comment.
@theIDinside it's ok to have a new object when there's a semantic change, but just accessing ancestorOrigins twice without removing an iframe or navigating should give the same object both times.
When a Location object is created, a Document is not yet created. This is problematic for ancestorOrigins.
Also remove
[SameObject]since step 1 can return a separate object.(See WHATWG Working Mode: Changes for more details.)
/document-lifecycle.html ( diff )
/document-sequences.html ( diff )
/dom.html ( diff )
/index.html ( diff )
/nav-history-apis.html ( diff )