Skip to content

Instantly share code, notes, and snippets.

@barneycarroll
Created February 11, 2017 14:41
Show Gist options
  • Save barneycarroll/33a0b46a49359b3919362f4cf5c13282 to your computer and use it in GitHub Desktop.
Save barneycarroll/33a0b46a49359b3919362f4cf5c13282 to your computer and use it in GitHub Desktop.
Work in progress: component for moving vnode state and DOM across parent boundaries

Intended ussage:

var components = [
  { key : 1, component : Component1 },
  { key : 2, component : Component2 },
]

m(Dis, {
  view: ({state: {place}}) => [
    m('button', {
      onclick(){
        components.reverse()
      }
    },
      'Displace'
    )

    m('.wrapper1',
      place(components[0].key, m(components[0].component)
     
      m('.wrapper2',
       place(components[1].key, m(components[1].component)
      )
    )
  ]
}
const patch = (dom, now, then) => {
const host = document.createDocumentFragment()
const {domSize} = then
host.vnodes = then
for(
let i = 0, node = then.dom;
i < domSize;
i++, node = node.nextSibling
){
host.appendChild(node.cloneNode(true))
Promise.resolve().then(() =>
node.parentNode.removeChild(node)
)
}
m.render(host, now)
dom.parentNode.replaceChild(host, dom)
}
const Holder = {
view({attrs: {view = Function.prototype}}){
return view.apply(this, arguments)
}
}
const Dis = {
oninit(){
this.placements = {}
},
place(key, ...children){
const {placements} = this
let displaced = false
const update = vnode => {
if( displaced ){
patch(vnode.dom, children, placements[key])
}
placements[key] = [vnode]
}
return m(Holder, {
oninit({children}){
Object.assign(this, {key, children})
},
onbeforeupdate({}, {children}){
if(key in placements && key != this.key){
displaced = true
Object.assign(this, {key, children})
}
},
view(){
return displaced ? this.children : children
},
oncreate: update,
onupdate: update
})
},
view: Holder.view
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment