bundle.js
(function () {
'use strict';
var template$1 = (function () {
return {
onrender () {
this.originalTitle = document.title;
this.observe( 'title', title => document.title = title );
},
onteardown () {
document.title = this.originalTitle;
}
};
}());
function renderMainFragment$1 ( root, component ) {
return {
mount: function ( target, anchor ) {
},
update: function ( changed, root ) {
},
teardown: function ( detach ) {
}
};
}
function Title ( options ) {
options = options || {};
var component = this;
var state = options.data || {};
var observers = {
immediate: Object.create( null ),
deferred: Object.create( null )
};
var callbacks = Object.create( null );
function dispatchObservers ( group, newState, oldState ) {
for ( var key in group ) {
if ( !( key in newState ) ) continue;
var newValue = newState[ key ];
var oldValue = oldState[ key ];
if ( newValue === oldValue && typeof newValue !== 'object' ) continue;
var callbacks = group[ key ];
if ( !callbacks ) continue;
for ( var i = 0; i < callbacks.length; i += 1 ) {
var callback = callbacks[i];
if ( callback.__calling ) continue;
callback.__calling = true;
callback.call( component, newValue, oldValue );
callback.__calling = false;
}
}
}
this.fire = function fire ( eventName, data ) {
var handlers = eventName in callbacks && callbacks[ eventName ].slice();
if ( !handlers ) return;
for ( var i = 0; i < handlers.length; i += 1 ) {
handlers[i].call( this, data );
}
};
this.get = function get ( key ) {
return key ? state[ key ] : state;
};
this.set = function set ( newState ) {
var oldState = state;
state = Object.assign( {}, oldState, newState );
dispatchObservers( observers.immediate, newState, oldState );
if ( mainFragment ) mainFragment.update( newState, state );
dispatchObservers( observers.deferred, newState, oldState );
};
this._mount = function mount ( target, anchor ) {
mainFragment.mount( target, anchor );
};
this.observe = function ( key, callback, options ) {
var group = ( options && options.defer ) ? observers.deferred : observers.immediate;
( group[ key ] || ( group[ key ] = [] ) ).push( callback );
if ( !options || options.init !== false ) {
callback.__calling = true;
callback.call( component, state[ key ] );
callback.__calling = false;
}
return {
cancel: function () {
var index = group[ key ].indexOf( callback );
if ( ~index ) group[ key ].splice( index, 1 );
}
};
};
this.on = function on ( eventName, handler ) {
var handlers = callbacks[ eventName ] || ( callbacks[ eventName ] = [] );
handlers.push( handler );
return {
cancel: function () {
var index = handlers.indexOf( handler );
if ( ~index ) handlers.splice( index, 1 );
}
};
};
this.teardown = function teardown ( detach ) {
this.fire( 'teardown' );
template$1.onteardown.call( this );
mainFragment.teardown( detach !== false );
mainFragment = null;
state = {};
};
this.root = options.root;
this.yield = options.yield;
var mainFragment = renderMainFragment$1( state, this );
if ( options.target ) this._mount( options.target );
if ( options.root ) {
options.root.__renderHooks.push({ fn: template$1.onrender, context: this });
} else {
template$1.onrender.call( this );
}
}
var template = (function () {
return {
data () {
return {
title: 'dynamic title woo!!!'
};
},
components: {
Title
}
};
}());
function renderMainFragment ( root, component ) {
var h1 = document.createElement( 'h1' );
h1.appendChild( document.createTextNode( "change the title" ) );
var text1 = document.createTextNode( "\n" );
var input = document.createElement( 'input' );
var input_updating = false;
function inputChangeHandler () {
input_updating = true;
component.set({ title: input.value });
input_updating = false;
}
input.addEventListener( 'input', inputChangeHandler, false );
input.value = root.title;
var text2 = document.createTextNode( "\n\n" );
var title_initialData = {
title: root.title
};
var title = new template.components.Title({
target: null,
root: component.root || component,
data: title_initialData
});
return {
mount: function ( target, anchor ) {
target.insertBefore( h1, anchor );
target.insertBefore( text1, anchor );
target.insertBefore( input, anchor );
target.insertBefore( text2, anchor );
title._mount( target, anchor );
},
update: function ( changed, root ) {
if ( !input_updating ) input.value = root.title;
var title_changes = {};
if ( 'title' in changed ) title_changes.title = root.title;
if ( Object.keys( title_changes ).length ) title.set( title_changes );
},
teardown: function ( detach ) {
input.removeEventListener( 'input', inputChangeHandler, false );
title.teardown( detach );
if ( detach ) {
h1.parentNode.removeChild( h1 );
text1.parentNode.removeChild( text1 );
input.parentNode.removeChild( input );
text2.parentNode.removeChild( text2 );
}
}
};
}
function App ( options ) {
options = options || {};
var component = this;
var state = Object.assign( template.data(), options.data );
var observers = {
immediate: Object.create( null ),
deferred: Object.create( null )
};
var callbacks = Object.create( null );
function dispatchObservers ( group, newState, oldState ) {
for ( var key in group ) {
if ( !( key in newState ) ) continue;
var newValue = newState[ key ];
var oldValue = oldState[ key ];
if ( newValue === oldValue && typeof newValue !== 'object' ) continue;
var callbacks = group[ key ];
if ( !callbacks ) continue;
for ( var i = 0; i < callbacks.length; i += 1 ) {
var callback = callbacks[i];
if ( callback.__calling ) continue;
callback.__calling = true;
callback.call( component, newValue, oldValue );
callback.__calling = false;
}
}
}
this.fire = function fire ( eventName, data ) {
var handlers = eventName in callbacks && callbacks[ eventName ].slice();
if ( !handlers ) return;
for ( var i = 0; i < handlers.length; i += 1 ) {
handlers[i].call( this, data );
}
};
this.get = function get ( key ) {
return key ? state[ key ] : state;
};
this.set = function set ( newState ) {
var oldState = state;
state = Object.assign( {}, oldState, newState );
dispatchObservers( observers.immediate, newState, oldState );
if ( mainFragment ) mainFragment.update( newState, state );
dispatchObservers( observers.deferred, newState, oldState );
while ( this.__renderHooks.length ) {
var hook = this.__renderHooks.pop();
hook.fn.call( hook.context );
}
};
this._mount = function mount ( target, anchor ) {
mainFragment.mount( target, anchor );
};
this.observe = function ( key, callback, options ) {
var group = ( options && options.defer ) ? observers.deferred : observers.immediate;
( group[ key ] || ( group[ key ] = [] ) ).push( callback );
if ( !options || options.init !== false ) {
callback.__calling = true;
callback.call( component, state[ key ] );
callback.__calling = false;
}
return {
cancel: function () {
var index = group[ key ].indexOf( callback );
if ( ~index ) group[ key ].splice( index, 1 );
}
};
};
this.on = function on ( eventName, handler ) {
var handlers = callbacks[ eventName ] || ( callbacks[ eventName ] = [] );
handlers.push( handler );
return {
cancel: function () {
var index = handlers.indexOf( handler );
if ( ~index ) handlers.splice( index, 1 );
}
};
};
this.teardown = function teardown ( detach ) {
this.fire( 'teardown' );
mainFragment.teardown( detach !== false );
mainFragment = null;
state = {};
};
this.root = options.root;
this.yield = options.yield;
this.__renderHooks = [];
var mainFragment = renderMainFragment( state, this );
if ( options.target ) this._mount( options.target );
while ( this.__renderHooks.length ) {
var hook = this.__renderHooks.pop();
hook.fn.call( hook.context );
}
}
new App({
target: document.querySelector( 'main' )
});
}());