-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
"Upgrade an element" step 4 should remove element, or an already constructed marker #1238
Comments
Yes, I think you're exactly right. Looking back on @rniwa's original algorithm in WICG/webcomponents#403, he said "Pop the entry from the element construction stack of DEFINITION." In my translation of that into the spec, I assumed it was element, not realizing that the construction process would replace it with an already-constructed marker.
I don't think that'll be quite necessary. We just want to pop the top element of the stack in any case. I'll add a note clarifying that in non-pathological cases this will be an already-constructed marker. PR incoming. |
Fixes #1238. Usually, the popped stack entry is not the element, but instead an already-constructed marker. This makes the stack-popping generic, and also adds a note explaining exactly what could be going on here.
Fixes #1238. Usually, the popped stack entry is not the element, but instead an already-constructed marker. This makes the stack-popping generic, and also adds a note explaining exactly what could be going on here. Also fixes a typo in the HTMLElement() constructor which used the variable names "instance" and "element" interchangeably.
Fixes #1238. Usually, the popped stack entry is not the element, but instead an already-constructed marker. This makes the stack-popping generic, and also adds a note explaining exactly what could be going on here. Also clarifies the case in which the already constructed marker matters. It turns out that calling super() multiple times is not possible, but it's still possible to trigger that exception; this adds an example. Finally, fixes a typo in the HTMLElement() constructor which used the variable names "instance" and "element" interchangeably.
Fixes #1238. Usually, the popped stack entry is not the element, but instead an already-constructed marker. This makes the stack-popping generic, and also adds a note explaining exactly what could be going on here. Also clarifies the case in which the already constructed marker matters. It turns out that calling super() multiple times is not possible, but it's still possible to trigger that exception; this adds an example. Finally, fixes a typo in the HTMLElement() constructor which used the variable names "instance" and "element" interchangeably.
I'm trying to implement this is Blink. I'm glad there is now popping somewhere. Could you sanity check me on the following observation? I believe by popping the construction stack in upgrade, the spec prevents reentering a constructor of a given type, during upgrade. The reason is subsequent constructor calls, with new or through upgrade (for example, innerHTML) will reach step 5 of HTMLElement constructor. To put it another way, popping in upgrade “protects” the time between the UA calling the author's constructor and super getting to run; but in addition it extends protection to the author's constructor body, too, because the popping happens after that. While this is a severe restriction I believe this is probably the only sane situation to prevent “poaching.” One interesting wrinkle this causes is that calling the same constructor, whether with new or upgrade, is allowed during a call caused by "new" because the construction stack is empty. This is not a particular problem for our implementation, but it is an asymmetry for the author. I believe they can detect whether a call is via new or upgrade this way: class X extends HTMLElement() {
constructor(opt_in_detect) {
super();
console.log('in upgrade? ', inUpgrade(opt_in_detect));
}
inUpgrade(opt_in_detect) {
if (opt_in_detect) throw 'OK';
else try {
new X(true);
} catch (e) {
return e != 'OK';
}
// unreached
}
} …but I’m not sure. :) |
Actually I take that back; poaching is still possible by calling before super. In that case, maybe we must live with the problem and could relax the restriction. |
This all looks very familiar. Did you see my revised commit over in #1242, as well as my comment #1242 (comment) and my question to you about whether we should tighten the restriction? |
I had not seen it yet—behind on email. #1242 looks good and addresses this issue. |
Fixes #1238. Usually, the popped stack entry is not the element, but instead an already-constructed marker. This makes the stack-popping generic, and also adds a note explaining exactly what could be going on here. Also clarifies the cases in which the already constructed marker matters. In addition to calling super() multiple times, this error case can be triggered by creating another instance of the class being constructed. This adds examples of both possibilities. Finally, fixes a typo in the HTMLElement() constructor which used the variable names "instance" and "element" interchangeably.
Fixes #1238. Usually, the popped stack entry is not the element, but instead an already-constructed marker. This makes the stack-popping generic, and also adds a note explaining exactly what could be going on here. Also clarifies the cases in which the already constructed marker matters. In addition to calling super() multiple times, this error case can be triggered by creating another instance of the class being constructed. This adds examples of both possibilities. Finally, fixes a typo in the HTMLElement() constructor which used the variable names "instance" and "element" interchangeably, and fixes a broken cross-reference to "upgrade an element".
Fixes #1238. Usually, the popped stack entry is not the element, but instead an already-constructed marker. This makes the stack-popping generic, and also adds a note explaining exactly what could be going on here. Also clarifies the cases in which the already constructed marker matters. In addition to calling super() multiple times, this error case can be triggered by creating another instance of the class being constructed. This adds examples of both possibilities. Finally, fixes a typo in the HTMLElement() constructor which used the variable names "instance" and "element" interchangeably, and fixes a broken cross-reference to "upgrade an element".
I'm trying to implement the HTMLElement constructor in Blink. Step 8 replaces an element with an already constructed marker. I don't see anywhere that removes already constructed markers from the stack, which could be a problem.
I think upgrade an element step 4 may intend to simply pop from the construction stack instead of popping element; in the common case the top of the stack will not be element but an already constructed marker. Maybe already constructed markers should be associated with the element that caused them, and step 4 can pop element or its associated already constructed marker.
The text was updated successfully, but these errors were encountered: