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
Unable to extend DOM classes at runtime #10063
Comments
Hey @WebReflection! We really appreciate you taking the time to report an issue. The collaborators If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack |
To whom it might concern, the way I've solved this issue in user land is through an const {construct, setPrototypeOf} = Reflect;
let transpiled = false;
try {
// the angry koala check https://twitter.com/WebReflection/status/1133757401482584064
transpiled = !!new {o(){}}.o;
} catch($) {}
export default transpiled ?
function (Super) {
const Class = function () {
return construct(Super, arguments, Class);
};
setPrototypeOf(Class, Super);
setPrototypeOf(Class.prototype, Super.prototype);
return Class;
} :
Super => class extends Super {}; Above code is used in heresy 🔥 to avoid issues when defining components via objects intead of classes. |
Since |
That would work, but I'd still need to use defensive code and runtime transpiled checks to be sure whoever imported my module and mixed with the rest of the code doesn't need to have that flag on. However, wouldn't it be safe to assume that such check should always be performed when:
Specially for custom elements builtins, where using Is this an option? Otherwise having at least a flag to tell people about would be surely better than current state. Thanks |
It's also possible to hit this error on other built-ins, like the Notification object (#9367) |
I think I am having the same issue with extending |
See citation-js/citation-js#91 See babel/babel#10063 BREAKING CHANGE: Changes Response and Request class names
Bug Report
Current Behavior
If an extend is created at runtime, hence without an explicit class, it's impossible to instantiate any instance later on with such class.
Input Code
The following code works out of the box in Chrome and Firefox, but it fails only with the second class once transpiled. See the console error in Babel site itself (P.S. you cannot define twice the same component, so if you edit the code, be sure you also refresh the page before making any conclusion/assumption)
Expected behavior/code
Since
document.createElement('p').constructor
is exactly the classHTMLParagraphElement
, and since extending explicitlyHTMLParagraphElement
has no issues, I'd expect Babel to not throw also when extending the retrieved class, as it is natively in the browser.Babel Configuration (.babelrc, package.json, cli command)
The previously posted REPL configuration has es2015 on ... that's it.
Environment
Possible Solution
The only difference between the two extends is that
_wrapNativeSuper(HTMLParagraphElement)
is not used for theFail
class, so that passing it directly causes the issue as soon as_getPrototypeOf(Fail).apply(this, arguments)
is attempted, since you usually cannot.apply(...)
classes, or at least you surely cannot do that with native DOM classes (that also require to be register as custom elements to be used as such).A possible solution could be to test at runtime if a class is native, and in that case enforce the usage of
_wrapNativeSuper
.However, since this issue is very DOM use cases specific, maybe forcing _wrapNativeSuper for any class that is either explicitly native or
instanceof Element
could work?Yet I think the easiest way to go would be to pass
_isNativeFunction(Class) ? _wrapNativeSuper(Class) : Class
when it's not instantly possible to recognize native from user-land.Additional context/Screenshots
The text was updated successfully, but these errors were encountered: