mirror of
https://github.com/adnexus/shuttle-select.git
synced 2026-07-26 22:08:50 +00:00
changing to static files served with apache
This commit is contained in:
@@ -0,0 +1 @@
|
||||
.DS_Store
|
||||
@@ -1,23 +0,0 @@
|
||||
Copyright (c) 2010 Chris Parsons
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
# Example node.js project
|
||||
|
||||
This repo is to show how I am currently architecting my node.js projects.
|
||||
|
||||
Please feel free to use it as a basis for your own projects.
|
||||
|
||||
The interesting bit is currently in test/integration/user_sees_homepage.js - note how I'm stubbing out the response object.
|
||||
|
||||
I welcome patches and improvements.
|
||||
|
||||
# Testing options
|
||||
|
||||
* [Mario Aquino](http://github.com/marioaquino/example-nodejs-project) has added support for NoSpec on his branch.
|
||||
* [James Carr](http://github.com/jamescarr/example-nodejs-project) has added JSpec support.
|
||||
@@ -1,18 +0,0 @@
|
||||
$:.unshift(File.dirname(__FILE__) + '/../../lib')
|
||||
require 'cucumber/rake/task'
|
||||
|
||||
namespace :test do
|
||||
task :unit do
|
||||
puts "\n\nUNIT TESTS\n----------"
|
||||
puts `node test/unit/*.js`
|
||||
puts 'Tests Complete'
|
||||
end
|
||||
task :integration do
|
||||
puts "\n\nINTEGRATION TESTS\n----------"
|
||||
puts `node test/integration/*.js`
|
||||
puts 'Tests Complete'
|
||||
end
|
||||
end
|
||||
task :test => ['test:unit', 'test:integration']
|
||||
task :default => :test
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
def run_all_tests
|
||||
print `clear`
|
||||
puts "Tests run #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
|
||||
puts `rake`
|
||||
end
|
||||
|
||||
run_all_tests
|
||||
watch("(test|lib)(/.*)+.js") { |m| run_all_tests }
|
||||
|
||||
@interrupted = false
|
||||
|
||||
# Ctrl-C
|
||||
Signal.trap "INT" do
|
||||
if @interrupted
|
||||
abort("\n")
|
||||
else
|
||||
puts "Interrupt a second time to quit"
|
||||
@interrupted = true
|
||||
Kernel.sleep 1.5
|
||||
|
||||
run_all_tests
|
||||
@interrupted = false
|
||||
end
|
||||
end
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Shuttle Select Prototype</title>
|
||||
<script charset='utf-8' src='http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js' type='text/javascript'></script>
|
||||
<script charset='utf-8' src='http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/jquery-ui.min.js' type='text/javascript'></script>
|
||||
<link charset='utf-8' href='http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/themes/base/jquery-ui.css' rel='stylesheet' type='text/css' />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1 +0,0 @@
|
||||
// Code for example model goes here
|
||||
@@ -1,8 +0,0 @@
|
||||
var http = require('http')
|
||||
|
||||
exports.serve = function(handleRequest) {
|
||||
http.createServer(function (request, response) {
|
||||
handleRequest(request, response)
|
||||
}).listen(parseInt(process.env.PORT) || 8888)
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
var http = require('./http')
|
||||
var fs = require('fs')
|
||||
var sys = require("sys")
|
||||
|
||||
var haml = require('../vendor/haml/lib/haml')
|
||||
var sass = require('../vendor/sass/lib/sass')
|
||||
|
||||
exports.dispatch = function (request, response) {
|
||||
if (request.url == '/') {
|
||||
response.writeHead(200, {'Content-Type': 'text/html'})
|
||||
fs.readFile("./views/index.html.haml", "utf8", function(error, data) {
|
||||
if (error) {
|
||||
var msg = "ERROR: "+sys.inspect(error);
|
||||
sys.debug(msg)
|
||||
response.write("<pre>"+msg+"</pre>", "utf8")
|
||||
} else {
|
||||
response.write(haml.render(data), "utf8")
|
||||
}
|
||||
response.end()
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
var http = require('./lib/http')
|
||||
var router = require('./lib/router')
|
||||
var fs = require('fs')
|
||||
|
||||
http.serve(router.dispatch)
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
router = require('../lib/router')
|
||||
sys = require("sys")
|
||||
assert = require('assert')
|
||||
assert.contains = function(expected, actual) {
|
||||
actual = actual || ""
|
||||
if(actual.indexOf(expected) == -1) {
|
||||
sys.debug("Expected:\n\n<"+actual+">\n\nto contain <"+expected+">")
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
require('../helper')
|
||||
|
||||
function Response(test_function) {
|
||||
var self = this
|
||||
self._data = ""
|
||||
self._headers = {}
|
||||
self.writeHead = function(status, headers) {
|
||||
self._headers = headers
|
||||
self._headers['status'] = status.toString()
|
||||
}
|
||||
self.write = function(data) {
|
||||
if (data) {
|
||||
self._data += data
|
||||
}
|
||||
}
|
||||
self.end = function(data, encoding) {
|
||||
self.write(data)
|
||||
test_function(self._headers, self._data)
|
||||
}
|
||||
}
|
||||
|
||||
Request = function(method, url) {
|
||||
this.method = method
|
||||
this.url = url
|
||||
}
|
||||
|
||||
// Test: user views front page
|
||||
router.dispatch(new Request("GET", "/"), new Response(function(headers, data) {
|
||||
assert.contains("200", headers['status'])
|
||||
assert.contains("Hello, world!", data)
|
||||
}));
|
||||
@@ -1,3 +0,0 @@
|
||||
require('../helper')
|
||||
require('../../lib/example')
|
||||
// Unit test for an example model go here
|
||||
Vendored
-506
@@ -1,506 +0,0 @@
|
||||
var Haml;
|
||||
|
||||
(function () {
|
||||
|
||||
var matchers, self_close_tags, embedder, forceXML;
|
||||
|
||||
function html_escape(text) {
|
||||
return (text + "").
|
||||
replace(/&/g, "&").
|
||||
replace(/</g, "<").
|
||||
replace(/>/g, ">").
|
||||
replace(/\"/g, """);
|
||||
}
|
||||
|
||||
function render_attribs(attribs) {
|
||||
var key, value, result = [];
|
||||
for (key in attribs) {
|
||||
if (key !== '_content' && attribs.hasOwnProperty(key)) {
|
||||
switch (attribs[key]) {
|
||||
case 'undefined':
|
||||
case 'false':
|
||||
case 'null':
|
||||
case '""':
|
||||
break;
|
||||
default:
|
||||
try {
|
||||
value = JSON.parse("[" + attribs[key] +"]")[0];
|
||||
if (value === true) {
|
||||
value = key;
|
||||
} else if (typeof value === 'string' && embedder.test(value)) {
|
||||
value = '" +\n' + parse_interpol(html_escape(value)) + ' +\n"';
|
||||
} else {
|
||||
value = html_escape(value);
|
||||
}
|
||||
result.push(" " + key + '=\\"' + value + '\\"');
|
||||
} catch (e) {
|
||||
result.push(" " + key + '=\\"" + html_escape(' + attribs[key] + ') + "\\"');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.join("");
|
||||
}
|
||||
|
||||
// Parse the attribute block using a state machine
|
||||
function parse_attribs(line) {
|
||||
var attributes = {},
|
||||
l = line.length,
|
||||
i, c,
|
||||
count = 1,
|
||||
quote = false,
|
||||
skip = false,
|
||||
open, close, joiner, seperator,
|
||||
pair = {
|
||||
start: 1,
|
||||
middle: null,
|
||||
end: null
|
||||
};
|
||||
|
||||
if (!(l > 0 && (line.charAt(0) === '{' || line.charAt(0) === '('))) {
|
||||
return {
|
||||
_content: line[0] === ' ' ? line.substr(1, l) : line
|
||||
};
|
||||
}
|
||||
open = line.charAt(0);
|
||||
close = (open === '{') ? '}' : ')';
|
||||
joiner = (open === '{') ? ':' : '=';
|
||||
seperator = (open === '{') ? ',' : ' ';
|
||||
|
||||
function process_pair() {
|
||||
if (typeof pair.start === 'number' &&
|
||||
typeof pair.middle === 'number' &&
|
||||
typeof pair.end === 'number') {
|
||||
var key = line.substr(pair.start, pair.middle - pair.start).trim(),
|
||||
value = line.substr(pair.middle + 1, pair.end - pair.middle - 1).trim();
|
||||
attributes[key] = value;
|
||||
}
|
||||
pair = {
|
||||
start: null,
|
||||
middle: null,
|
||||
end: null
|
||||
};
|
||||
}
|
||||
|
||||
for (i = 1; count > 0; i += 1) {
|
||||
|
||||
// If we reach the end of the line, then there is a problem
|
||||
if (i > l) {
|
||||
throw "Malformed attribute block";
|
||||
}
|
||||
|
||||
c = line.charAt(i);
|
||||
if (skip) {
|
||||
skip = false;
|
||||
} else {
|
||||
if (quote) {
|
||||
if (c === '\\') {
|
||||
skip = true;
|
||||
}
|
||||
if (c === quote) {
|
||||
quote = false;
|
||||
}
|
||||
} else {
|
||||
if (c === '"' || c === "'") {
|
||||
quote = c;
|
||||
}
|
||||
|
||||
if (count === 1) {
|
||||
if (c === joiner) {
|
||||
pair.middle = i;
|
||||
}
|
||||
if (c === seperator || c === close) {
|
||||
pair.end = i;
|
||||
process_pair();
|
||||
if (c === seperator) {
|
||||
pair.start = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (c === open || c === "(") {
|
||||
count += 1;
|
||||
}
|
||||
if (c === close || (count > 1 && c === ")")) {
|
||||
count -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
attributes._content = line.substr(i, line.length);
|
||||
return attributes;
|
||||
}
|
||||
|
||||
// Split interpolated strings into an array of literals and code fragments.
|
||||
function parse_interpol(value) {
|
||||
var items = [],
|
||||
pos = 0,
|
||||
next = 0,
|
||||
match;
|
||||
while (true) {
|
||||
// Match up to embedded string
|
||||
next = value.substr(pos).search(embedder);
|
||||
if (next < 0) {
|
||||
if (pos < value.length) {
|
||||
items.push(JSON.stringify(value.substr(pos)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
items.push(JSON.stringify(value.substr(pos, next)));
|
||||
pos += next;
|
||||
|
||||
// Match embedded string
|
||||
match = value.substr(pos).match(embedder);
|
||||
next = match[0].length;
|
||||
if (next < 0) { break; }
|
||||
items.push(match[1] || match[2]);
|
||||
pos += next;
|
||||
}
|
||||
return items.filter(function (part) { return part && part.length > 0}).join(" +\n");
|
||||
}
|
||||
|
||||
// Used to find embedded code in interpolated strings.
|
||||
embedder = /\#\{([^}]*)\}/;
|
||||
|
||||
self_close_tags = ["meta", "img", "link", "br", "hr", "input", "area", "base"];
|
||||
|
||||
// All matchers' regexps should capture leading whitespace in first capture
|
||||
// and trailing content in last capture
|
||||
matchers = [
|
||||
// html tags
|
||||
{
|
||||
regexp: /^(\s*)((?:[.#%][a-z_\-][a-z0-9_:\-]*)+)(.*)$/i,
|
||||
process: function () {
|
||||
var tag, classes, ids, attribs, content;
|
||||
tag = this.matches[2];
|
||||
classes = tag.match(/\.([a-z_\-][a-z0-9_\-]*)/gi);
|
||||
ids = tag.match(/\#([a-z_\-][a-z0-9_\-]*)/gi);
|
||||
tag = tag.match(/\%([a-z_\-][a-z0-9_:\-]*)/gi);
|
||||
|
||||
// Default to <div> tag
|
||||
tag = tag ? tag[0].substr(1, tag[0].length) : 'div';
|
||||
|
||||
attribs = this.matches[3];
|
||||
if (attribs) {
|
||||
attribs = parse_attribs(attribs);
|
||||
if (attribs._content) {
|
||||
this.contents.unshift(attribs._content.trim());
|
||||
delete(attribs._content);
|
||||
}
|
||||
} else {
|
||||
attribs = {};
|
||||
}
|
||||
|
||||
if (classes) {
|
||||
classes = classes.map(function (klass) {
|
||||
return klass.substr(1, klass.length);
|
||||
}).join(' ');
|
||||
if (attribs['class']) {
|
||||
try {
|
||||
attribs['class'] = JSON.stringify(classes + " " + JSON.parse(attribs['class']));
|
||||
} catch (e) {
|
||||
attribs['class'] = JSON.stringify(classes + " ") + " + " + attribs['class'];
|
||||
}
|
||||
} else {
|
||||
attribs['class'] = JSON.stringify(classes);
|
||||
}
|
||||
}
|
||||
if (ids) {
|
||||
ids = ids.map(function (id) {
|
||||
return id.substr(1, id.length);
|
||||
}).join(' ');
|
||||
if (attribs.id) {
|
||||
attribs.id = JSON.stringify(ids + " ") + attribs.id;
|
||||
} else {
|
||||
attribs.id = JSON.stringify(ids);
|
||||
}
|
||||
}
|
||||
|
||||
attribs = render_attribs(attribs);
|
||||
|
||||
content = this.render_contents();
|
||||
if (content === '""') {
|
||||
content = '';
|
||||
}
|
||||
|
||||
if (forceXML ? content.length > 0 : self_close_tags.indexOf(tag) == -1) {
|
||||
return '"<' + tag + attribs + '>"' +
|
||||
(content.length > 0 ? ' + \n' + content : "") +
|
||||
' + \n"</' + tag + '>"';
|
||||
} else {
|
||||
return '"<' + tag + attribs + ' />"';
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// each loops
|
||||
{
|
||||
regexp: /^(\s*)(?::for|:each)\s+(?:([a-z_][a-z_\-]*),\s*)?([a-z_][a-z_\-]*)\s+in\s+(.*)(\s*)$/i,
|
||||
process: function () {
|
||||
var ivar = this.matches[2] || '__key__', // index
|
||||
vvar = this.matches[3], // value
|
||||
avar = this.matches[4], // array
|
||||
rvar = '__result__'; // results
|
||||
|
||||
if (this.matches[5]) {
|
||||
this.contents.unshift(this.matches[5]);
|
||||
}
|
||||
return '(function () { ' +
|
||||
'var ' + rvar + ' = [], ' + ivar + ', ' + vvar + '; ' +
|
||||
'for (' + ivar + ' in ' + avar + ') { ' +
|
||||
'if (' + avar + '.hasOwnProperty(' + ivar + ')) { ' +
|
||||
vvar + ' = ' + avar + '[' + ivar + ']; ' +
|
||||
rvar + '.push(\n' + (this.render_contents() || "''") + '\n); ' +
|
||||
'} } return ' + rvar + '.join(""); }).call(this)';
|
||||
}
|
||||
},
|
||||
|
||||
// if statements
|
||||
{
|
||||
regexp: /^(\s*):if\s+(.*)\s*$/i,
|
||||
process: function () {
|
||||
var condition = this.matches[2];
|
||||
return '(function () { ' +
|
||||
'if (' + condition + ') { ' +
|
||||
'return (\n' + (this.render_contents() || '') + '\n);' +
|
||||
'} else { return ""; } }).call(this)';
|
||||
}
|
||||
},
|
||||
|
||||
// declarations
|
||||
{
|
||||
regexp: /^()!!!(?:\s*(.*))\s*$/,
|
||||
process: function () {
|
||||
var line = '';
|
||||
switch ((this.matches[2] || '').toLowerCase()) {
|
||||
case '':
|
||||
// XHTML 1.0 Transitional
|
||||
line = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
|
||||
break;
|
||||
case 'strict':
|
||||
case '1.0':
|
||||
// XHTML 1.0 Strict
|
||||
line = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
|
||||
break;
|
||||
case 'frameset':
|
||||
// XHTML 1.0 Frameset
|
||||
line = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">';
|
||||
break;
|
||||
case '5':
|
||||
// XHTML 5
|
||||
line = '<!DOCTYPE html>';
|
||||
break;
|
||||
case '1.1':
|
||||
// XHTML 1.1
|
||||
line = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">';
|
||||
break;
|
||||
case 'basic':
|
||||
// XHTML Basic 1.1
|
||||
line = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">';
|
||||
break;
|
||||
case 'mobile':
|
||||
// XHTML Mobile 1.2
|
||||
line = '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">';
|
||||
break;
|
||||
case 'xml':
|
||||
// XML
|
||||
line = "<?xml version='1.0' encoding='utf-8' ?>";
|
||||
break;
|
||||
case 'xml iso-8859-1':
|
||||
// XML iso-8859-1
|
||||
line = "<?xml version='1.0' encoding='iso-8859-1' ?>";
|
||||
break;
|
||||
}
|
||||
return JSON.stringify(line + "\n");
|
||||
}
|
||||
},
|
||||
|
||||
// Embedded markdown. Needs to be added to exports externally.
|
||||
{
|
||||
regexp: /^(\s*):markdown\s*$/i,
|
||||
process: function () {
|
||||
return parse_interpol(exports.Markdown.encode(this.contents.join("\n")));
|
||||
}
|
||||
},
|
||||
|
||||
// script blocks
|
||||
{
|
||||
regexp: /^(\s*):(?:java)?script\s*$/,
|
||||
process: function () {
|
||||
return parse_interpol('\n<script type="text/javascript">\n' +
|
||||
'//<![CDATA[\n' +
|
||||
this.contents.join("\n") +
|
||||
"\n//]]>\n</script>\n");
|
||||
}
|
||||
},
|
||||
|
||||
// css blocks
|
||||
{
|
||||
regexp: /^(\s*):css\s*$/,
|
||||
process: function () {
|
||||
return JSON.stringify('\n<style type="text/css">\n' +
|
||||
this.contents.join("\n") +
|
||||
"\n</style>\n");
|
||||
}
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
function compile(lines) {
|
||||
var block = false,
|
||||
output = [];
|
||||
|
||||
// If lines is a string, turn it into an array
|
||||
if (typeof lines === 'string') {
|
||||
lines = lines.trim().split("\n");
|
||||
}
|
||||
|
||||
lines.forEach(function(line) {
|
||||
var match, found = false;
|
||||
|
||||
// Collect all text as raw until outdent
|
||||
if (block) {
|
||||
match = block.check_indent(line);
|
||||
if (match) {
|
||||
block.contents.push(match[1] || "");
|
||||
return;
|
||||
} else {
|
||||
output.push(block.process());
|
||||
block = false;
|
||||
}
|
||||
}
|
||||
|
||||
matchers.forEach(function (matcher) {
|
||||
if (!found) {
|
||||
match = matcher.regexp(line);
|
||||
if (match) {
|
||||
block = {
|
||||
contents: [],
|
||||
matches: match,
|
||||
check_indent: new RegExp("^(?:\\s*|" + match[1] + " (.*))$"),
|
||||
process: matcher.process,
|
||||
render_contents: function () {
|
||||
return compile(this. contents);
|
||||
}
|
||||
};
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Match plain text
|
||||
if (!found) {
|
||||
output.push(function () {
|
||||
// Escaped plain text
|
||||
if (line[0] === '\\') {
|
||||
return parse_interpol(line.substr(1, line.length));
|
||||
}
|
||||
|
||||
// Plain variable data
|
||||
if (line[0] === '=') {
|
||||
line = line.substr(1, line.length).trim();
|
||||
try {
|
||||
return parse_interpol(JSON.parse(line));
|
||||
} catch (e) {
|
||||
return line;
|
||||
}
|
||||
}
|
||||
|
||||
// HTML escape variable data
|
||||
if (line.substr(0, 2) === "&=") {
|
||||
line = line.substr(2, line.length).trim();
|
||||
try {
|
||||
return JSON.stringify(html_escape(JSON.parse(line)));
|
||||
} catch (e2) {
|
||||
return 'html_escape(' + line + ')';
|
||||
}
|
||||
}
|
||||
|
||||
// Plain text
|
||||
return parse_interpol(line);
|
||||
}());
|
||||
}
|
||||
|
||||
});
|
||||
if (block) {
|
||||
output.push(block.process());
|
||||
}
|
||||
return output.filter(function (part) { return part && part.length > 0}).join(" +\n");
|
||||
};
|
||||
|
||||
function optimize(js) {
|
||||
var new_js = [], buffer = [], part, end;
|
||||
|
||||
function flush() {
|
||||
if (buffer.length > 0) {
|
||||
new_js.push(JSON.stringify(buffer.join("")) + end);
|
||||
buffer = [];
|
||||
}
|
||||
}
|
||||
js.split("\n").forEach(function (line) {
|
||||
part = line.match(/^(\".*\")(\s*\+\s*)?$/);
|
||||
if (!part) {
|
||||
flush();
|
||||
new_js.push(line);
|
||||
return;
|
||||
}
|
||||
end = part[2] || "";
|
||||
part = part[1];
|
||||
try {
|
||||
buffer.push(JSON.parse(part));
|
||||
} catch (e) {
|
||||
flush();
|
||||
new_js.push(line);
|
||||
}
|
||||
});
|
||||
flush();
|
||||
return new_js.join("\n");
|
||||
};
|
||||
|
||||
function render(text, options) {
|
||||
options = options || {};
|
||||
text = text || "";
|
||||
var js = compile(text);
|
||||
if (options.optimize) {
|
||||
js = Haml.optimize(js);
|
||||
}
|
||||
return execute(js, options.context || Haml, options.locals);
|
||||
};
|
||||
|
||||
function execute(js, self, locals) {
|
||||
return (function () {
|
||||
with(locals || {}) {
|
||||
try {
|
||||
return eval("(" + js + ")");
|
||||
} catch (e) {
|
||||
return "\n<pre class='error'>" + html_escape(e.stack) + "</pre>\n";
|
||||
}
|
||||
|
||||
}
|
||||
}).call(self);
|
||||
};
|
||||
|
||||
Haml = function Haml(haml, xml) {
|
||||
forceXML = xml;
|
||||
var js = optimize(compile(haml));
|
||||
return new Function("locals",
|
||||
html_escape + "\n" +
|
||||
"with(locals || {}) {\n" +
|
||||
" try {\n" +
|
||||
" return (" + js + ");\n" +
|
||||
" } catch (e) {\n" +
|
||||
" return \"\\n<pre class='error'>\" + html_escape(e.stack) + \"</pre>\\n\";\n" +
|
||||
" }\n" +
|
||||
"}");
|
||||
}
|
||||
Haml.compile = compile;
|
||||
Haml.optimize = optimize;
|
||||
Haml.render = render;
|
||||
Haml.execute = execute;
|
||||
|
||||
}());
|
||||
|
||||
// Hook into module system
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Haml;
|
||||
}
|
||||
Vendored
-299
@@ -1,299 +0,0 @@
|
||||
|
||||
// Sass - Core - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)
|
||||
|
||||
/**
|
||||
* Version triplet.
|
||||
*/
|
||||
|
||||
exports.version = '0.4.0'
|
||||
|
||||
/**
|
||||
* Compiled sass cache.
|
||||
*/
|
||||
|
||||
var cache = {}
|
||||
|
||||
/**
|
||||
* Sass grammar tokens.
|
||||
*/
|
||||
|
||||
var tokens = [
|
||||
['indent', /^\n +/],
|
||||
['space', /^ +/],
|
||||
['nl', /^\n/],
|
||||
['js', /^{(.*?)}/],
|
||||
['comment', /^\/\/(.*)/],
|
||||
['string', /^(?:'(.*?)'|"(.*?)")/],
|
||||
['variable', /^!([\w\-]+) *= *([^\n]+)/],
|
||||
['variable.alternate', /^([\w\-]+): +([^\n]+)/],
|
||||
['property.expand', /^=([\w\-]+) *([^\n]+)/],
|
||||
['property', /^:([\w\-]+) *([^\n]+)/],
|
||||
['continuation', /^&(.+)/],
|
||||
['mixin', /^\+([\w\-]+)/],
|
||||
['selector', /^(.+)/]
|
||||
]
|
||||
|
||||
/**
|
||||
* Vendor-specific expansion prefixes.
|
||||
*/
|
||||
|
||||
exports.expansions = ['-moz-', '-webkit-']
|
||||
|
||||
/**
|
||||
* Tokenize the given _str_.
|
||||
*
|
||||
* @param {string} str
|
||||
* @return {array}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function tokenize(str) {
|
||||
var token, captures, stack = []
|
||||
while (str.length) {
|
||||
for (var i = 0, len = tokens.length; i < len; ++i)
|
||||
if (captures = tokens[i][1].exec(str)) {
|
||||
token = [tokens[i][0], captures],
|
||||
str = str.replace(tokens[i][1], '')
|
||||
break
|
||||
}
|
||||
if (token)
|
||||
stack.push(token),
|
||||
token = null
|
||||
else
|
||||
throw new Error("SyntaxError: near `" + str.slice(0, 25).replace('\n', '\\n') + "'")
|
||||
}
|
||||
return stack
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given _tokens_, returning
|
||||
* and hash containing the properties below:
|
||||
*
|
||||
* selectors: array of top-level selectors
|
||||
* variables: hash of variables defined
|
||||
*
|
||||
* @param {array} tokens
|
||||
* @return {hash}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function parse(tokens) {
|
||||
var token, selector,
|
||||
data = { variables: {}, mixins: {}, selectors: [] },
|
||||
line = 1,
|
||||
lastIndents = 0,
|
||||
indents = 0
|
||||
|
||||
/**
|
||||
* Output error _msg_ in context to the current line.
|
||||
*/
|
||||
|
||||
function error(msg) {
|
||||
throw new Error('ParseError: on line ' + line + '; ' + msg)
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset parents until the indentation levels match.
|
||||
*/
|
||||
|
||||
function reset() {
|
||||
if (indents === 0)
|
||||
return selector = null
|
||||
while (lastIndents-- > indents)
|
||||
selector = selector.parent
|
||||
}
|
||||
|
||||
// Parse tokens
|
||||
|
||||
while (token = tokens.shift())
|
||||
switch (token[0]) {
|
||||
case 'mixin':
|
||||
if (indents) {
|
||||
var mixin = data.mixins[token[1][1]]
|
||||
if (!mixin) error("mixin `" + token[1][1] + "' does not exist")
|
||||
mixin.parent = selector
|
||||
selector.children.push(mixin)
|
||||
}
|
||||
else
|
||||
data.mixins[token[1][1]] = selector = new Selector(token[1][1], null, 'mixin')
|
||||
break
|
||||
case 'continuation':
|
||||
reset()
|
||||
selector = new Selector(token[1][1], selector, 'continuation')
|
||||
break
|
||||
case 'selector':
|
||||
reset()
|
||||
selector = new Selector(token[1][1], selector)
|
||||
if (!selector.parent)
|
||||
data.selectors.push(selector)
|
||||
break
|
||||
case 'property':
|
||||
reset()
|
||||
if (!selector) error('properties must be nested within a selector')
|
||||
var val = token[1][2]
|
||||
.replace(/!([\w\-]+)/g, function(orig, name){
|
||||
return data.variables[name] || orig
|
||||
})
|
||||
.replace(/\{(.*?)\}/g, function(_, js){
|
||||
with (data.variables){ return eval(js) }
|
||||
})
|
||||
selector.properties.push(new Property(token[1][1], val))
|
||||
break
|
||||
case 'property.expand':
|
||||
exports.expansions.forEach(function(prefix){
|
||||
tokens.unshift(['property', [, prefix + token[1][1], token[1][2]]])
|
||||
})
|
||||
break
|
||||
case 'variable':
|
||||
case 'variable.alternate':
|
||||
data.variables[token[1][1]] = token[1][2]
|
||||
break
|
||||
case 'js':
|
||||
with (data.variables){ eval(token[1][1]) }
|
||||
break
|
||||
case 'nl':
|
||||
++line, indents = 0
|
||||
break
|
||||
case 'comment':
|
||||
break
|
||||
case 'indent':
|
||||
++line
|
||||
lastIndents = indents,
|
||||
indents = (token[1][0].length - 1) / 2
|
||||
if (indents > lastIndents &&
|
||||
indents - 1 > lastIndents)
|
||||
error('invalid indentation, to much nesting')
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile _selectors_ to a string of css.
|
||||
*
|
||||
* @param {array} selectors
|
||||
* @return {string}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function compile(selectors) {
|
||||
return selectors.join('\n')
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect data by parsing _sass_.
|
||||
* Returns a hash containing the following properties:
|
||||
*
|
||||
* selectors: array of top-level selectors
|
||||
* variables: hash of variables defined
|
||||
*
|
||||
* @param {string} sass
|
||||
* @return {hash}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.collect = function(sass) {
|
||||
return parse(tokenize(sass))
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a string of _sass_.
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - filename Optional filename to aid in error reporting
|
||||
* - cache Optional caching of compiled content. Requires "filename" option
|
||||
*
|
||||
* @param {string} sass
|
||||
* @param {object} options
|
||||
* @return {string}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.render = function(sass, options) {
|
||||
options = options || {}
|
||||
if (options.cache && !options.filename)
|
||||
throw new Error('filename option must be passed when cache is enabled')
|
||||
if (options.cache)
|
||||
return cache[options.filename]
|
||||
? cache[options.filename]
|
||||
: cache[options.filename] = compile(exports.collect(sass).selectors)
|
||||
return compile(exports.collect(sass).selectors)
|
||||
}
|
||||
|
||||
// --- Selector
|
||||
|
||||
/**
|
||||
* Initialize a selector with _string_ and
|
||||
* optional _parent_.
|
||||
*
|
||||
* @param {string} string
|
||||
* @param {Selector} parent
|
||||
* @param {string} type
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function Selector(string, parent, type) {
|
||||
this.string = string
|
||||
this.parent = parent
|
||||
this.properties = []
|
||||
this.children = []
|
||||
if (type) this[type] = true
|
||||
if (parent) parent.children.push(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Return selector string.
|
||||
*
|
||||
* @return {string}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Selector.prototype.selector = function() {
|
||||
var selector = this.string
|
||||
if (this.parent)
|
||||
selector = this.continuation
|
||||
? this.parent.selector() + selector
|
||||
: this.mixin
|
||||
? this.parent.selector()
|
||||
: this.parent.selector() + ' ' + selector
|
||||
return selector
|
||||
}
|
||||
|
||||
/**
|
||||
* Return selector and nested selectors as CSS.
|
||||
*
|
||||
* @return {string}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Selector.prototype.toString = function() {
|
||||
return (this.properties.length
|
||||
? this.selector() + ' {\n' + this.properties.join('\n') + '}\n'
|
||||
: '') + this.children.join('')
|
||||
}
|
||||
|
||||
// --- Property
|
||||
|
||||
/**
|
||||
* Initialize property with _name_ and _val_.
|
||||
*
|
||||
* @param {string} name
|
||||
* @param {string} val
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function Property(name, val) {
|
||||
this.name = name
|
||||
this.val = val
|
||||
}
|
||||
|
||||
/**
|
||||
* Return CSS string representing a property.
|
||||
*
|
||||
* @return {string}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Property.prototype.toString = function() {
|
||||
return ' ' + this.name + ': ' + this.val + ';'
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
%html
|
||||
%head
|
||||
%title Shuttle Select Prototype
|
||||
%script{:charset => "utf-8", :src => "http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js", :type => "text/javascript"}
|
||||
%script{:charset => "utf-8", :src => "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/jquery-ui.min.js", :type => "text/javascript"}
|
||||
%link{:charset => "utf-8", :href => "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/themes/base/jquery-ui.css", :rel => "stylesheet", :type => "text/css"}
|
||||
%body
|
||||
%h1
|
||||
Reference in New Issue
Block a user