Skip to content

Commit

Permalink
Merge pull request #124 from sveltejs/raw-mustaches
Browse files Browse the repository at this point in the history
Raw mustaches
  • Loading branch information
Rich-Harris authored Dec 6, 2016
2 parents 108f741 + 91903cb commit 4a89354
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 0 deletions.
47 changes: 47 additions & 0 deletions compiler/generate/visitors/RawMustacheTag.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import deindent from '../utils/deindent.js';

export default {
enter ( generator, node ) {
const name = generator.current.counter( 'raw' );

generator.addSourcemapLocations( node.expression );
const { snippet } = generator.contextualise( node.expression );

// we would have used comments here, but the `insertAdjacentHTML` api only
// exists for `Element`s.
const before = `${name}_before`;
generator.addElement( before, `document.createElement( 'noscript' )`, true );
const after = `${name}_after`;
generator.addElement( after, `document.createElement( 'noscript' )`, true );

const isToplevel = generator.current.localElementDepth === 0;

const mountStatement = deindent`
${before}.insertAdjacentHTML( 'afterend', ${snippet} );
`;
const detachStatement = deindent`
while ( ${before}.nextSibling && ${before}.nextSibling !== ${after} ) {
${before}.parentNode.removeChild( ${before}.nextSibling );
}
`;

if ( isToplevel ) {
generator.current.mountStatements.push(mountStatement);
} else {
generator.current.initStatements.push(mountStatement);
}

generator.current.updateStatements.push( deindent`
${detachStatement}
${mountStatement}
` );

if ( isToplevel ) {
const { detachStatements } = generator.current;
// we need `before` and `after` to still be in the DOM when running the
// detach code, so splice in the detach code *before* detaching
// `before`/`after`.
detachStatements.splice( detachStatements.length - 2, 0, detachStatement);
}
}
};
2 changes: 2 additions & 0 deletions compiler/generate/visitors/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import EachBlock from './EachBlock.js';
import Element from './Element.js';
import IfBlock from './IfBlock.js';
import MustacheTag from './MustacheTag.js';
import RawMustacheTag from './RawMustacheTag.js';
import Text from './Text.js';
import YieldTag from './YieldTag.js';

Expand All @@ -12,6 +13,7 @@ export default {
Element,
IfBlock,
MustacheTag,
RawMustacheTag,
Text,
YieldTag
};
15 changes: 15 additions & 0 deletions compiler/parse/state/mustache.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,21 @@ export default function mustache ( parser ) {
});
}

// {{{raw}}} mustache
else if ( parser.eat( '{' ) ) {
const expression = readExpression( parser );

parser.allowWhitespace();
parser.eat( '}}}', true );

parser.current().children.push({
start,
end: parser.index,
type: 'RawMustacheTag',
expression
});
}

else {
const expression = readExpression( parser );

Expand Down
16 changes: 16 additions & 0 deletions test/compiler/raw-mustaches/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const ns = '<noscript></noscript>';
export default {
data: {
raw: '<span><em>raw html!!!\\o/</span></em>'
},
html: `before${ns}<span><em>raw html!!!\\o/</span></em>${ns}after`,

test ( assert, component, target ) {
component.set({ raw: '' });
assert.equal( target.innerHTML, `before${ns}${ns}after` );
component.set({ raw: 'how about <strong>unclosed elements?' });
assert.equal( target.innerHTML, `before${ns}how about <strong>unclosed elements?</strong>${ns}after` );
component.teardown();
assert.equal( target.innerHTML, '' );
}
};
1 change: 1 addition & 0 deletions test/compiler/raw-mustaches/main.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
before{{{raw}}}after
1 change: 1 addition & 0 deletions test/parser/raw-mustaches/input.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p> {{{raw1}}} {{{raw2}}} </p>
48 changes: 48 additions & 0 deletions test/parser/raw-mustaches/output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"html": {
"start": 0,
"end": 30,
"type": "Fragment",
"children": [
{
"start": 0,
"end": 30,
"type": "Element",
"name": "p",
"attributes": [],
"children": [
{
"start": 4,
"end": 14,
"type": "RawMustacheTag",
"expression": {
"start": 7,
"end": 11,
"type": "Identifier",
"name": "raw1"
}
},
{
"start": 14,
"end": 15,
"type": "Text",
"data": " "
},
{
"start": 15,
"end": 25,
"type": "RawMustacheTag",
"expression": {
"start": 18,
"end": 22,
"type": "Identifier",
"name": "raw2"
}
}
]
}
]
},
"css": null,
"js": null
}

0 comments on commit 4a89354

Please sign in to comment.