-
Notifications
You must be signed in to change notification settings - Fork 619
Improve compatibility with webcomponents.js (connectedCallback) #337
Conversation
Previously, Turbolinks replaced the document body by settting document.body. However, the reference Custom Elements polyfill [1] does not patch the document.body property, the connectedCallback of any custom elements in the new body will never be called. By using document.documentElement.replaceChild(), we make it possible for the Custom Elements polyfill to detect that new elements were connected do the DOM. [1]: https://github.com/webcomponents/custom-elements
Thanks for the heads up! Your patch to fix the the polyfill seems like the best overall solution: webcomponents/custom-elements#127. |
According to webcomponents/custom-elements#127 (comment), @denisw 's change was merged, reverted, then re-opened as webcomponents/custom-elements#134. Unfortunately, fixing this WebComponents-side seems to be blocked. @javan is this proposed change worth reconsidering? |
We'll need to test it carefully, of course, but I don't see any issue with using |
+1, there's a new turbolinks/src/turbolinks/snapshot_renderer.coffee Lines 102 to 104 in c340c42
We should probably use it instead of the current implementation for consistency. |
Closes turbolinks#337 Background --- [Custom Elements][mdn] are a great fit for Turbolinks. Unfortunately, more often than not it's still required to use the `webcomponents.js` Custom Elements [polyfill] to support browsers other than Chrome and Safari 11. This, in itself, is not much of a problem. However, I noticed that on browsers that need to fall back to the polyfill, my custom elements' `connectedCallback` methods are not called after following a link, breaking them all. Problem --- When visiting a new page, Turbolinks currently replaces the body by setting `document.body`: ```coffee assignNewBody: -> document.body = @newbody ``` However, the polyfill cannot detect document.body changes (webcomponents/custom-elements#126). So it will not be able to walk the DOM and call the `connectedCallback` methods of all custom elements. Solution --- Previously, `Turbolinks` replaced the document body by setting `document.body`. However, the reference Custom Elements [polyfill] does not patch the `document.body` property, the `connectedCallback` of any custom elements in the new body will never be called. By using `document.documentElement.replaceChild()`, we make it possible for the Custom Elements polyfill to detect that new elements were connected do the DOM. [mdn]: https://developer.mozilla.org/en-US/docs/Web/Web_Components/Custom_Elements [polyfill]: https://github.com/webcomponents/custom-elements Co-authored-by: Sean Doyle <sean.p.doyle24@gmail.com> Co-authored-by: Denis Washington <denis@denisw.de>
@sstephenson @javan I've opened #431 so that the CI test suite can run on then change, and on the off-change that this PR stays inactive. If it'd be better for us to centralize the work to this PR, I'll gladly close #431. I've credited @denisw as a co-author on that commit. |
Background
Custom Elements are a great fit for Turbolinks (and are rightfully mentioned in the Turbolinks README). Unfortunately, more often than not it's still required to use the webcomponents.js Custom Elements polyfill to support browsers other than Chrome and Safari 11.
This, in itself, is not much of a problem. However, I noticed that on browsers that need to fall back to the polyfill, my custom elements'
connectedCallback
methods are not called after following a link, breaking them all. 😞The Problem
When visiting a new page, Turbolinks currently replaces the body by setting
document.body
:However, the polyfill cannot detect
document.body
changes (webcomponents/custom-elements#126). So it will not be able to walk the DOM and call theconnectedCallback
methods of all custom elements.The Solution
We can make the webcomponents.js polyfill aware of the body change by simply using
Element.prototype.replaceChild
instead:This version (implemented by this PR) is totally equivalent to setting
document.body
, butreplaceChild
is patched by the polyfill, soconnectedCallback
works as expected.There are no disadvantages to this change. As
replaceChild
is supported on all browsers including IE back to version 6, no new browser incompatibilities are introduced.