Skip to content

Instantly share code, notes, and snippets.

@Rich-Harris
Created January 3, 2017 21:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Rich-Harris/831b8298670369f5024e344589c0f43e to your computer and use it in GitHub Desktop.
Save Rich-Harris/831b8298670369f5024e344589c0f43e to your computer and use it in GitHub Desktop.
.DS_Store
node_modules
{{#each people as person}}
<Person isLeader='{{leader === person}}' person='{{person}}' on:select='set({ leader: event.person })'/>
{{/each}}
<script>
import Person from './Person.html';
export default {
data: function () {
return {
leader: null,
people: [
{ name: 'Alice' },
{ name: 'Bob' },
{ name: 'Carol' }
]
};
},
components: {
Person
}
}
</script>
(function () {
'use strict';
function appendNode ( node, target ) {
target.appendChild( node );
}
function insertNode ( node, target, anchor ) {
target.insertBefore( node, anchor );
}
function detachNode ( node ) {
node.parentNode.removeChild( node );
}
function createElement ( name ) {
return document.createElement( name );
}
function createText ( data ) {
return document.createTextNode( data );
}
function createComment ( data ) {
return document.createComment( data );
}
function get ( key ) {
return key ? this._state[ key ] : this._state;
}
function fire ( eventName, data ) {
var handlers = eventName in this._handlers && this._handlers[ eventName ].slice();
if ( !handlers ) return;
for ( var i = 0; i < handlers.length; i += 1 ) {
handlers[i].call( this, data );
}
}
function observe ( key, callback, options ) {
var group = ( options && options.defer ) ? this._observers.pre : this._observers.post;
( group[ key ] || ( group[ key ] = [] ) ).push( callback );
if ( !options || options.init !== false ) {
callback.__calling = true;
callback.call( this, this._state[ key ] );
callback.__calling = false;
}
return {
cancel: function () {
var index = group[ key ].indexOf( callback );
if ( ~index ) group[ key ].splice( index, 1 );
}
};
}
function on ( eventName, handler ) {
var handlers = this._handlers[ eventName ] || ( this._handlers[ eventName ] = [] );
handlers.push( handler );
return {
cancel: function () {
var index = handlers.indexOf( handler );
if ( ~index ) handlers.splice( index, 1 );
}
};
}
function noop () {}
function dispatchObservers ( component, 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;
}
}
}
function renderMainFragment$1 ( root, component ) {
var div = createElement( 'div' );
var p = createElement( 'p' );
appendNode( p, div );
var strong = createElement( 'strong' );
appendNode( strong, p );
var text = createText( root.person.name );
appendNode( text, strong );
appendNode( createText( " " ), p );
var ifBlock_anchor = createComment( "#if isLeader" );
appendNode( ifBlock_anchor, p );
function getBlock ( root ) {
if ( root.isLeader ) return renderIfBlock_0;
return null;
}
var currentBlock = getBlock( root );
var ifBlock = currentBlock && currentBlock( root, component );
if ( ifBlock ) ifBlock.mount( ifBlock_anchor.parentNode, ifBlock_anchor );
appendNode( createText( "\n\t" ), div );
var button = createElement( 'button' );
function clickHandler ( event ) {
var root = this.__svelte.root;
component.fire("select", { person: root.person });
}
button.addEventListener( 'click', clickHandler, false );
button.disabled = root.isLeader;
button.__svelte = {
root: root
};
appendNode( button, div );
appendNode( createText( "make leader" ), button );
return {
mount: function ( target, anchor ) {
insertNode( div, target, anchor );
},
update: function ( changed, root ) {
text.data = root.person.name;
var _currentBlock = currentBlock;
currentBlock = getBlock( root );
if ( _currentBlock === currentBlock && ifBlock) {
ifBlock.update( changed, root );
} else {
if ( ifBlock ) ifBlock.teardown( true );
ifBlock = currentBlock && currentBlock( root, component );
if ( ifBlock ) ifBlock.mount( ifBlock_anchor.parentNode, ifBlock_anchor );
}
button.disabled = root.isLeader;
button.__svelte.root = root;
},
teardown: function ( detach ) {
if ( ifBlock ) ifBlock.teardown( false );
button.removeEventListener( 'click', clickHandler, false );
if ( detach ) {
detachNode( div );
}
},
};
}
function renderIfBlock_0 ( root, component ) {
var text = createText( "(leader)" );
return {
mount: function ( target, anchor ) {
insertNode( text, target, anchor );
},
update: noop,
teardown: function ( detach ) {
if ( detach ) {
detachNode( text );
}
},
};
}
function Person ( options ) {
options = options || {};
this._state = options.data || {};
this._observers = {
pre: Object.create( null ),
post: Object.create( null )
};
this._handlers = Object.create( null );
this._root = options._root;
this._yield = options._yield;
this._fragment = renderMainFragment$1( this._state, this );
if ( options.target ) this._fragment.mount( options.target, null );
}
Person.prototype.get = get;
Person.prototype.fire = fire;
Person.prototype.observe = observe;
Person.prototype.on = on;
Person.prototype.set = function set ( newState ) {
var oldState = this._state;
this._state = Object.assign( {}, oldState, newState );
dispatchObservers( this, this._observers.pre, newState, oldState );
if ( this._fragment ) this._fragment.update( newState, this._state );
dispatchObservers( this, this._observers.post, newState, oldState );
};
Person.prototype.teardown = function teardown ( detach ) {
this.fire( 'teardown' );
this._fragment.teardown( detach !== false );
this._fragment = null;
this._state = {};
};
var template = (function () {
return {
data: function () {
return {
leader: null,
people: [
{ name: 'Alice' },
{ name: 'Bob' },
{ name: 'Carol' }
]
};
},
components: {
Person
}
}
}());
function renderMainFragment ( root, component ) {
var eachBlock_anchor = createComment( "#each people" );
var eachBlock_value = root.people;
var eachBlock_iterations = [];
for ( var i = 0; i < eachBlock_value.length; i += 1 ) {
eachBlock_iterations[i] = renderEachBlock( root, eachBlock_value, eachBlock_value[i], i, component );
}
return {
mount: function ( target, anchor ) {
insertNode( eachBlock_anchor, target, anchor );
for ( var i = 0; i < eachBlock_iterations.length; i += 1 ) {
eachBlock_iterations[i].mount( eachBlock_anchor.parentNode, eachBlock_anchor );
}
},
update: function ( changed, root ) {
var eachBlock_value = root.people;
for ( var i = 0; i < eachBlock_value.length; i += 1 ) {
if ( !eachBlock_iterations[i] ) {
eachBlock_iterations[i] = renderEachBlock( root, eachBlock_value, eachBlock_value[i], i, component );
eachBlock_iterations[i].mount( eachBlock_anchor.parentNode, eachBlock_anchor );
} else {
eachBlock_iterations[i].update( changed, root, eachBlock_value, eachBlock_value[i], i );
}
}
for ( var i = eachBlock_value.length; i < eachBlock_iterations.length; i += 1 ) {
eachBlock_iterations[i].teardown( true );
}
eachBlock_iterations.length = eachBlock_value.length;
},
teardown: function ( detach ) {
for ( var i = 0; i < eachBlock_iterations.length; i += 1 ) {
eachBlock_iterations[i].teardown( detach );
}
if ( detach ) {
detachNode( eachBlock_anchor );
}
},
};
}
function renderEachBlock ( root, eachBlock_value, person, person__index, component ) {
var person1_initialData = {
isLeader: root.leader === person,
person: person
};
var person1 = new template.components.Person({
target: null,
_root: component._root || component,
data: person1_initialData
});
person1.on( 'select', function ( event ) {
component.set({ leader: event.person });
});
return {
mount: function ( target, anchor ) {
person1._fragment.mount( target, anchor );
},
update: function ( changed, root, eachBlock_value, person, person__index ) {
var person = eachBlock_value[person__index];
var person1_changes = {};
if ( 'leader' in changed||'people' in changed ) person1_changes.isLeader = root.leader === person;
if ( 'people' in changed ) person1_changes.person = person;
if ( Object.keys( person1_changes ).length ) person1.set( person1_changes );
},
teardown: function ( detach ) {
person1.teardown( detach );
},
};
}
function App ( options ) {
options = options || {};
this._state = Object.assign( template.data(), options.data );
this._observers = {
pre: Object.create( null ),
post: Object.create( null )
};
this._handlers = Object.create( null );
this._root = options._root;
this._yield = options._yield;
this._renderHooks = [];
this._fragment = renderMainFragment( this._state, this );
if ( options.target ) this._fragment.mount( options.target, null );
while ( this._renderHooks.length ) {
var hook = this._renderHooks.pop();
hook.fn.call( hook.context );
}
}
App.prototype.get = get;
App.prototype.fire = fire;
App.prototype.observe = observe;
App.prototype.on = on;
App.prototype.set = function set ( newState ) {
var oldState = this._state;
this._state = Object.assign( {}, oldState, newState );
dispatchObservers( this, this._observers.pre, newState, oldState );
if ( this._fragment ) this._fragment.update( newState, this._state );
dispatchObservers( this, this._observers.post, newState, oldState );
while ( this._renderHooks.length ) {
var hook = this._renderHooks.pop();
hook.fn.call( hook.context );
}
};
App.prototype.teardown = function teardown ( detach ) {
this.fire( 'teardown' );
this._fragment.teardown( detach !== false );
this._fragment = null;
this._state = {};
};
new App({
target: document.querySelector( 'main' )
});
}());
<body>
<main></main>
<script src='bundle.js'></script>
</body>
import App from './App.html';
new App({
target: document.querySelector( 'main' )
});
{
"name": "svelte-component-list",
"devDependencies": {
"rollup": "^0.40.0",
"rollup-plugin-svelte": "^1.6.0"
},
"scripts": {
"build": "rollup -c"
}
}
<div>
<p><strong>{{person.name}}</strong> {{#if isLeader}}(leader){{/if}}</p>
<button on:click='fire("select", { person: person })' disabled='{{isLeader}}'>make leader</button>
</div>
import svelte from 'rollup-plugin-svelte';
export default {
entry: 'main.js',
dest: 'bundle.js',
format: 'iife',
plugins: [
svelte()
]
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment