Skip to content

Commit

Permalink
Add adoptedCallback to work around Firefox Native CE bug (#34455)
Browse files Browse the repository at this point in the history
See https://output.jsbin.com/yuwojok/29/quiet for a working demo of the bug. When we construct a CustomElement in one document, then insert it into another document (as we do with A4A ads), Firefox incorrectly resets the prototype of our CE instance to `HTMLElement.prototype`.

Luckily, we can fix this by listening for the `adoptedCallback`, which fires just after Firefox resets the prototype. If we detect a broken prototype chain, we can correct it before any other code can notice. See https://output.jsbin.com/datajos/5/quiet for a demo of the fix.
  • Loading branch information
jridgewell authored May 19, 2021
1 parent be956c9 commit c381d3d
Showing 1 changed file with 14 additions and 1 deletion.
15 changes: 14 additions & 1 deletion src/custom-element.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,20 @@ export function createCustomElementClass(win, elementConnectedCallback) {
);
// It's necessary to create a subclass, because the same "base" class cannot
// be registered to multiple custom elements.
class CustomAmpElement extends BaseCustomElement {}
class CustomAmpElement extends BaseCustomElement {
/**
* adoptedCallback is only called when using a Native implementation of Custom Elements V1.
* Our polyfill does not call this method.
*/
adoptedCallback() {
// Work around an issue with Firefox changing the prototype of our
// already constructed element to the new document's HTMLElement.
if (Object.getPrototypeOf(this) !== customAmpElementProto) {
Object.setPrototypeOf(this, customAmpElementProto);
}
}
}
const customAmpElementProto = CustomAmpElement.prototype;
return /** @type {typeof AmpElement} */ (CustomAmpElement);
}

Expand Down

0 comments on commit c381d3d

Please sign in to comment.