brinkiepie
5/2/2016 - 2:08 PM

Mithril wormhole: a component whose content is appended to the body instead of rendering in place

Mithril wormhole: a component whose content is appended to the body instead of rendering in place

import m      from 'mithril'
// This dependency resides here: 
// https://gist.github.com/barneycarroll/4144b93b6221f419bf7dcb5e847f8a22
import events from 'mithril-events'

// A hash of registered wormholes with values indicating status
const cache = Object.create( null )

// At the beginning of every draw, set the value of each to false,
// to indicate it hasn't registered this draw 
events.redraw.add( () => {
  for( let key in cache )
    cache[ key ].registered = false
}

// Then after draw...
events.config.add( () => {
  for( let key in cache ){
    const wormhole = cache[ key ]
    
    // If it hasn't re-registered
    if( !wormhole.registered ){
      // Remove its root from the DOM
      document.body.removeChild( wormhole.root )
      
      // And the entry from the cache
      delete cache[ key ]
    }
} )

// Export is a component: interface is easy & idiomatic.
export default {
  view( ctrl, { key = '' }, content ){
    let wormhole = cache[ key ]
    let fresh    = !wormhole
  
    // If the key isn't in the cache, create a new wormhole entry.
    if( fresh )
      wormhole = cache[ key ] = {
        // We need a root to render the content in
        root : document.createElement( 'div' )
      }
    
    // Render the content.
    m.render( wormhole.root, content )
    
    if( fresh )
      document.body.appendChild( wormhole.root )
    
    // Record registration to avoid teardown
    wormhole.registered = true
  }
}