diff --git a/text/0000-promote-in-element-to-public-api.md b/text/0000-promote-in-element-to-public-api.md new file mode 100644 index 0000000000..ab26417d8b --- /dev/null +++ b/text/0000-promote-in-element-to-public-api.md @@ -0,0 +1,102 @@ +- Start Date: 2017-12-22 +- RFC PR: (leave this empty) +- Ember Issue: (leave this empty) + +# Summary + +Promote the private API `{{-in-element}}` to public API as `{{in-element}}`. + +# Motivation + +Sometimes developers need to render content out of the regular HTML flow. This concept is often also +called "portals". Some components like dropdowns and modals use this technique to render stuff close +to the root of the page to bypass CSS overflow rules. Some apps that are embedded into static pages +even use this technique to update parts of the page **outside** the app itself. + +This need need has been covered by solutions developed in the user space but it was so common that +glimmer baked it into the VM in the form of `{{-in-element}}`, but it remains private (or _intimate_) API. +People is usually wary of using private APIs (and for good reason) as they may get removed at any time. + +If the core team and the community is happy with the current behavior of `{{-in-element}}` it's +time to make it public. + +# Detailed design + +The existing API of `{{-in-element}}` is very simple: + +* It takes a single positional param `destinationElement` that is a DOM element, and a block. +* The given block is rendered not where it is located, but inside the given `destination` element, at +the end of it if there is any other content on the destination element. +* If `destinationElement` is null/undefined then it doesn't render anything but it doesn't error. +* If `destinationElement` is false/0/"" it raises an assertion in development but fails silently in production. +* If `destinationElement` changes the block is removed from the previous destination and added to the new one. This +process tears down the rendered content on the initial destination and renders it again on the new one, meaning +that any component withing the block will be destroyed and instantiated again (calling the appropiate lifecycle hooks), +so transient HTML state like the value of an input will be lost unless manually preserved somewhere else, like a service. +* If the destination element is an invalid value (a string, a number ...) it throws an `parent.insertBefore is not a function` error. I think +that throwing an error is correct but the error message could be improved. +* If the destination element has a different context (like SVG) the content will be appended normally by the glimmer VM, +which doesn't try to validate the correctness of the generated HTML. This is normal behavior in Glimmer, not +an exception, and users must be aware that rendering invalid markup might be interpreted or auto-corrected in +unexpected ways by the browser when in SSR mode. +* Rendering into a foreign object (an element within an `