This repository has been archived by the owner on Sep 13, 2022. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Some of these dependencies are no longer available on github, so embe…
…dding them.
- Loading branch information
Showing
24 changed files
with
1,222 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule copperplate
deleted from
ae2b7b
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
h2. Copperplate. | ||
|
||
JavaScript templating engine with HTML syntax. | ||
|
||
HTML syntax is a good idea. It blends in with your text editors HTML mode. Proper indentation in if/else blocks with no editor configuration, yay! | ||
|
||
h2. Control flow | ||
|
||
If and else. | ||
|
||
<pre><code>var t = new Copperplate("Hello, <if thing>World!</if><else>Moon.</else>"); | ||
|
||
t.html({thing: true}); // "Hello, World!" | ||
t.html({thing: false}); // "Hello, Moon."</code></pre> | ||
|
||
Elseif. | ||
|
||
<pre><code>var t = new Copperplate("<if one>One</if><elseif two>Two</elseif>"); | ||
|
||
t.html({one: true, two: false}); // "One" | ||
t.html({one: false, two: true}); // "Two" | ||
t.html({one: false, two: false}); // ""</code></pre> | ||
|
||
Nesting. | ||
|
||
<pre><code>var t = new Copperplate("" | ||
+ "<if one>" | ||
+ "<if two>two</if>" | ||
+ "<else>" | ||
+ "<if three>three</if>" | ||
+ "</else>" | ||
+ "</if>"); | ||
|
||
t.html({one: true, two: true, three: false}); // "two" | ||
t.html({one: true, two: false, three: false}); // "" | ||
t.html({one: true, two: false, three: true}); // "three" | ||
t.html({one: false, two: false, three: true}); // "" | ||
</code></pre> | ||
|
||
|
||
h2. Variables | ||
|
||
The variable syntax is <code>{{foo}}</code>. | ||
|
||
<pre><code> var t = new Copperplate('Hello, {{thing}}!'); | ||
t.html({thing: "World"}) // "Hello, World!"; | ||
t.html({thing: "Moon"}) // "Hello, Moon!";</code></pre> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
(function (GLOBAL) { | ||
var Copperplate = function (template) { | ||
this.template = template; | ||
} | ||
|
||
Copperplate.prototype = { | ||
html: function (data) { | ||
var elements = this.template.match(/\<[^\>]+\>|[^\<]+/g); | ||
var out = []; | ||
var ifBlocks = []; | ||
var previousTagWasConditionalEndTag; | ||
|
||
for (var i = 0, il = elements.length; i < il; i++) { | ||
var e = this.insertVariables(elements[i], data); | ||
var ifBlocksEntry = ifBlocks[ifBlocks.length - 1]; | ||
|
||
// End tag | ||
if (/^\<\//.test(e)) { | ||
var t = this.getTag(e); | ||
|
||
if (t[0] === "if") { | ||
previousTagWasConditionalEndTag = true; | ||
ifBlocksEntry.previousEndTag = "if"; | ||
} else if (t[0] === "else") { | ||
previousTagWasConditionalEndTag = true; | ||
if (ifBlocks.length === 0) { | ||
throw Error("Unexpected else, not in a tree.") | ||
} | ||
|
||
ifBlocksEntry.previousEndTag = "else"; | ||
|
||
ifBlocks.pop(); | ||
} else if (t[0] === "elseif") { | ||
if (previousTagWasConditionalEndTag) { | ||
ifBlocks.pop(); | ||
} | ||
|
||
previousTagWasConditionalEndTag = true; | ||
if (ifBlocks.length === 0) { | ||
throw Error("Unexpected elseif, not in a tree.") | ||
} | ||
|
||
ifBlocksEntry.previousEndTag = "elseif"; | ||
} else { | ||
if (ifBlocksEntry) { | ||
if (previousTagWasConditionalEndTag && ifBlocksEntry.previousEndTag) { | ||
ifBlocks.pop(); | ||
} | ||
} | ||
|
||
if (!this.ifBlocksContainsFalse(ifBlocks)) { | ||
out.push(e); | ||
} | ||
} | ||
|
||
|
||
// Start tag | ||
} else if (/^\</.test(e)) { | ||
var t = this.getTag(e); | ||
|
||
// State for | ||
var stateAttribute = t[1][0] && t[1][0][0]; | ||
var state = data[stateAttribute]; | ||
|
||
if (typeof(state) === "function") { | ||
state = state.call(data); | ||
} | ||
|
||
if (t[0] === "if") { | ||
if (ifBlocksEntry) { | ||
if (previousTagWasConditionalEndTag && ifBlocksEntry.previousEndTag === "if") { | ||
ifBlocks.pop(); | ||
} | ||
} | ||
|
||
ifBlocks.push({ | ||
didTerminate: state, | ||
currentState: state, | ||
previousEndTag: null | ||
}); | ||
|
||
previousTagWasConditionalEndTag = false; | ||
} else if (t[0] === "else") { | ||
previousTagWasConditionalEndTag = false; | ||
|
||
if (ifBlocksEntry.didTerminate) { | ||
ifBlocksEntry.currentState = false; | ||
continue; | ||
} else { | ||
ifBlocksEntry.currentState = !ifBlocksEntry.currentState; | ||
} | ||
} else if (t[0] === "elseif") { | ||
previousTagWasConditionalEndTag = false; | ||
|
||
if (ifBlocksEntry.didTerminate) { | ||
ifBlocksEntry.currentState = false; | ||
continue; | ||
} else { | ||
ifBlocksEntry.didTerminate = state; | ||
ifBlocksEntry.currentState = state; | ||
} | ||
} else { | ||
if (ifBlocksEntry) { | ||
if (previousTagWasConditionalEndTag && ifBlocksEntry.previousEndTag) { | ||
ifBlocks.pop(); | ||
} | ||
} | ||
|
||
if (!this.ifBlocksContainsFalse(ifBlocks)) { | ||
out.push(e); | ||
} | ||
} | ||
|
||
|
||
// Content | ||
} else { | ||
if (/^\s+$/.test(e)) { | ||
out.push(e); | ||
continue; | ||
} | ||
|
||
if (ifBlocksEntry) { | ||
if (previousTagWasConditionalEndTag && ifBlocksEntry.previousEndTag) { | ||
ifBlocks.pop(); | ||
} | ||
} | ||
|
||
|
||
if (!this.ifBlocksContainsFalse(ifBlocks)) { | ||
out.push(e); | ||
} | ||
} | ||
} | ||
|
||
return out.join(""); | ||
}, | ||
|
||
ifBlocksContainsFalse: function (ifBlocks) { | ||
var res = false; | ||
for (var j = 0, jl = ifBlocks.length; j < jl; j++) { | ||
if (!ifBlocks[j].currentState) { | ||
res = true; | ||
} | ||
} | ||
|
||
return res; | ||
}, | ||
|
||
getTag: function (tag) { | ||
var out = []; | ||
out.push(tag.match(/^\<\/?([a-zA-Z]+)/)[1]); | ||
|
||
var rawAttrs = tag.match(/^\<\/?[a-zA-Z]+ ([^\>]+)/); | ||
if (rawAttrs) { | ||
data = rawAttrs[1].split(/ +/g); | ||
var attrs = []; | ||
for (var i = 0, il = data.length; i < il; i++) { | ||
var split = data[i].split("="); | ||
var val = split[1] || null; | ||
|
||
if (val) { | ||
val = val.replace(/^['"](.*?)['"]$/, "$1"); | ||
} | ||
|
||
attrs.push([split[0], val]); | ||
} | ||
out.push(attrs); | ||
} else { | ||
out.push([]); | ||
} | ||
|
||
return out; | ||
}, | ||
|
||
insertVariables: function (string, data) { | ||
return string.replace(/{{([^}]+)}}/, function (all, key) { | ||
return data[key] || ""; | ||
}); | ||
} | ||
} | ||
|
||
GLOBAL.Copperplate = Copperplate; | ||
}(this)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
server: http://localhost:4224 | ||
|
||
load: | ||
- ../copperplate.js | ||
- tests/*_test.js |
Oops, something went wrong.