Open Bug 1502814 Opened 7 years ago Updated 11 months ago

Custom elements stop working when moving them between frames

Categories

(Core :: DOM: Core & HTML, defect, P2)

63 Branch
defect

Tracking

()

ASSIGNED
Tracking Status
firefox63 --- affected
firefox64 --- affected
firefox65 --- affected

People

(Reporter: david.kocsis, Assigned: avandolder)

References

(Blocks 7 open bugs)

Details

Attachments

(1 file)

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:63.0) Gecko/20100101 Firefox/63.0 Steps to reproduce: I've created an iframe with a custom tag in it. It's not a custom element yet, then moved out from the frame and now it has upgraded to a proper custom element. Then i tried to move it back to the frame. I've created a fiddle with the issue: https://jsfiddle.net/b1cd34jf/ And could came up with a workaround as well, just uncomment the line in the connectedCallback. Actual results: It seems like it has lost its prototype (downgraded maybe) and threw an error: TypeError: this._log is not a function Expected results: Custom element stays upgraded or downgrade fully without calling its lifecycle methods.
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0 20181102100039 I was able to reproduce the mentioned behavior on Windows 10 x64 using the latest Nightly, Beta and Fx release builds. When using the provided test cases and moving the element between frames I observe the mentioned error in the console: "error: TypeError: this._log is not a function"
Status: UNCONFIRMED → NEW
Component: Untriaged → Layout: Images, Video, and HTML Frames
Ever confirmed: true
Product: Firefox → Core
Component: Layout: Images, Video, and HTML Frames → DOM: Core & HTML
Presumably due to reparenting when adopting; we switch to the default prototype in the new document. I thought this was a well-known issue, but I'm not seeing a previous bug on this. I suppose we could try to preserve custom protos when reparenting...
Priority: -- → P3
Blocks: 1528791

Edgar, thanks for looking into this (and finding this bug!). I would suggest that we attempt a generic solution here (i.e., no prototype changes during adoption, regardless of the type of node) and not scope it to custom elements.

Blocks: dom
Severity: normal → S3
Blocks: 1783398

Previously, nodes that were being adopted into a new document were
given the default prototype for that node from the new document. With
custom elements, however, the new document will not contain the
necessary prototype, and instead an HTMLUnknownElement prototype was
being given. Instead, use a wrapper around the original prototype.

Assignee: nobody → avandolder
Status: NEW → ASSIGNED
Blocks: 1556358
Duplicate of this bug: 1826686
No longer blocks: 1556358
Attachment #9320916 - Attachment description: Bug 1502814 - Keep a node's prototype the same when adopting across frames. r?edgar → Bug 1502814 - Keep custom element prototypes when adopting across frames. r?edgar,#dom-core
Attachment #9320916 - Attachment description: Bug 1502814 - Keep custom element prototypes when adopting across frames. r?edgar,#dom-core → Bug 1502814 - Keep element prototypes when adopting across documents. r?edgar,#dom-core
Duplicate of this bug: 1868039

I've the same issue in my designer application https://node-projects.github.io/web-component-designer-demo/index.html

You can undock a window to a new browser window (rightclick on the header), but in firefox it does not work, cause I heavily use webcomponents.

Blocks: 1893321
Priority: P3 → P2
Blocks: 1899532
No longer blocks: 1899532
See Also: → 1899532

Here's a workaround, for anyone that needs it:

function checkElementPrototype(el) {
  if (el instanceof FirefoxFixer) return;

  const constructor = customElements.get(el.tagName.toLowerCase());
  Object.setPrototypeOf(el, constructor.prototype);
}

class FirefoxFixer extends HTMLElement {
  adoptedCallback() {
    checkElementPrototype(this);
  }

  disconnectedCallback() {
    checkElementPrototype(this);
  }
}

If you extend FirefoxFixer, and make sure you call the super methods in disconnectedCallback and adoptedCallback, it works around the bug.

Here's a demo https://static-misc-4.glitch.me/iframe-ce/

(This is a specific variant of more general bug 1470017, it seems the plan was to fix this one before fixing the general bug per https://bugzilla.mozilla.org/show_bug.cgi?id=1419329#c4)

Blocks: 1470017
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: