allow reserved words in tags e.g. {{class}} (#383)

pull/385/head
Rich Harris 8 years ago
parent ecf141346e
commit 854a37c0d7

@ -1,13 +1,24 @@
import { parseExpressionAt } from 'acorn'; import { parseExpressionAt } from 'acorn';
export default function readExpression ( parser ) { export default function readExpression ( parser ) {
const start = parser.index;
const name = parser.readUntil( /\s*}}/ );
if ( name && /^\w+$/.test( name ) ) {
return {
type: 'Identifier',
start,
end: start + name.length,
name
};
}
parser.index = start;
try { try {
const node = parseExpressionAt( parser.template, parser.index ); const node = parseExpressionAt( parser.template, parser.index );
parser.index = node.end; parser.index = node.end;
// TODO check it's a valid expression. probably shouldn't have
// [arrow] function expressions, etc
return node; return node;
} catch ( err ) { } catch ( err ) {
parser.acornError( err ); parser.acornError( err );

@ -0,0 +1,14 @@
export default {
data: {
class: 'foo'
},
html: `<div class="foo"></div>`,
test ( assert, component, target ) {
component.set({ class: 'bar' });
assert.equal( target.innerHTML, `<div class="bar"></div>` );
component.destroy();
}
};

@ -0,0 +1,40 @@
{
"hash": 3305933215,
"html": {
"start": 0,
"end": 29,
"type": "Fragment",
"children": [
{
"start": 0,
"end": 29,
"type": "Element",
"name": "div",
"attributes": [
{
"start": 5,
"end": 22,
"type": "Attribute",
"name": "class",
"value": [
{
"start": 12,
"end": 21,
"type": "MustacheTag",
"expression": {
"type": "Identifier",
"start": 14,
"end": 19,
"name": "class"
}
}
]
}
],
"children": []
}
]
},
"css": null,
"js": null
}

167
tmp.js

@ -0,0 +1,167 @@
import { createComment, insertNode, detachNode, teardownEach, createElement, addEventListener, removeEventListener, appendNode, createText, dispatchObservers, proto } from "/Users/rharris/Documents/www/SVELTE/svelte/shared.js"
function renderMainFragment ( root, component ) {
var eachBlock_anchor = createComment();
var eachBlock_value = root.values;
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 );
}
var text = createText( "\n\n" );
var p = createElement( 'p' );
var last_text1 = root.selected
var text1 = createText( last_text1 );
appendNode( text1, p );
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 );
}
insertNode( text, target, anchor );
insertNode( p, target, anchor );
},
update: function ( changed, root ) {
var __tmp;
var eachBlock_value = root.values;
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 );
}
}
teardownEach( eachBlock_iterations, true, eachBlock_value.length );
eachBlock_iterations.length = eachBlock_value.length;
if ( ( __tmp = root.selected ) !== last_text1 ) {
text1.data = last_text1 = __tmp;
}
},
teardown: function ( detach ) {
teardownEach( eachBlock_iterations, detach );
if ( detach ) {
detachNode( eachBlock_anchor );
detachNode( text );
detachNode( p );
}
}
};
}
function renderEachBlock ( root, eachBlock_value, value, value__index, component ) {
var label = createElement( 'label' );
var input = createElement( 'input' );
input.type = "checkbox";
var last_input_value = value;
input.value = input.__value = last_input_value;
var input_updating = false;
function inputChangeHandler () {
input_updating = true;
component._set({ selected: getBindingGroupValue( component._bindingGroups[0] ) });
input_updating = false;
}
addEventListener( input, 'change', inputChangeHandler );
appendNode( input, label );
input.group = root.selected;
appendNode( createText( " " ), label );
var last_text1 = value
var text1 = createText( last_text1 );
appendNode( text1, label );
return {
mount: function ( target, anchor ) {
insertNode( label, target, anchor );
},
update: function ( changed, root, eachBlock_value, value, value__index ) {
var __tmp;
if ( ( __tmp = value ) !== last_input_value ) {
last_input_value = __tmp;
input.value = input.__value = last_input_value;
}
if ( !input_updating ) {
input.checked = root.selected.indexOf( last_input_value ) !== -1;
}
if ( ( __tmp = value ) !== last_text1 ) {
text1.data = last_text1 = __tmp;
}
},
teardown: function ( detach ) {
removeEventListener( input, 'change', inputChangeHandler );
if ( detach ) {
detachNode( label );
}
}
};
}
function SvelteComponent ( 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._torndown = false;
this._fragment = renderMainFragment( this._state, this );
if ( options.target ) this._fragment.mount( options.target, null );
}
SvelteComponent.prototype = Object.assign( {}, proto );
SvelteComponent.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 );
};
SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = function destroy ( detach ) {
this.fire( 'destroy' );
this._fragment.teardown( detach !== false );
this._fragment = null;
this._state = {};
this._torndown = true;
};
export default SvelteComponent;
Loading…
Cancel
Save