Skip to content
This repository has been archived by the owner on Sep 13, 2022. It is now read-only.

Commit

Permalink
Some of these dependencies are no longer available on github, so embe…
Browse files Browse the repository at this point in the history
…dding them.
  • Loading branch information
augustl committed Aug 30, 2011
1 parent 53c65f2 commit 8b379d3
Show file tree
Hide file tree
Showing 24 changed files with 1,222 additions and 17 deletions.
14 changes: 1 addition & 13 deletions .gitmodules
Expand Up @@ -6,16 +6,4 @@
url = git://github.com/augustl/js-unzip.git
[submodule "vendor/js-inflate"]
path = vendor/js-inflate
url = git://github.com/augustl/js-inflate.git
[submodule "vendor/sarge"]
path = vendor/sarge
url = git://github.com/augustl/sarge.git
[submodule "vendor/sarge-eventually"]
path = vendor/sarge-eventually
url = git://github.com/augustl/sarge-eventually.git
[submodule "vendor/sarge-standards-css-select"]
path = vendor/sarge-standards-css-select
url = git://github.com/augustl/sarge-standards-css-select.git
[submodule "vendor/copperplate"]
path = vendor/copperplate
url = git://github.com/augustl/copperplate
url = git://github.com/augustl/js-inflate.git
1 change: 0 additions & 1 deletion vendor/copperplate
Submodule copperplate deleted from ae2b7b
47 changes: 47 additions & 0 deletions vendor/copperplate/README.textile
@@ -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>
183 changes: 183 additions & 0 deletions vendor/copperplate/copperplate.js
@@ -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));
5 changes: 5 additions & 0 deletions vendor/copperplate/test/jsTestDriver.conf
@@ -0,0 +1,5 @@
server: http://localhost:4224

load:
- ../copperplate.js
- tests/*_test.js

0 comments on commit 8b379d3

Please sign in to comment.