diff --git a/Gemfile b/Gemfile index 2e9f0e9..1e44d36 100644 --- a/Gemfile +++ b/Gemfile @@ -5,3 +5,4 @@ gem "therubyracer", ">= 0.9.8", "< 0.11" gem "rspec" gem "uglifier" gem "listen" +gem "coffee-script" diff --git a/Gemfile.lock b/Gemfile.lock index 3524cc7..e797927 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,10 @@ GEM remote: http://rubygems.org/ specs: + coffee-script (2.2.0) + coffee-script-source + execjs + coffee-script-source (1.4.0) diff-lcs (1.1.3) execjs (1.4.0) multi_json (~> 1.0) @@ -26,6 +30,7 @@ PLATFORMS ruby DEPENDENCIES + coffee-script listen rake rspec diff --git a/Rakefile b/Rakefile index 4f0e403..3f8794a 100644 --- a/Rakefile +++ b/Rakefile @@ -2,23 +2,25 @@ require "rubygems" require "bundler/setup" require 'find' require 'uglifier' +require 'coffee-script' SRC_PATH = './src' BUILD_PATH = './lib' -COFFEES = %w{ emblem compiler preprocessor translation emberties } +COFFEES = %w{ emblem compiler preprocessor emberties } #minimal_deps = %w(base compiler/parser compiler/base compiler/ast utils compiler/compiler runtime).map do |file| desc 'Compiles and concatenates source coffeescript files' task :coffee do - files = join_filenames( - COFFEES.map { |file| "#{file}.coffee" }, - SRC_PATH - ) - # Compile everything - `coffee -b --output #{BUILD_PATH} --compile #{files}` + COFFEES.each do |src| + File.open("#{BUILD_PATH}/#{src}.js", 'w') do |f| + js = CoffeeScript.compile(File.read("#{SRC_PATH}/#{src}.coffee"), bare: true) + f.puts js + end + end + if $?.to_i == 0 puts "Compiled successfully." else @@ -88,7 +90,7 @@ def remove_exports(string) string = string.gsub(/^(module\.)/, "// \1") end -minimal_deps = %w(emblem parser compiler preprocessor translation emberties).map do |file| +minimal_deps = %w(emblem parser compiler preprocessor emberties).map do |file| "lib/#{file}.js" end diff --git a/dist/emblem.js b/dist/emblem.js index 82f1da1..7aa128d 100644 --- a/dist/emblem.js +++ b/dist/emblem.js @@ -2164,7 +2164,6 @@ Handlebars.template = Handlebars.VM.template; ; // lib/emblem.js -// Generated by CoffeeScript 1.4.0 var Emblem; this.Emblem = {}; @@ -2181,12 +2180,11 @@ Emblem = this.Emblem; //  -//  - //  ; // lib/parser.js +//  //  Emblem.Parser = (function(){ @@ -2347,66 +2345,185 @@ Emblem.Parser = (function(){ } function parse_content() { - var r0, r1; + var r0, r1, r2; + r1 = pos; r0 = []; - r1 = parse_statement(); - while (r1 !== null) { - r0.push(r1); - r1 = parse_statement(); + r2 = parse_statement(); + while (r2 !== null) { + r0.push(r2); + r2 = parse_statement(); + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(statements) { + // Coalesce all adjacent ContentNodes into one. + + var compressedStatements = []; + var buffer = []; + + for(var i = 0; i < statements.length; ++i) { + var nodes = statements[i]; + + for(var j = 0; j < nodes.length; ++j) { + var node = nodes[j] + if(node.type === "content") { + if(node.string) { + // Ignore empty strings (comments). + buffer.push(node.string); + } + continue; + } + + // Flush content if present. + if(buffer.length) { + compressedStatements.push(new Handlebars.AST.ContentNode(buffer.join(''))); + buffer = []; + } + compressedStatements.push(node); + } + } + + if(buffer.length) { + compressedStatements.push(new Handlebars.AST.ContentNode(buffer.join(''))); + } + + return compressedStatements; + })(r0); + } + if (r0 === null) { + pos = r1; } return r0; } - function parse_statement() { - var r0; + function parse_invertibleContent() { + var r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12; - r0 = parse_comment(); - if (r0 === null) { - r0 = parse_html(); - if (r0 === null) { - r0 = parse_mustache(); + r1 = pos; + r2 = pos; + r3 = parse_content(); + if (r3 !== null) { + r5 = pos; + r6 = pos; + r7 = parse_DEDENT(); + if (r7 !== null) { + if (input.substr(pos, 4) === "else") { + r8 = "else"; + pos += 4; + } else { + r8 = null; + if (reportFailures === 0) { + matchFailed("\"else\""); + } + } + if (r8 !== null) { + r9 = parse__(); + if (r9 !== null) { + r10 = parse_TERM(); + if (r10 !== null) { + r11 = parse_INDENT(); + if (r11 !== null) { + r12 = parse_content(); + if (r12 !== null) { + r4 = [r7, r8, r9, r10, r11, r12]; + } else { + r4 = null; + pos = r6; + } + } else { + r4 = null; + pos = r6; + } + } else { + r4 = null; + pos = r6; + } + } else { + r4 = null; + pos = r6; + } + } else { + r4 = null; + pos = r6; + } + } else { + r4 = null; + pos = r6; + } + if (r4 !== null) { + reportedPos = r5; + r4 = (function(c) {return c;})(r12); + } + if (r4 === null) { + pos = r5; + } + r4 = r4 !== null ? r4 : ""; + if (r4 !== null) { + r0 = [r3, r4]; + } else { + r0 = null; + pos = r2; } + } else { + r0 = null; + pos = r2; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(c, i) { + return new Handlebars.AST.ProgramNode(c, i || []); + })(r3, r4); + } + if (r0 === null) { + pos = r1; } return r0; } - function parse_html() { - var r0, r1; + function parse_statement() { + var r0; - r0 = parse_htmlMaybeBlock(); + r0 = parse_comment(); if (r0 === null) { - r0 = parse_htmlWithInlineContent(); + r0 = parse_htmlElement(); if (r0 === null) { - r1 = pos; r0 = parse_textLine(); - if (r0 !== null) { - reportedPos = r1; - r0 = (function(t) { return t; })(r0); - } if (r0 === null) { - pos = r1; + r0 = parse_mustache(); } } } return r0; } + function parse_htmlElement() { + var r0; + + r0 = parse_htmlElementMaybeBlock(); + if (r0 === null) { + r0 = parse_htmlElementWithInlineContent(); + } + return r0; + } + function parse_mustache() { var r0, r1; r1 = pos; - r0 = parse_forcedMustache(); + r0 = parse_explicitMustache(); + if (r0 === null) { + r0 = parse_lineStartingMustache(); + } if (r0 !== null) { reportedPos = r1; - r0 = (function(f) { return f; })(r0); + r0 = (function(m) { + return [m]; + })(r0); } if (r0 === null) { pos = r1; } - if (r0 === null) { - r0 = parse_mustacheMaybeBlock(); - } return r0; } @@ -2505,7 +2622,7 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function() { return ""; })(); + r0 = (function() { return []; })(); } if (r0 === null) { pos = r1; @@ -2513,34 +2630,41 @@ Emblem.Parser = (function(){ return r0; } - function parse_htmlMaybeBlock() { - var r0, r1, r2, r3, r4, r5, r6, r7, r8; + function parse_lineStartingMustache() { + var r0; + + r0 = parse_capitalizedLineStarterMustache(); + if (r0 === null) { + r0 = parse_mustacheMaybeBlock(); + } + return r0; + } + + function parse_capitalizedLineStarterMustache() { + var r0, r1, r2, r3, r4; r1 = pos; r2 = pos; - r3 = parse_htmlAttributesOnly(); - if (r3 !== null) { - r5 = pos; - r6 = parse_INDENT(); - if (r6 !== null) { - r7 = parse_content(); - if (r7 !== null) { - r8 = parse_DEDENT(); - if (r8 !== null) { - r4 = [r6, r7, r8]; - } else { - r4 = null; - pos = r5; - } - } else { - r4 = null; - pos = r5; - } - } else { - r4 = null; - pos = r5; + r4 = pos; + reportFailures++; + if (/^[A-Z]/.test(input.charAt(pos))) { + r3 = input.charAt(pos); + pos++; + } else { + r3 = null; + if (reportFailures === 0) { + matchFailed("[A-Z]"); } - r4 = r4 !== null ? r4 : ""; + } + reportFailures--; + if (r3 !== null) { + r3 = ""; + pos = r4; + } else { + r3 = null; + } + if (r3 !== null) { + r4 = parse_mustacheMaybeBlock(); if (r4 !== null) { r0 = [r3, r4]; } else { @@ -2553,10 +2677,19 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(h, c) { - h.nodes = c ? c[1] : []; - return h; - })(r3, r4); + r0 = (function(ret) { + // TODO make this configurable + var defaultCapitalizedHelper = 'view'; + + if(ret.mustache) { + // Block. Modify inner MustacheNode and return. + ret.mustache = unshiftParam(ret.mustache, defaultCapitalizedHelper); + return ret; + } else { + // ret is the MustacheNode + return unshiftParam(ret, defaultCapitalizedHelper); + } + })(r4); } if (r0 === null) { pos = r1; @@ -2564,18 +2697,44 @@ Emblem.Parser = (function(){ return r0; } - function parse_htmlAttributesOnly() { - var r0, r1, r2, r3, r4, r5; + function parse_htmlElementMaybeBlock() { + var r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10; r1 = pos; r2 = pos; - r3 = parse_htmlTag(); + r3 = parse_htmlTagAndOptionalAttributes(); if (r3 !== null) { r4 = parse__(); if (r4 !== null) { r5 = parse_TERM(); if (r5 !== null) { - r0 = [r3, r4, r5]; + r7 = pos; + r8 = parse_INDENT(); + if (r8 !== null) { + r9 = parse_content(); + if (r9 !== null) { + r10 = parse_DEDENT(); + if (r10 !== null) { + r6 = [r8, r9, r10]; + } else { + r6 = null; + pos = r7; + } + } else { + r6 = null; + pos = r7; + } + } else { + r6 = null; + pos = r7; + } + r6 = r6 !== null ? r6 : ""; + if (r6 !== null) { + r0 = [r3, r4, r5, r6]; + } else { + r0 = null; + pos = r2; + } } else { r0 = null; pos = r2; @@ -2590,7 +2749,15 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(t) { t.nodes = []; return t; })(r3); + r0 = (function(h, c) { + var ret = h[0]; + if(c) { + ret = ret.concat(c[1]); + } + ret.push(h[1]); + + return ret; + })(r3, r6); } if (r0 === null) { pos = r1; @@ -2598,24 +2765,26 @@ Emblem.Parser = (function(){ return r0; } - function parse_htmlWithInlineContent() { - var r0, r1, r2, r3, r4, r5, r6; + function parse_htmlElementWithInlineContent() { + var r0, r1, r2, r3, r4, r5; r1 = pos; r2 = pos; - r3 = parse_htmlTag(); + r3 = parse_htmlTagAndOptionalAttributes(); if (r3 !== null) { - r4 = parse_whitespace(); + if (input.charCodeAt(pos) === 32) { + r4 = " "; + pos++; + } else { + r4 = null; + if (reportFailures === 0) { + matchFailed("\" \""); + } + } if (r4 !== null) { r5 = parse_htmlInlineContent(); if (r5 !== null) { - r6 = parse_TERM(); - if (r6 !== null) { - r0 = [r3, r4, r5, r6]; - } else { - r0 = null; - pos = r2; - } + r0 = [r3, r4, r5]; } else { r0 = null; pos = r2; @@ -2630,7 +2799,15 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(t, c) { t.nodes = c; return t; })(r3, r5); + r0 = (function(h, c) { + var ret = h[0]; + if(c) { + ret = ret.concat(c); + } + ret.push(h[1]); + + return ret; + })(r3, r5); } if (r0 === null) { pos = r1; @@ -2639,37 +2816,43 @@ Emblem.Parser = (function(){ } function parse_mustacheMaybeBlock() { - var r0, r1, r2, r3, r4, r5, r6, r7, r8, r9; + var r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10; r1 = pos; r2 = pos; - r3 = parse_mustacheContent(); + r3 = parse_inMustache(); if (r3 !== null) { - r4 = parse_TERM(); + r4 = parse__(); if (r4 !== null) { - r6 = pos; - r7 = parse_INDENT(); - if (r7 !== null) { - r8 = parse_content(); + r5 = parse_TERM(); + if (r5 !== null) { + r7 = pos; + r8 = parse_INDENT(); if (r8 !== null) { - r9 = parse_DEDENT(); + r9 = parse_invertibleContent(); if (r9 !== null) { - r5 = [r7, r8, r9]; + r10 = parse_DEDENT(); + if (r10 !== null) { + r6 = [r8, r9, r10]; + } else { + r6 = null; + pos = r7; + } } else { - r5 = null; - pos = r6; + r6 = null; + pos = r7; } } else { - r5 = null; - pos = r6; + r6 = null; + pos = r7; + } + r6 = r6 !== null ? r6 : ""; + if (r6 !== null) { + r0 = [r3, r4, r5, r6]; + } else { + r0 = null; + pos = r2; } - } else { - r5 = null; - pos = r6; - } - r5 = r5 !== null ? r5 : ""; - if (r5 !== null) { - r0 = [r3, r4, r5]; } else { r0 = null; pos = r2; @@ -2684,10 +2867,11 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(t, c) { - t.nodes = c ? c[1] : []; - return t; - })(r3, r5); + r0 = (function(mustacheNode, block) { + if(!block) return mustacheNode; + var programNode = block[1]; + return new Handlebars.AST.BlockNode(mustacheNode, programNode, programNode.inverse, mustacheNode.id); + })(r3, r6); } if (r0 === null) { pos = r1; @@ -2695,22 +2879,16 @@ Emblem.Parser = (function(){ return r0; } - function parse_forcedMustache() { - var r0, r1, r2, r3, r4, r5; + function parse_explicitMustache() { + var r0, r1, r2, r3, r4; r1 = pos; r2 = pos; - r3 = parse__(); + r3 = parse_equalSign(); if (r3 !== null) { - r4 = parse_equalSign(); + r4 = parse_mustacheMaybeBlock(); if (r4 !== null) { - r5 = parse_mustacheMaybeBlock(); - if (r5 !== null) { - r0 = [r3, r4, r5]; - } else { - r0 = null; - pos = r2; - } + r0 = [r3, r4]; } else { r0 = null; pos = r2; @@ -2721,7 +2899,11 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(e, c) { c.forced = true; c.escaped = e; return c; })(r4, r5); + r0 = (function(e, ret) { + var mustache = ret.mustache || ret; + mustache.escaped = e; + return ret; + })(r3, r4); } if (r0 === null) { pos = r1; @@ -2729,35 +2911,31 @@ Emblem.Parser = (function(){ return r0; } - function parse_mustacheContent() { - var r0, r1, r2, r3, r4, r5; + function parse_inMustache() { + var r0, r1, r2, r3, r4, r5, r6; r1 = pos; r2 = pos; - r4 = pos; - reportFailures++; - if (/^[A-Za-z]/.test(input.charAt(pos))) { - r3 = input.charAt(pos); - pos++; - } else { - r3 = null; - if (reportFailures === 0) { - matchFailed("[A-Za-z]"); - } - } - reportFailures--; - if (r3 !== null) { - r3 = ""; - pos = r4; - } else { - r3 = null; - } + r3 = parse_pathIdNode(); if (r3 !== null) { - r4 = parse_params(); + r4 = parse_trailingModifier(); + r4 = r4 !== null ? r4 : ""; if (r4 !== null) { - r5 = parse_hash(); + r5 = []; + r6 = parse_inMustacheParam(); + while (r6 !== null) { + r5.push(r6); + r6 = parse_inMustacheParam(); + } if (r5 !== null) { - r0 = [r3, r4, r5]; + r6 = parse_hash(); + r6 = r6 !== null ? r6 : ""; + if (r6 !== null) { + r0 = [r3, r4, r5, r6]; + } else { + r0 = null; + pos = r2; + } } else { r0 = null; pos = r2; @@ -2772,9 +2950,21 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(p, h) { - return { type: 'mustache', params:p, hash:h }; - })(r4, r5); + r0 = (function(path, tm, params, hash) { + params.unshift(path); + + var mustacheNode = new Handlebars.AST.MustacheNode(params, hash); + + if(tm == '!') { + return unshiftParam(mustacheNode, 'unbound'); + } else if(tm == '?') { + return unshiftParam(mustacheNode, 'if'); + } else if(tm == '^') { + return unshiftParam(mustacheNode, 'unless'); + } + + return mustacheNode; + })(r3, r4, r5, r6); } if (r0 === null) { pos = r1; @@ -2782,123 +2972,59 @@ Emblem.Parser = (function(){ return r0; } - function parse_params() { - var r0, r1, r2, r3, r4, r5, r6, r7, r8; + function parse_modifiedParam() { + var r0, r1, r2, r3, r4; r1 = pos; - r3 = pos; - r4 = pos; - r5 = parse__(); - if (r5 !== null) { - r6 = parse_param(); - if (r6 !== null) { - r8 = pos; - reportFailures++; - if (input.charCodeAt(pos) === 61) { - r7 = "="; - pos++; - } else { - r7 = null; - if (reportFailures === 0) { - matchFailed("\"=\""); - } - } - reportFailures--; - if (r7 === null) { - r7 = ""; - } else { - r7 = null; - pos = r8; - } - if (r7 !== null) { - r8 = parse__(); - if (r8 !== null) { - r2 = [r5, r6, r7, r8]; - } else { - r2 = null; - pos = r4; - } - } else { - r2 = null; - pos = r4; - } + r2 = pos; + r3 = parse_param(); + if (r3 !== null) { + r4 = parse_trailingModifier(); + if (r4 !== null) { + r0 = [r3, r4]; } else { - r2 = null; - pos = r4; + r0 = null; + pos = r2; } } else { - r2 = null; - pos = r4; + r0 = null; + pos = r2; } - if (r2 !== null) { - reportedPos = r3; - r2 = (function(param) {return param;})(r6); + if (r0 !== null) { + reportedPos = r1; + r0 = (function(p, m) { + var ret = new String(p); + ret.trailingModifier = m; + return ret; + })(r3, r4); } - if (r2 === null) { - pos = r3; + if (r0 === null) { + pos = r1; } - if (r2 !== null) { - r0 = []; - while (r2 !== null) { - r0.push(r2); - r3 = pos; - r4 = pos; - r5 = parse__(); - if (r5 !== null) { - r6 = parse_param(); - if (r6 !== null) { - r8 = pos; - reportFailures++; - if (input.charCodeAt(pos) === 61) { - r7 = "="; - pos++; - } else { - r7 = null; - if (reportFailures === 0) { - matchFailed("\"=\""); - } - } - reportFailures--; - if (r7 === null) { - r7 = ""; - } else { - r7 = null; - pos = r8; - } - if (r7 !== null) { - r8 = parse__(); - if (r8 !== null) { - r2 = [r5, r6, r7, r8]; - } else { - r2 = null; - pos = r4; - } - } else { - r2 = null; - pos = r4; - } - } else { - r2 = null; - pos = r4; - } - } else { - r2 = null; - pos = r4; - } - if (r2 !== null) { - reportedPos = r3; - r2 = (function(param) {return param;})(r6); - } - if (r2 === null) { - pos = r3; - } + return r0; + } + + function parse_inMustacheParam() { + var r0, r1, r2, r3, r4; + + r1 = pos; + r2 = pos; + r3 = parse__(); + if (r3 !== null) { + r4 = parse_param(); + if (r4 !== null) { + r0 = [r3, r4]; + } else { + r0 = null; + pos = r2; } } else { r0 = null; + pos = r2; } if (r0 !== null) { reportedPos = r1; - r0 = (function(p) { return p; })(r0); + r0 = (function(p) { return p; })(r4); } if (r0 === null) { pos = r1; @@ -2906,23 +3032,38 @@ Emblem.Parser = (function(){ return r0; } - function parse_param() { + function parse_trailingModifier() { + var r0; + + if (/^[!?*\^]/.test(input.charAt(pos))) { + r0 = input.charAt(pos); + pos++; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("[!?*\\^]"); + } + } + return r0; + } + + function parse_hash() { var r0, r1, r2; r1 = pos; - r2 = parse_paramChar(); + r2 = parse_hashSegment(); if (r2 !== null) { r0 = []; while (r2 !== null) { r0.push(r2); - r2 = parse_paramChar(); + r2 = parse_hashSegment(); } } else { r0 = null; } if (r0 !== null) { reportedPos = r1; - r0 = (function(p) { return p.join(''); })(r0); + r0 = (function(h) { return new Handlebars.AST.HashNode(h); })(r0); } if (r0 === null) { pos = r1; @@ -2930,56 +3071,107 @@ Emblem.Parser = (function(){ return r0; } - function parse_paramChar() { - var r0; + function parse_pathIdent() { + var r0, r1, r2, r3, r4, r5; - r0 = parse_alpha(); + if (input.substr(pos, 2) === "..") { + r0 = ".."; + pos += 2; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"..\""); + } + } if (r0 === null) { - if (input.charCodeAt(pos) === 95) { - r0 = "_"; + if (input.charCodeAt(pos) === 46) { + r0 = "."; pos++; } else { r0 = null; if (reportFailures === 0) { - matchFailed("\"_\""); + matchFailed("\".\""); } } if (r0 === null) { - if (input.charCodeAt(pos) === 45) { - r0 = "-"; + r1 = pos; + r2 = pos; + if (/^[a-zA-Z0-9_$\-]/.test(input.charAt(pos))) { + r4 = input.charAt(pos); pos++; } else { - r0 = null; + r4 = null; if (reportFailures === 0) { - matchFailed("\"-\""); + matchFailed("[a-zA-Z0-9_$\\-]"); } } - if (r0 === null) { - if (input.charCodeAt(pos) === 46) { - r0 = "."; + if (r4 !== null) { + r3 = []; + while (r4 !== null) { + r3.push(r4); + if (/^[a-zA-Z0-9_$\-]/.test(input.charAt(pos))) { + r4 = input.charAt(pos); + pos++; + } else { + r4 = null; + if (reportFailures === 0) { + matchFailed("[a-zA-Z0-9_$\\-]"); + } + } + } + } else { + r3 = null; + } + if (r3 !== null) { + r5 = pos; + reportFailures++; + if (input.charCodeAt(pos) === 61) { + r4 = "="; pos++; } else { - r0 = null; + r4 = null; if (reportFailures === 0) { - matchFailed("\".\""); + matchFailed("\"=\""); } } + reportFailures--; + if (r4 === null) { + r4 = ""; + } else { + r4 = null; + pos = r5; + } + if (r4 !== null) { + r0 = [r3, r4]; + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(s) { return s.join(''); })(r3); + } + if (r0 === null) { + pos = r1; } } } return r0; } - function parse_hash() { - var r0, r1, r2, r3, r4, r5, r6, r7, r8, r9; + function parse_hashSegment() { + var r0, r1, r2, r3, r4, r5, r6, r7, r8; r1 = pos; - r0 = []; - r3 = pos; - r4 = pos; - r5 = parse__(); - if (r5 !== null) { - r6 = parse_param(); + r2 = pos; + r3 = parse__(); + if (r3 !== null) { + r5 = pos; + r6 = parse_ident(); if (r6 !== null) { if (input.charCodeAt(pos) === 61) { r7 = "="; @@ -2991,45 +3183,24 @@ Emblem.Parser = (function(){ } } if (r7 !== null) { - r8 = parse_hashValue(); + r8 = parse_pathIdNode(); if (r8 !== null) { - r9 = parse__(); - if (r9 !== null) { - r2 = [r5, r6, r7, r8, r9]; - } else { - r2 = null; - pos = r4; - } + r4 = [r6, r7, r8]; } else { - r2 = null; - pos = r4; + r4 = null; + pos = r5; } } else { - r2 = null; - pos = r4; + r4 = null; + pos = r5; } } else { - r2 = null; - pos = r4; + r4 = null; + pos = r5; } - } else { - r2 = null; - pos = r4; - } - if (r2 !== null) { - reportedPos = r3; - r2 = (function(k, v) { return { key: k, value: v }; })(r6, r8); - } - if (r2 === null) { - pos = r3; - } - while (r2 !== null) { - r0.push(r2); - r3 = pos; - r4 = pos; - r5 = parse__(); - if (r5 !== null) { - r6 = parse_param(); + if (r4 === null) { + r5 = pos; + r6 = parse_ident(); if (r6 !== null) { if (input.charCodeAt(pos) === 61) { r7 = "="; @@ -3041,64 +3212,296 @@ Emblem.Parser = (function(){ } } if (r7 !== null) { - r8 = parse_hashValue(); + r8 = parse_stringNode(); if (r8 !== null) { - r9 = parse__(); - if (r9 !== null) { - r2 = [r5, r6, r7, r8, r9]; - } else { - r2 = null; - pos = r4; - } + r4 = [r6, r7, r8]; } else { - r2 = null; - pos = r4; + r4 = null; + pos = r5; } } else { - r2 = null; - pos = r4; + r4 = null; + pos = r5; } } else { - r2 = null; - pos = r4; + r4 = null; + pos = r5; + } + if (r4 === null) { + r5 = pos; + r6 = parse_ident(); + if (r6 !== null) { + if (input.charCodeAt(pos) === 61) { + r7 = "="; + pos++; + } else { + r7 = null; + if (reportFailures === 0) { + matchFailed("\"=\""); + } + } + if (r7 !== null) { + r8 = parse_integerNode(); + if (r8 !== null) { + r4 = [r6, r7, r8]; + } else { + r4 = null; + pos = r5; + } + } else { + r4 = null; + pos = r5; + } + } else { + r4 = null; + pos = r5; + } + if (r4 === null) { + r5 = pos; + r6 = parse_ident(); + if (r6 !== null) { + if (input.charCodeAt(pos) === 61) { + r7 = "="; + pos++; + } else { + r7 = null; + if (reportFailures === 0) { + matchFailed("\"=\""); + } + } + if (r7 !== null) { + r8 = parse_booleanNode(); + if (r8 !== null) { + r4 = [r6, r7, r8]; + } else { + r4 = null; + pos = r5; + } + } else { + r4 = null; + pos = r5; + } + } else { + r4 = null; + pos = r5; + } + } + } + } + if (r4 !== null) { + r0 = [r3, r4]; + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(h) { return [h[0], h[2]]; })(r4); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_param() { + var r0; + + r0 = parse_pathIdNode(); + if (r0 === null) { + r0 = parse_stringNode(); + if (r0 === null) { + r0 = parse_integerNode(); + if (r0 === null) { + r0 = parse_booleanNode(); + } + } + } + return r0; + } + + function parse_path() { + var r0, r1, r2, r3, r4, r5, r6, r7, r8, r9; + + r1 = pos; + r2 = pos; + r3 = parse_pathIdent(); + if (r3 !== null) { + r4 = []; + r6 = pos; + r7 = pos; + r8 = parse_seperator(); + if (r8 !== null) { + r9 = parse_pathIdent(); + if (r9 !== null) { + r5 = [r8, r9]; + } else { + r5 = null; + pos = r7; + } + } else { + r5 = null; + pos = r7; + } + if (r5 !== null) { + reportedPos = r6; + r5 = (function(p) { return p; })(r9); + } + if (r5 === null) { + pos = r6; + } + while (r5 !== null) { + r4.push(r5); + r6 = pos; + r7 = pos; + r8 = parse_seperator(); + if (r8 !== null) { + r9 = parse_pathIdent(); + if (r9 !== null) { + r5 = [r8, r9]; + } else { + r5 = null; + pos = r7; + } + } else { + r5 = null; + pos = r7; + } + if (r5 !== null) { + reportedPos = r6; + r5 = (function(p) { return p; })(r9); + } + if (r5 === null) { + pos = r6; + } + } + if (r4 !== null) { + r0 = [r3, r4]; + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(first, tail) { + var ret = [first]; + for(var i = 0; i < tail.length; ++i) { + //ret = ret.concat(tail[i]); + ret.push(tail[i]); + } + return ret; + })(r3, r4); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_seperator() { + var r0; + + if (/^[\/.]/.test(input.charAt(pos))) { + r0 = input.charAt(pos); + pos++; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("[\\/.]"); + } + } + return r0; + } + + function parse_pathIdNode() { + var r0, r1; + + r1 = pos; + r0 = parse_path(); + if (r0 !== null) { + reportedPos = r1; + r0 = (function(v) { return new Handlebars.AST.IdNode(v); })(r0); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_stringNode() { + var r0, r1; + + r1 = pos; + r0 = parse_string(); + if (r0 !== null) { + reportedPos = r1; + r0 = (function(v) { return new Handlebars.AST.StringNode(v); })(r0); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_integerNode() { + var r0, r1; + + r1 = pos; + r0 = parse_integer(); + if (r0 !== null) { + reportedPos = r1; + r0 = (function(v) { return new Handlebars.AST.IntegerNode(v); })(r0); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_booleanNode() { + var r0, r1; + + r1 = pos; + r0 = parse_boolean(); + if (r0 !== null) { + reportedPos = r1; + r0 = (function(v) { return new Handlebars.AST.BooleanNode(v); })(r0); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_boolean() { + var r0; + + if (input.substr(pos, 4) === "true") { + r0 = "true"; + pos += 4; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"true\""); + } + } + if (r0 === null) { + if (input.substr(pos, 5) === "false") { + r0 = "false"; + pos += 5; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"false\""); } - } else { - r2 = null; - pos = r4; - } - if (r2 !== null) { - reportedPos = r3; - r2 = (function(k, v) { return { key: k, value: v }; })(r6, r8); - } - if (r2 === null) { - pos = r3; - } - } - if (r0 !== null) { - reportedPos = r1; - r0 = (function(h) { - var ret = {}; - for(var i = 0; i < h.length; ++i) { - var pair = h[i]; - ret[pair.key] = pair.value; - } - return ret; - })(r0); - } - if (r0 === null) { - pos = r1; - } - return r0; - } - - function parse_hashValue() { - var r0; - - r0 = parse_string(); - if (r0 === null) { - r0 = parse_param(); - if (r0 === null) { - r0 = parse_integer(); } } return r0; @@ -3224,7 +3627,7 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(p) { return p.join(''); })(r0); + r0 = (function(p) { return p[1]; })(r0); } if (r0 === null) { pos = r1; @@ -3323,7 +3726,7 @@ Emblem.Parser = (function(){ var r0, r1; r1 = pos; - r0 = parse_forcedMustache(); + r0 = parse_explicitMustache(); if (r0 !== null) { reportedPos = r1; r0 = (function(m) { return [m]; })(r0); @@ -3338,7 +3741,7 @@ Emblem.Parser = (function(){ } function parse_textLine() { - var r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17; + var r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12; r1 = pos; r2 = pos; @@ -3365,176 +3768,68 @@ Emblem.Parser = (function(){ if (r4 !== null) { r5 = parse_textNodes(); if (r5 !== null) { - r6 = parse_TERM(); - if (r6 !== null) { - r7 = []; - r9 = pos; - r10 = pos; - r11 = parse_INDENT(); + r6 = []; + r8 = pos; + r9 = pos; + r10 = parse_INDENT(); + if (r10 !== null) { + r11 = parse_textNodes(); if (r11 !== null) { - r14 = pos; - r15 = pos; - r16 = parse_textNodes(); - if (r16 !== null) { - r17 = parse_TERM(); - if (r17 !== null) { - r13 = [r16, r17]; - } else { - r13 = null; - pos = r15; - } - } else { - r13 = null; - pos = r15; - } - if (r13 !== null) { - reportedPos = r14; - r13 = (function(n) { return n;})(r16); - } - if (r13 === null) { - pos = r14; - } - if (r13 !== null) { - r12 = []; - while (r13 !== null) { - r12.push(r13); - r14 = pos; - r15 = pos; - r16 = parse_textNodes(); - if (r16 !== null) { - r17 = parse_TERM(); - if (r17 !== null) { - r13 = [r16, r17]; - } else { - r13 = null; - pos = r15; - } - } else { - r13 = null; - pos = r15; - } - if (r13 !== null) { - reportedPos = r14; - r13 = (function(n) { return n;})(r16); - } - if (r13 === null) { - pos = r14; - } - } - } else { - r12 = null; - } + r12 = parse_DEDENT(); if (r12 !== null) { - r13 = parse_DEDENT(); - if (r13 !== null) { - r8 = [r11, r12, r13]; - } else { - r8 = null; - pos = r10; - } + r7 = [r10, r11, r12]; } else { - r8 = null; - pos = r10; + r7 = null; + pos = r9; } } else { - r8 = null; - pos = r10; - } - if (r8 !== null) { - reportedPos = r9; - r8 = (function(n) { return n; })(r12); - } - if (r8 === null) { + r7 = null; pos = r9; } - while (r8 !== null) { - r7.push(r8); - r9 = pos; - r10 = pos; - r11 = parse_INDENT(); + } else { + r7 = null; + pos = r9; + } + if (r7 !== null) { + reportedPos = r8; + r7 = (function(t) { return t; })(r11); + } + if (r7 === null) { + pos = r8; + } + while (r7 !== null) { + r6.push(r7); + r8 = pos; + r9 = pos; + r10 = parse_INDENT(); + if (r10 !== null) { + r11 = parse_textNodes(); if (r11 !== null) { - r14 = pos; - r15 = pos; - r16 = parse_textNodes(); - if (r16 !== null) { - r17 = parse_TERM(); - if (r17 !== null) { - r13 = [r16, r17]; - } else { - r13 = null; - pos = r15; - } - } else { - r13 = null; - pos = r15; - } - if (r13 !== null) { - reportedPos = r14; - r13 = (function(n) { return n;})(r16); - } - if (r13 === null) { - pos = r14; - } - if (r13 !== null) { - r12 = []; - while (r13 !== null) { - r12.push(r13); - r14 = pos; - r15 = pos; - r16 = parse_textNodes(); - if (r16 !== null) { - r17 = parse_TERM(); - if (r17 !== null) { - r13 = [r16, r17]; - } else { - r13 = null; - pos = r15; - } - } else { - r13 = null; - pos = r15; - } - if (r13 !== null) { - reportedPos = r14; - r13 = (function(n) { return n;})(r16); - } - if (r13 === null) { - pos = r14; - } - } - } else { - r12 = null; - } + r12 = parse_DEDENT(); if (r12 !== null) { - r13 = parse_DEDENT(); - if (r13 !== null) { - r8 = [r11, r12, r13]; - } else { - r8 = null; - pos = r10; - } + r7 = [r10, r11, r12]; } else { - r8 = null; - pos = r10; + r7 = null; + pos = r9; } } else { - r8 = null; - pos = r10; - } - if (r8 !== null) { - reportedPos = r9; - r8 = (function(n) { return n; })(r12); - } - if (r8 === null) { + r7 = null; pos = r9; } + } else { + r7 = null; + pos = r9; } if (r7 !== null) { - r0 = [r3, r4, r5, r6, r7]; - } else { - r0 = null; - pos = r2; + reportedPos = r8; + r7 = (function(t) { return t; })(r11); } + if (r7 === null) { + pos = r8; + } + } + if (r6 !== null) { + r0 = [r3, r4, r5, r6]; } else { r0 = null; pos = r2; @@ -3554,11 +3849,11 @@ Emblem.Parser = (function(){ if (r0 !== null) { reportedPos = r1; r0 = (function(nodes, indentedNodes) { - if(indentedNodes.length) { - nodes = nodes.concat(indentedNodes[0][0]); + for(var i = 0; i < indentedNodes.length; ++i) { + nodes = nodes.concat(indentedNodes[i]); } return nodes; - })(r5, r7); + })(r5, r6); } if (r0 === null) { pos = r1; @@ -3609,7 +3904,13 @@ Emblem.Parser = (function(){ } } if (r4 !== null) { - r0 = [r3, r4]; + r5 = parse_TERM(); + if (r5 !== null) { + r0 = [r3, r4, r5]; + } else { + r0 = null; + pos = r2; + } } else { r0 = null; pos = r2; @@ -3640,43 +3941,119 @@ Emblem.Parser = (function(){ function parse_rawMustache() { var r0; - r0 = parse_rawMustacheEscaped(); + r0 = parse_rawMustacheUnescaped(); if (r0 === null) { - r0 = parse_rawMustacheUnescaped(); + r0 = parse_rawMustacheEscaped(); } return r0; } - function parse_rawMustacheUnescaped() { + function parse_rawMustacheSingle() { var r0, r1, r2, r3, r4, r5, r6, r7; r1 = pos; r2 = pos; - if (input.substr(pos, 2) === "{{") { - r3 = "{{"; - pos += 2; - } else { - r3 = null; - if (reportFailures === 0) { - matchFailed("\"{{\""); + r3 = parse_singleOpen(); + if (r3 !== null) { + r4 = parse__(); + if (r4 !== null) { + r5 = parse_inMustache(); + if (r5 !== null) { + r6 = parse__(); + if (r6 !== null) { + r7 = parse_singleClose(); + if (r7 !== null) { + r0 = [r3, r4, r5, r6, r7]; + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; } + } else { + r0 = null; + pos = r2; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(m) { m.escaped = true; return m; })(r5); + } + if (r0 === null) { + pos = r1; } + return r0; + } + + function parse_rawMustacheEscaped() { + var r0, r1, r2, r3, r4, r5, r6, r7; + + r1 = pos; + r2 = pos; + r3 = parse_doubleOpen(); if (r3 !== null) { r4 = parse__(); if (r4 !== null) { - r5 = parse_mustacheContent(); + r5 = parse_inMustache(); if (r5 !== null) { r6 = parse__(); if (r6 !== null) { - if (input.substr(pos, 2) === "}}") { - r7 = "}}"; - pos += 2; + r7 = parse_doubleClose(); + if (r7 !== null) { + r0 = [r3, r4, r5, r6, r7]; } else { - r7 = null; - if (reportFailures === 0) { - matchFailed("\"}}\""); - } + r0 = null; + pos = r2; } + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(m) { m.escaped = true; return m; })(r5); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_rawMustacheUnescaped() { + var r0, r1, r2, r3, r4, r5, r6, r7; + + r1 = pos; + r2 = pos; + r3 = parse_tripleOpen(); + if (r3 !== null) { + r4 = parse__(); + if (r4 !== null) { + r5 = parse_inMustache(); + if (r5 !== null) { + r6 = parse__(); + if (r6 !== null) { + r7 = parse_tripleClose(); if (r7 !== null) { r0 = [r3, r4, r5, r6, r7]; } else { @@ -3701,7 +4078,433 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(m) { m.forced = true; return m; })(r5); + r0 = (function(m) { m.escaped = false; return m; })(r5); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_preMustacheText() { + var r0, r1, r2; + + r1 = pos; + if (/^[^{\uEFFF]/.test(input.charAt(pos))) { + r2 = input.charAt(pos); + pos++; + } else { + r2 = null; + if (reportFailures === 0) { + matchFailed("[^{\\uEFFF]"); + } + } + if (r2 !== null) { + r0 = []; + while (r2 !== null) { + r0.push(r2); + if (/^[^{\uEFFF]/.test(input.charAt(pos))) { + r2 = input.charAt(pos); + pos++; + } else { + r2 = null; + if (reportFailures === 0) { + matchFailed("[^{\\uEFFF]"); + } + } + } + } else { + r0 = null; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(a) { return new Handlebars.AST.ContentNode(a.join('')); })(r0); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_inTagMustache() { + var r0; + + r0 = parse_rawMustacheSingle(); + if (r0 === null) { + r0 = parse_rawMustacheUnescaped(); + if (r0 === null) { + r0 = parse_rawMustacheEscaped(); + } + } + return r0; + } + + function parse_singleOpen() { + var r0; + + if (input.charCodeAt(pos) === 123) { + r0 = "{"; + pos++; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"{\""); + } + } + return r0; + } + + function parse_doubleOpen() { + var r0; + + if (input.substr(pos, 2) === "{{") { + r0 = "{{"; + pos += 2; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"{{\""); + } + } + return r0; + } + + function parse_tripleOpen() { + var r0; + + if (input.substr(pos, 3) === "{{{") { + r0 = "{{{"; + pos += 3; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"{{{\""); + } + } + return r0; + } + + function parse_singleClose() { + var r0; + + if (input.charCodeAt(pos) === 125) { + r0 = "}"; + pos++; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"}\""); + } + } + return r0; + } + + function parse_doubleClose() { + var r0; + + if (input.substr(pos, 2) === "}}") { + r0 = "}}"; + pos += 2; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"}}\""); + } + } + return r0; + } + + function parse_tripleClose() { + var r0; + + if (input.substr(pos, 3) === "}}}") { + r0 = "}}}"; + pos += 3; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"}}}\""); + } + } + return r0; + } + + function parse_equalSign() { + var r0, r1, r2, r3, r4; + + r1 = pos; + r2 = pos; + if (input.substr(pos, 2) === "==") { + r3 = "=="; + pos += 2; + } else { + r3 = null; + if (reportFailures === 0) { + matchFailed("\"==\""); + } + } + if (r3 !== null) { + if (input.charCodeAt(pos) === 32) { + r4 = " "; + pos++; + } else { + r4 = null; + if (reportFailures === 0) { + matchFailed("\" \""); + } + } + r4 = r4 !== null ? r4 : ""; + if (r4 !== null) { + r0 = [r3, r4]; + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function() { return false; })(); + } + if (r0 === null) { + pos = r1; + } + if (r0 === null) { + r1 = pos; + r2 = pos; + if (input.charCodeAt(pos) === 61) { + r3 = "="; + pos++; + } else { + r3 = null; + if (reportFailures === 0) { + matchFailed("\"=\""); + } + } + if (r3 !== null) { + if (input.charCodeAt(pos) === 32) { + r4 = " "; + pos++; + } else { + r4 = null; + if (reportFailures === 0) { + matchFailed("\" \""); + } + } + r4 = r4 !== null ? r4 : ""; + if (r4 !== null) { + r0 = [r3, r4]; + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function() { return true; })(); + } + if (r0 === null) { + pos = r1; + } + } + return r0; + } + + function parse_htmlTagAndOptionalAttributes() { + var r0, r1, r2, r3, r4, r5, r6, r7, r8; + + r1 = pos; + r2 = pos; + r3 = pos; + r4 = parse_htmlTagName(); + if (r4 !== null) { + r5 = parse_shorthandAttributes(); + r5 = r5 !== null ? r5 : ""; + if (r5 !== null) { + r6 = []; + r7 = parse_inTagMustache(); + while (r7 !== null) { + r6.push(r7); + r7 = parse_inTagMustache(); + } + if (r6 !== null) { + r7 = []; + r8 = parse_fullAttribute(); + while (r8 !== null) { + r7.push(r8); + r8 = parse_fullAttribute(); + } + if (r7 !== null) { + r0 = [r4, r5, r6, r7]; + } else { + r0 = null; + pos = r3; + } + } else { + r0 = null; + pos = r3; + } + } else { + r0 = null; + pos = r3; + } + } else { + r0 = null; + pos = r3; + } + if (r0 !== null) { + reportedPos = r2; + r0 = (function(h, s, m, f) { return [h, s, m, f]; })(r4, r5, r6, r7); + } + if (r0 === null) { + pos = r2; + } + if (r0 === null) { + r2 = pos; + r3 = pos; + r4 = parse_shorthandAttributes(); + if (r4 !== null) { + r5 = []; + r6 = parse_inTagMustache(); + while (r6 !== null) { + r5.push(r6); + r6 = parse_inTagMustache(); + } + if (r5 !== null) { + r6 = []; + r7 = parse_fullAttribute(); + while (r7 !== null) { + r6.push(r7); + r7 = parse_fullAttribute(); + } + if (r6 !== null) { + r0 = [r4, r5, r6]; + } else { + r0 = null; + pos = r3; + } + } else { + r0 = null; + pos = r3; + } + } else { + r0 = null; + pos = r3; + } + if (r0 !== null) { + reportedPos = r2; + r0 = (function(s, m, f) { return [null, s, m, f] })(r4, r5, r6); + } + if (r0 === null) { + pos = r2; + } + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(h) { + var tagName = h[0] || 'div', + shorthandAttributes = h[1] || [], + inTagMustaches = h[2], + fullAttributes = h[3], + id = shorthandAttributes[0], + classes = shorthandAttributes[1]; + + var tagOpenContent = []; + tagOpenContent.push(new Handlebars.AST.ContentNode('<' + tagName)); + + if(id) { + tagOpenContent.push(new Handlebars.AST.ContentNode(' id="' + id + '"')); + } + + if(classes && classes.length) { + tagOpenContent.push(new Handlebars.AST.ContentNode(' class="' + classes.join(' ') + '"')); + } + + // Pad in tag mustaches with spaces. + for(var i = 0; i < inTagMustaches.length; ++i) { + tagOpenContent.push(new Handlebars.AST.ContentNode(' ')); + tagOpenContent.push(inTagMustaches[i]); + } + + for(var i = 0; i < fullAttributes.length; ++i) { + tagOpenContent = tagOpenContent.concat(fullAttributes[i]); + } + tagOpenContent.push(new Handlebars.AST.ContentNode('>')); + + return [tagOpenContent, new Handlebars.AST.ContentNode('')]; + })(r0); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_shorthandAttributes() { + var r0; + + r0 = parse_attributesAtLeastID(); + if (r0 === null) { + r0 = parse_attributesAtLeastClass(); + } + return r0; + } + + function parse_attributesAtLeastID() { + var r0, r1, r2, r3, r4, r5; + + r1 = pos; + r2 = pos; + r3 = parse_idShorthand(); + if (r3 !== null) { + r4 = []; + r5 = parse_classShorthand(); + while (r5 !== null) { + r4.push(r5); + r5 = parse_classShorthand(); + } + if (r4 !== null) { + r0 = [r3, r4]; + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(id, classes) { return [id, classes]; })(r3, r4); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_attributesAtLeastClass() { + var r0, r1, r2; + + r1 = pos; + r2 = parse_classShorthand(); + if (r2 !== null) { + r0 = []; + while (r2 !== null) { + r0.push(r2); + r2 = parse_classShorthand(); + } + } else { + r0 = null; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(classes) { return [null, classes]; })(r0); } if (r0 === null) { pos = r1; @@ -3709,50 +4512,47 @@ Emblem.Parser = (function(){ return r0; } - function parse_rawMustacheEscaped() { - var r0, r1, r2, r3, r4, r5, r6, r7; + function parse_fullAttribute() { + var r0, r1, r2, r3, r4; r1 = pos; r2 = pos; - if (input.substr(pos, 3) === "{{{") { - r3 = "{{{"; - pos += 3; + if (input.charCodeAt(pos) === 32) { + r4 = " "; + pos++; } else { - r3 = null; + r4 = null; if (reportFailures === 0) { - matchFailed("\"{{{\""); + matchFailed("\" \""); } } - if (r3 !== null) { - r4 = parse__(); - if (r4 !== null) { - r5 = parse_mustacheContent(); - if (r5 !== null) { - r6 = parse__(); - if (r6 !== null) { - if (input.substr(pos, 3) === "}}}") { - r7 = "}}}"; - pos += 3; - } else { - r7 = null; - if (reportFailures === 0) { - matchFailed("\"}}}\""); - } - } - if (r7 !== null) { - r0 = [r3, r4, r5, r6, r7]; - } else { - r0 = null; - pos = r2; - } - } else { - r0 = null; - pos = r2; - } + if (r4 !== null) { + r3 = []; + while (r4 !== null) { + r3.push(r4); + if (input.charCodeAt(pos) === 32) { + r4 = " "; + pos++; } else { - r0 = null; - pos = r2; + r4 = null; + if (reportFailures === 0) { + matchFailed("\" \""); + } + } + } + } else { + r3 = null; + } + if (r3 !== null) { + r4 = parse_actionAttribute(); + if (r4 === null) { + r4 = parse_boundAttribute(); + if (r4 === null) { + r4 = parse_normalAttribute(); } + } + if (r4 !== null) { + r0 = [r3, r4]; } else { r0 = null; pos = r2; @@ -3763,7 +4563,9 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(m) { m.forced = true; m.escaped = true; return m; })(r5); + r0 = (function(a) { + return [new Handlebars.AST.ContentNode(' '), a]; + })(r4); } if (r0 === null) { pos = r1; @@ -3771,30 +4573,30 @@ Emblem.Parser = (function(){ return r0; } - function parse_preMustacheText() { + function parse_boundAttributeValueText() { var r0, r1, r2; r1 = pos; - if (/^[^{\uEFFF]/.test(input.charAt(pos))) { + if (/^[A-Za-z.:0-9]/.test(input.charAt(pos))) { r2 = input.charAt(pos); pos++; } else { r2 = null; if (reportFailures === 0) { - matchFailed("[^{\\uEFFF]"); + matchFailed("[A-Za-z.:0-9]"); } } if (r2 !== null) { r0 = []; while (r2 !== null) { r0.push(r2); - if (/^[^{\uEFFF]/.test(input.charAt(pos))) { + if (/^[A-Za-z.:0-9]/.test(input.charAt(pos))) { r2 = input.charAt(pos); pos++; } else { r2 = null; if (reportFailures === 0) { - matchFailed("[^{\\uEFFF]"); + matchFailed("[A-Za-z.:0-9]"); } } } @@ -3803,7 +4605,7 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(a) { return a.join(''); })(r0); + r0 = (function(s) { return s.join(''); })(r0); } if (r0 === null) { pos = r1; @@ -3811,24 +4613,56 @@ Emblem.Parser = (function(){ return r0; } - function parse_equalSign() { - var r0, r1, r2, r3, r4; + function parse_actionValue() { + var r0, r1; + + r0 = parse_quotedActionValue(); + if (r0 === null) { + r1 = pos; + r0 = parse_pathIdNode(); + if (r0 !== null) { + reportedPos = r1; + r0 = (function(id) { return new Handlebars.AST.MustacheNode([id]); })(r0); + } + if (r0 === null) { + pos = r1; + } + } + return r0; + } + + function parse_quotedActionValue() { + var r0, r1, r2, r3, r4, r5; r1 = pos; r2 = pos; - if (input.substr(pos, 2) === "==") { - r3 = "=="; - pos += 2; + if (input.charCodeAt(pos) === 34) { + r3 = "\""; + pos++; } else { r3 = null; if (reportFailures === 0) { - matchFailed("\"==\""); + matchFailed("\"\\\"\""); } } if (r3 !== null) { - r4 = parse__(); + r4 = parse_inMustache(); if (r4 !== null) { - r0 = [r3, r4]; + if (input.charCodeAt(pos) === 34) { + r5 = "\""; + pos++; + } else { + r5 = null; + if (reportFailures === 0) { + matchFailed("\"\\\"\""); + } + } + if (r5 !== null) { + r0 = [r3, r4, r5]; + } else { + r0 = null; + pos = r2; + } } else { r0 = null; pos = r2; @@ -3837,29 +4671,35 @@ Emblem.Parser = (function(){ r0 = null; pos = r2; } - if (r0 !== null) { - reportedPos = r1; - r0 = (function() { return true; })(); - } if (r0 === null) { - pos = r1; - } - if (r0 === null) { - r1 = pos; r2 = pos; - if (input.charCodeAt(pos) === 61) { - r3 = "="; + if (input.charCodeAt(pos) === 39) { + r3 = "'"; pos++; } else { r3 = null; if (reportFailures === 0) { - matchFailed("\"=\""); + matchFailed("\"'\""); } } if (r3 !== null) { - r4 = parse__(); + r4 = parse_inMustache(); if (r4 !== null) { - r0 = [r3, r4]; + if (input.charCodeAt(pos) === 39) { + r5 = "'"; + pos++; + } else { + r5 = null; + if (reportFailures === 0) { + matchFailed("\"'\""); + } + } + if (r5 !== null) { + r0 = [r3, r4, r5]; + } else { + r0 = null; + pos = r2; + } } else { r0 = null; pos = r2; @@ -3868,28 +4708,41 @@ Emblem.Parser = (function(){ r0 = null; pos = r2; } - if (r0 !== null) { - reportedPos = r1; - r0 = (function() { return false; })(); - } - if (r0 === null) { - pos = r1; - } + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(p) { return p[1]; })(r0); + } + if (r0 === null) { + pos = r1; } return r0; } - function parse_htmlTag() { - var r0, r1, r2, r3, r4; + function parse_actionAttribute() { + var r0, r1, r2, r3, r4, r5; r1 = pos; r2 = pos; - r3 = parse_htmlTagName(); + r3 = parse_knownEvent(); if (r3 !== null) { - r4 = parse_attrShortcuts(); - r4 = r4 !== null ? r4 : ""; + if (input.charCodeAt(pos) === 61) { + r4 = "="; + pos++; + } else { + r4 = null; + if (reportFailures === 0) { + matchFailed("\"=\""); + } + } if (r4 !== null) { - r0 = [r3, r4]; + r5 = parse_actionValue(); + if (r5 !== null) { + r0 = [r3, r4, r5]; + } else { + r0 = null; + pos = r2; + } } else { r0 = null; pos = r2; @@ -3900,40 +4753,88 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(h, t) { return { type: 'html', tagName: h, attrs:(t||{}) }; })(r3, r4); + r0 = (function(event, mustacheNode) { + // Unshift the action helper and augment the hash + return unshiftParam(mustacheNode, 'action', [['on', new Handlebars.AST.StringNode(event)]]); + })(r3, r5); } if (r0 === null) { pos = r1; } - if (r0 === null) { - r1 = pos; - r0 = parse_attrShortcuts(); - if (r0 !== null) { - reportedPos = r1; - r0 = (function(t) { return { type: 'html', tagName: null, attrs: t }; })(r0); + return r0; + } + + function parse_boundAttribute() { + var r0, r1, r2, r3, r4, r5; + + r1 = pos; + r2 = pos; + r3 = parse_ident(); + if (r3 !== null) { + if (input.charCodeAt(pos) === 61) { + r4 = "="; + pos++; + } else { + r4 = null; + if (reportFailures === 0) { + matchFailed("\"=\""); + } } - if (r0 === null) { - pos = r1; + if (r4 !== null) { + r5 = parse_boundAttributeValueText(); + if (r5 !== null) { + r0 = [r3, r4, r5]; + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; } + } else { + r0 = null; + pos = r2; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(key, value) { + var hashNode = new Handlebars.AST.HashNode([[key, new Handlebars.AST.StringNode(value)]]); + var params = [new Handlebars.AST.IdNode(['bindAttr'])]; + + return new Handlebars.AST.MustacheNode(params, hashNode); + })(r3, r5); + } + if (r0 === null) { + pos = r1; } return r0; } - function parse_attrShortcuts() { + function parse_normalAttribute() { var r0, r1, r2, r3, r4, r5; r1 = pos; r2 = pos; - r3 = parse_idShortcut(); + r3 = parse_ident(); if (r3 !== null) { - r4 = []; - r5 = parse_classShortcut(); - while (r5 !== null) { - r4.push(r5); - r5 = parse_classShortcut(); + if (input.charCodeAt(pos) === 61) { + r4 = "="; + pos++; + } else { + r4 = null; + if (reportFailures === 0) { + matchFailed("\"=\""); + } } if (r4 !== null) { - r0 = [r3, r4]; + r5 = parse_string(); + if (r5 !== null) { + r0 = [r3, r4, r5]; + } else { + r0 = null; + pos = r2; + } } else { r0 = null; pos = r2; @@ -3944,45 +4845,88 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(id, classes) { - var ret = { id: id }; - var classString = classes.join(' '); - if(classString) { - ret['class'] = classString; - } - return ret; - })(r3, r4); + r0 = (function(key, value) { + var s = key + '=' + '"' + value + '"'; + return new Handlebars.AST.ContentNode(s); + })(r3, r5); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_attributeName() { + var r0, r1, r2; + + r1 = pos; + r0 = []; + r2 = parse_attributeChar(); + while (r2 !== null) { + r0.push(r2); + r2 = parse_attributeChar(); + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(a) { return a.join(''); })(r0); } if (r0 === null) { pos = r1; } + return r0; + } + + function parse_attributeValue() { + var r0; + + r0 = parse_string(); if (r0 === null) { - r1 = pos; - r2 = parse_classShortcut(); - if (r2 !== null) { - r0 = []; - while (r2 !== null) { - r0.push(r2); - r2 = parse_classShortcut(); - } + r0 = parse_param(); + } + return r0; + } + + function parse_attributeChar() { + var r0; + + r0 = parse_alpha(); + if (r0 === null) { + if (/^[0-9]/.test(input.charAt(pos))) { + r0 = input.charAt(pos); + pos++; } else { r0 = null; - } - if (r0 !== null) { - reportedPos = r1; - r0 = (function(classes) { - - return { 'class': classes.join(' ') }; - })(r0); + if (reportFailures === 0) { + matchFailed("[0-9]"); + } } if (r0 === null) { - pos = r1; + if (input.charCodeAt(pos) === 95) { + r0 = "_"; + pos++; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"_\""); + } + } + if (r0 === null) { + if (input.charCodeAt(pos) === 45) { + r0 = "-"; + pos++; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"-\""); + } + } + } } } return r0; } - function parse_idShortcut() { + function parse_idShorthand() { var r0, r1, r2, r3, r4; r1 = pos; @@ -4018,7 +4962,7 @@ Emblem.Parser = (function(){ return r0; } - function parse_classShortcut() { + function parse_classShorthand() { var r0, r1, r2, r3, r4; r1 = pos; @@ -5588,6 +6532,312 @@ Emblem.Parser = (function(){ return r0; } + function parse_knownEvent() { + var r0; + + reportFailures++; + if (input.substr(pos, 10) === "touchStart") { + r0 = "touchStart"; + pos += 10; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"touchStart\""); + } + } + if (r0 === null) { + if (input.substr(pos, 9) === "touchMove") { + r0 = "touchMove"; + pos += 9; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"touchMove\""); + } + } + if (r0 === null) { + if (input.substr(pos, 8) === "touchEnd") { + r0 = "touchEnd"; + pos += 8; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"touchEnd\""); + } + } + if (r0 === null) { + if (input.substr(pos, 11) === "touchCancel") { + r0 = "touchCancel"; + pos += 11; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"touchCancel\""); + } + } + if (r0 === null) { + if (input.substr(pos, 7) === "keyDown") { + r0 = "keyDown"; + pos += 7; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"keyDown\""); + } + } + if (r0 === null) { + if (input.substr(pos, 5) === "keyUp") { + r0 = "keyUp"; + pos += 5; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"keyUp\""); + } + } + if (r0 === null) { + if (input.substr(pos, 8) === "keyPress") { + r0 = "keyPress"; + pos += 8; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"keyPress\""); + } + } + if (r0 === null) { + if (input.substr(pos, 9) === "mouseDown") { + r0 = "mouseDown"; + pos += 9; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"mouseDown\""); + } + } + if (r0 === null) { + if (input.substr(pos, 7) === "mouseUp") { + r0 = "mouseUp"; + pos += 7; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"mouseUp\""); + } + } + if (r0 === null) { + if (input.substr(pos, 11) === "contextMenu") { + r0 = "contextMenu"; + pos += 11; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"contextMenu\""); + } + } + if (r0 === null) { + if (input.substr(pos, 5) === "click") { + r0 = "click"; + pos += 5; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"click\""); + } + } + if (r0 === null) { + if (input.substr(pos, 11) === "doubleClick") { + r0 = "doubleClick"; + pos += 11; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"doubleClick\""); + } + } + if (r0 === null) { + if (input.substr(pos, 9) === "mouseMove") { + r0 = "mouseMove"; + pos += 9; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"mouseMove\""); + } + } + if (r0 === null) { + if (input.substr(pos, 7) === "focusIn") { + r0 = "focusIn"; + pos += 7; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"focusIn\""); + } + } + if (r0 === null) { + if (input.substr(pos, 8) === "focusOut") { + r0 = "focusOut"; + pos += 8; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"focusOut\""); + } + } + if (r0 === null) { + if (input.substr(pos, 10) === "mouseEnter") { + r0 = "mouseEnter"; + pos += 10; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"mouseEnter\""); + } + } + if (r0 === null) { + if (input.substr(pos, 10) === "mouseLeave") { + r0 = "mouseLeave"; + pos += 10; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"mouseLeave\""); + } + } + if (r0 === null) { + if (input.substr(pos, 6) === "submit") { + r0 = "submit"; + pos += 6; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"submit\""); + } + } + if (r0 === null) { + if (input.substr(pos, 5) === "input") { + r0 = "input"; + pos += 5; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"input\""); + } + } + if (r0 === null) { + if (input.substr(pos, 6) === "change") { + r0 = "change"; + pos += 6; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"change\""); + } + } + if (r0 === null) { + if (input.substr(pos, 9) === "dragStart") { + r0 = "dragStart"; + pos += 9; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"dragStart\""); + } + } + if (r0 === null) { + if (input.substr(pos, 4) === "drag") { + r0 = "drag"; + pos += 4; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"drag\""); + } + } + if (r0 === null) { + if (input.substr(pos, 9) === "dragEnter") { + r0 = "dragEnter"; + pos += 9; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"dragEnter\""); + } + } + if (r0 === null) { + if (input.substr(pos, 9) === "dragLeave") { + r0 = "dragLeave"; + pos += 9; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"dragLeave\""); + } + } + if (r0 === null) { + if (input.substr(pos, 8) === "dragOver") { + r0 = "dragOver"; + pos += 8; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"dragOver\""); + } + } + if (r0 === null) { + if (input.substr(pos, 4) === "drop") { + r0 = "drop"; + pos += 4; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"drop\""); + } + } + if (r0 === null) { + if (input.substr(pos, 7) === "dragEnd") { + r0 = "dragEnd"; + pos += 7; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"dragEnd\""); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + reportFailures--; + if (reportFailures === 0 && r0 === null) { + matchFailed("a JS event"); + } + return r0; + } + function parse_INDENT() { var r0, r1; @@ -5777,6 +7027,26 @@ Emblem.Parser = (function(){ } + // Returns a new MustacheNode with a new preceding param (id). + function unshiftParam(mustacheNode, helperName, newHashPairs) { + + var hash = mustacheNode.hash; + + // Merge hash. + if(newHashPairs) { + hash = hash || new Handlebars.AST.HashNode([]); + + for(var i = 0; i < newHashPairs.length; ++i) { + hash.pairs.push(newHashPairs[i]); + } + } + + var params = [mustacheNode.id].concat(mustacheNode.params); + params.unshift(new Handlebars.AST.IdNode([helperName])); + return new Handlebars.AST.MustacheNode(params, hash, !mustacheNode.escaped); + } + + var result = parseFunctions[startRule](); /* @@ -5862,7 +7132,6 @@ Emblem.Parser = (function(){ // exports = Emblem.Parser; ; // lib/compiler.js -// Generated by CoffeeScript 1.4.0 var Emblem, Handlebars, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; @@ -5870,6 +7139,12 @@ var Emblem, Handlebars, //  +Emblem.parse = function(string) { + var processed; + processed = Emblem.Preprocessor.processSync(string); + return new Handlebars.AST.ProgramNode(Emblem.Parser.parse(processed), []); +}; + Emblem.precompileRaw = function(string, options) { var ast, environment; if (options == null) { @@ -5949,7 +7224,6 @@ Emblem.compileEmber = function(string) { }; ; // lib/preprocessor.js -// Generated by CoffeeScript 1.4.0 var Emblem, Preprocessor, StringScanner; //  @@ -6171,125 +7445,7 @@ Emblem.Preprocessor = Preprocessor = (function() { })(); ; -// lib/translation.js -// Generated by CoffeeScript 1.4.0 -var ContentStack, Emblem, Handlebars, processNodes, - __hasProp = {}.hasOwnProperty; - -//  - -//  - -ContentStack = (function() { - - function ContentStack() { - this.current = ""; - } - - ContentStack.prototype.append = function(s) { - return this.current += s; - }; - - ContentStack.prototype.flatten = function() { - var ret; - ret = this.current; - this.current = ""; - return ret; - }; - - return ContentStack; - -})(); - -processNodes = function(nodes, stack, statements) { - var attributesString, c, classNames, classes, closeId, firstChar, hash, helper, id, ids, k, name, node, openStache, pairs, param, params, result, substatements, tagName, v, value, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2; - if (statements == null) { - statements = []; - } - for (_i = 0, _len = nodes.length; _i < _len; _i++) { - node = nodes[_i]; - if (node.type === 'html') { - tagName = node.tagName || 'div'; - classes = node.attrs.classes || []; - classNames = classes.join(' '); - attributesString = ""; - _ref = node.attrs || {}; - for (name in _ref) { - if (!__hasProp.call(_ref, name)) continue; - value = _ref[name]; - attributesString += ' ' + name + '=' + '"' + value + '"'; - } - stack.append("<" + tagName + attributesString + ">"); - processNodes(node.nodes || [], stack, statements); - stack.append(""); - } else if (node.type === 'mustache') { - c = stack.flatten(); - if (c) { - statements.push(new Handlebars.AST.ContentNode(c)); - } - firstChar = node.params[0].charAt(0); - if (!node.forced && firstChar === firstChar.toUpperCase()) { - helper = "view"; - node.params.unshift(helper); - } - params = []; - _ref1 = node.params; - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - param = _ref1[_j]; - ids = param.split('.'); - result = []; - for (_k = 0, _len2 = ids.length; _k < _len2; _k++) { - id = ids[_k]; - result.push(id); - result.push('.'); - } - result.pop(); - params.push(new Handlebars.AST.IdNode(result)); - } - pairs = []; - _ref2 = node.hash; - for (k in _ref2) { - if (!__hasProp.call(_ref2, k)) continue; - v = _ref2[k]; - pairs.push([k, v]); - } - hash = null; - if (pairs.length) { - hash = new Handlebars.AST.HashNode(pairs); - } - if (node.nodes && node.nodes.length) { - closeId = params[0]; - substatements = processNodes(node.nodes, new ContentStack); - statements.push(new Handlebars.AST.ProgramNode(substatements, [])); - openStache = new Handlebars.AST.MustacheNode(params, hash, node.escaped); - statements.push(new Handlebars.AST.BlockNode(openStache, statements, [], closeId)); - } else { - statements.push(new Handlebars.AST.MustacheNode(params, hash, node.escaped)); - } - } else if (node instanceof Array) { - processNodes(node, stack, statements); - } else { - stack.append(node.toString()); - } - } - return statements; -}; - -Emblem.parse = function(string) { - var c, emblemAST, processed, stack, statements; - stack = new ContentStack; - processed = Emblem.Preprocessor.processSync(string); - emblemAST = Emblem.Parser.parse(processed); - statements = processNodes(emblemAST, stack); - c = stack.flatten(); - if (c) { - statements.push(new Handlebars.AST.ContentNode(c)); - } - return new Handlebars.AST.ProgramNode(statements, []); -}; -; // lib/emberties.js -// Generated by CoffeeScript 1.4.0 var ENV, Emblem, _base; //  diff --git a/dist/emblem.min.js b/dist/emblem.min.js index 48330a6..7386c80 100644 --- a/dist/emblem.min.js +++ b/dist/emblem.min.js @@ -1,3 +1,3 @@ this.StringScanner=function(){var e;return e=function(){function e(e){this.str=e!=null?e:"",this.str=""+this.str,this.pos=0,this.lastMatch={reset:function(){return this.str=null,this.captures=[],this}}.reset(),this}return e.prototype.bol=function(){return this.pos<=0||this.str[this.pos-1]==="\n"},e.prototype.captures=function(){return this.lastMatch.captures},e.prototype.check=function(e){var t;return this.str.substr(this.pos).search(e)!==0?(this.lastMatch.reset(),null):(t=this.str.substr(this.pos).match(e),this.lastMatch.str=t[0],this.lastMatch.captures=t.slice(1),this.lastMatch.str)},e.prototype.checkUntil=function(e){var t,n;return n=this.str.substr(this.pos).search(e),n<0?(this.lastMatch.reset(),null):(t=this.str.substr(this.pos+n).match(e),this.lastMatch.captures=t.slice(1),this.lastMatch.str=this.str.substr(this.pos,n)+t[0])},e.prototype.clone=function(){var e,t,n,r;e=new this.constructor(this.str),e.pos=this.pos,e.lastMatch={},r=this.lastMatch;for(t in r)n=r[t],e.lastMatch[t]=n;return e},e.prototype.concat=function(e){return this.str+=e,this},e.prototype.eos=function(){return this.pos===this.str.length},e.prototype.exists=function(e){var t,n;return n=this.str.substr(this.pos).search(e),n<0?(this.lastMatch.reset(),null):(t=this.str.substr(this.pos+n).match(e),this.lastMatch.str=t[0],this.lastMatch.captures=t.slice(1),n)},e.prototype.getch=function(){return this.scan(/./)},e.prototype.match=function(){return this.lastMatch.str},e.prototype.matches=function(e){return this.check(e),this.matchSize()},e.prototype.matched=function(){return this.lastMatch.str!=null},e.prototype.matchSize=function(){return this.matched()?this.match().length:null},e.prototype.peek=function(e){return this.str.substr(this.pos,e)},e.prototype.pointer=function(){return this.pos},e.prototype.setPointer=function(e){return e=+e,e<0&&(e=0),e>this.str.length&&(e=this.str.length),this.pos=e},e.prototype.reset=function(){return this.lastMatch.reset(),this.pos=0,this},e.prototype.rest=function(){return this.str.substr(this.pos)},e.prototype.scan=function(e){var t;return t=this.check(e),t!=null&&(this.pos+=t.length),t},e.prototype.scanUntil=function(e){var t;return t=this.checkUntil(e),t!=null&&(this.pos+=t.length),t},e.prototype.skip=function(e){return this.scan(e),this.matchSize()},e.prototype.skipUntil=function(e){return this.scanUntil(e),this.matchSize()},e.prototype.string=function(){return this.str},e.prototype.terminate=function(){return this.pos=this.str.length,this.lastMatch.reset(),this},e.prototype.toString=function(){return"#8?""+this.str.substr(0,5)+"...":this.str))+">"},e}(),e.prototype.beginningOfLine=e.prototype.bol,e.prototype.clear=e.prototype.terminate,e.prototype.dup=e.prototype.clone,e.prototype.endOfString=e.prototype.eos,e.prototype.exist=e.prototype.exists,e.prototype.getChar=e.prototype.getch,e.prototype.position=e.prototype.pointer,e.StringScanner=e,e}.call(this),this.Handlebars={},function(e){e.VERSION="1.0.rc.2",e.helpers={},e.partials={},e.registerHelper=function(e,t,n){n&&(t.not=n),this.helpers[e]=t},e.registerPartial=function(e,t){this.partials[e]=t},e.registerHelper("helperMissing",function(e){if(arguments.length===2)return undefined;throw new Error("Could not find property '"+e+"'")});var t=Object.prototype.toString,n="[object Function]";e.registerHelper("blockHelperMissing",function(r,i){var s=i.inverse||function(){},o=i.fn,u="",a=t.call(r);return a===n&&(r=r.call(this)),r===!0?o(this):r===!1||r==null?s(this):a==="[object Array]"?r.length>0?e.helpers.each(r,i):s(this):o(r)}),e.K=function(){},e.createFrame=Object.create||function(t){e.K.prototype=t;var n=new e.K;return e.K.prototype=null,n},e.logger={DEBUG:0,INFO:1,WARN:2,ERROR:3,level:3,methodMap:{0:"debug",1:"info",2:"warn",3:"error"},log:function(t,n){if(e.logger.level<=t){var r=e.logger.methodMap[t];typeof console!="undefined"&&console[r]&&console[r].call(console,n)}}},e.log=function(t,n){e.logger.log(t,n)},e.registerHelper("each",function(t,n){var r=n.fn,i=n.inverse,s=0,o="",u;n.data&&(u=e.createFrame(n.data));if(t&&typeof t=="object")if(t instanceof Array)for(var a=t.length;s2&&k.push("'"+this.terminals_[T]+"'");this.lexer.showPosition?L="Parse error on line "+(a+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+k.join(", ")+", got '"+(this.terminals_[g]||g)+"'":L="Parse error on line "+(a+1)+": Unexpected "+(g==1?"end of input":"'"+(this.terminals_[g]||g)+"'"),this.parseError(L,{text:this.lexer.match,token:this.terminals_[g]||g,line:this.lexer.yylineno,loc:p,expected:k})}}if(w[0]instanceof Array&&w.length>1)throw new Error("Parse Error: multiple actions possible at state: "+b+", token: "+g);switch(w[0]){case 1:r.push(g),i.push(this.lexer.yytext),s.push(this.lexer.yylloc),r.push(w[1]),g=null,y?(g=y,y=null):(f=this.lexer.yyleng,u=this.lexer.yytext,a=this.lexer.yylineno,p=this.lexer.yylloc,l>0&&l--);break;case 2:N=this.productions_[w[1]][1],x.$=i[i.length-N],x._$={first_line:s[s.length-(N||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(N||1)].first_column,last_column:s[s.length-1].last_column},d&&(x._$.range=[s[s.length-(N||1)].range[0],s[s.length-1].range[1]]),S=this.performAction.call(x,u,f,a,this.yy,w[1],i,s);if(typeof S!="undefined")return S;N&&(r=r.slice(0,-1*N*2),i=i.slice(0,-1*N),s=s.slice(0,-1*N)),r.push(this.productions_[w[1]][0]),i.push(x.$),s.push(x._$),C=o[r[r.length-2]][r[r.length-1]],r.push(C);break;case 3:return!0}}return!0}},t=function(){var e={EOF:1,parseError:function(t,n){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,n)},setInput:function(e){return this._input=e,this._more=this._less=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var e=this._input[0];this.yytext+=e,this.yyleng++,this.offset++,this.match+=e,this.matched+=e;var t=e.match(/(?:\r\n?|\n).*/g);return t?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),e},unput:function(e){var t=e.length,n=e.split(/(?:\r\n?|\n)/g);this._input=e+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-t-1),this.offset-=t;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-t},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-t]),this},more:function(){return this._more=!0,this},less:function(e){this.unput(this.match.slice(e))},pastInput:function(){var e=this.matched.substr(0,this.matched.length-this.match.length);return(e.length>20?"...":"")+e.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var e=this.match;return e.length<20&&(e+=this._input.substr(0,20-e.length)),(e.substr(0,20)+(e.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var e=this.pastInput(),t=(new Array(e.length+1)).join("-");return e+this.upcomingInput()+"\n"+t+"^"},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var e,t,n,r,i,s;this._more||(this.yytext="",this.match="");var o=this._currentRules();for(var u=0;ut[0].length)){t=n,r=u;if(!this.options.flex)break}}if(t){s=t[0].match(/(?:\r\n?|\n).*/g),s&&(this.yylineno+=s.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:s?s[s.length-1].length-s[s.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,o[r],this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1);if(e)return e;return}return this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return typeof t!="undefined"?t:this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.pop()},_currentRules:function(){return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules},topState:function(){return this.conditionStack[this.conditionStack.length-2]},pushState:function(t){this.begin(t)}};return e.options={},e.performAction=function(t,n,r,i){var s=i;switch(r){case 0:n.yytext.slice(-1)!=="\\"&&this.begin("mu"),n.yytext.slice(-1)==="\\"&&(n.yytext=n.yytext.substr(0,n.yyleng-1),this.begin("emu"));if(n.yytext)return 14;break;case 1:return 14;case 2:return n.yytext.slice(-1)!=="\\"&&this.popState(),n.yytext.slice(-1)==="\\"&&(n.yytext=n.yytext.substr(0,n.yyleng-1)),14;case 3:return n.yytext=n.yytext.substr(0,n.yyleng-4),this.popState(),15;case 4:return this.begin("par"),24;case 5:return 16;case 6:return 20;case 7:return 19;case 8:return 19;case 9:return 23;case 10:return 23;case 11:this.popState(),this.begin("com");break;case 12:return n.yytext=n.yytext.substr(3,n.yyleng-5),this.popState(),15;case 13:return 22;case 14:return 36;case 15:return 35;case 16:return 35;case 17:return 39;case 18:break;case 19:return this.popState(),18;case 20:return this.popState(),18;case 21:return n.yytext=n.yytext.substr(1,n.yyleng-2).replace(/\\"/g,'"'),30;case 22:return n.yytext=n.yytext.substr(1,n.yyleng-2).replace(/\\'/g,"'"),30;case 23:return n.yytext=n.yytext.substr(1),28;case 24:return 32;case 25:return 32;case 26:return 31;case 27:return 35;case 28:return n.yytext=n.yytext.substr(1,n.yyleng-2),35;case 29:return"INVALID";case 30:break;case 31:return this.popState(),37;case 32:return 5}},e.rules=[/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\{\{>)/,/^(?:\{\{#)/,/^(?:\{\{\/)/,/^(?:\{\{\^)/,/^(?:\{\{\s*else\b)/,/^(?:\{\{\{)/,/^(?:\{\{&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{)/,/^(?:=)/,/^(?:\.(?=[} ]))/,/^(?:\.\.)/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}\}\})/,/^(?:\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@[a-zA-Z]+)/,/^(?:true(?=[}\s]))/,/^(?:false(?=[}\s]))/,/^(?:[0-9]+(?=[}\s]))/,/^(?:[a-zA-Z0-9_$-]+(?=[=}\s\/.]))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:\s+)/,/^(?:[a-zA-Z0-9_$-/]+)/,/^(?:$)/],e.conditions={mu:{rules:[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,32],inclusive:!1},emu:{rules:[2],inclusive:!1},com:{rules:[3],inclusive:!1},par:{rules:[30,31],inclusive:!1},INITIAL:{rules:[0,1,32],inclusive:!0}},e}();return e.lexer=t,n.prototype=e,e.Parser=n,new n}();Handlebars.Parser=handlebars,Handlebars.parse=function(e){return Handlebars.Parser.yy=Handlebars.AST,Handlebars.Parser.parse(e)},Handlebars.print=function(e){return(new Handlebars.PrintVisitor).accept(e)},function(){Handlebars.AST={},Handlebars.AST.ProgramNode=function(e,t){this.type="program",this.statements=e,t&&(this.inverse=new Handlebars.AST.ProgramNode(t))},Handlebars.AST.MustacheNode=function(e,t,n){this.type="mustache",this.escaped=!n,this.hash=t;var r=this.id=e[0],i=this.params=e.slice(1),s=this.eligibleHelper=r.isSimple;this.isHelper=s&&(i.length||t)},Handlebars.AST.PartialNode=function(e,t){this.type="partial",this.partialName=e,this.context=t};var e=function(e,t){if(e.original!==t.original)throw new Handlebars.Exception(e.original+" doesn't match "+t.original)};Handlebars.AST.BlockNode=function(t,n,r,i){e(t.id,i),this.type="block",this.mustache=t,this.program=n,this.inverse=r,this.inverse&&!this.program&&(this.isInverse=!0)},Handlebars.AST.ContentNode=function(e){this.type="content",this.string=e},Handlebars.AST.HashNode=function(e){this.type="hash",this.pairs=e},Handlebars.AST.IdNode=function(e){this.type="ID",this.original=e.join(".");var t=[],n=0;for(var r=0,i=e.length;r":">",'"':""","'":"'","`":"`"},t=/[&<>"'`]/g,n=/[&<>"'`]/,r=function(t){return e[t]||"&"};Handlebars.Utils={escapeExpression:function(e){return e instanceof Handlebars.SafeString?e.toString():e==null||e===!1?"":n.test(e)?e.replace(t,r):e},isEmpty:function(e){return!e&&e!==0?!0:Object.prototype.toString.call(e)==="[object Array]"&&e.length===0?!0:!1}}}(),Handlebars.Compiler=function(){},Handlebars.JavaScriptCompiler=function(){},function(e,t){e.prototype={compiler:e,disassemble:function(){var e=this.opcodes,t,n=[],r,i;for(var s=0,o=e.length;sthis.stackVars.length&&this.stackVars.push("stack"+this.stackSlot),"stack"+this.stackSlot},popStack:function(){var e=this.compileStack.pop();return e instanceof n?e.value:(this.stackSlot--,e)},topStack:function(){var e=this.compileStack[this.compileStack.length-1];return e instanceof n?e.value:e},quotedString:function(e){return'"'+e.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r")+'"'},setupHelper:function(e,t){var n=[];this.setupParams(e,n);var r=this.nameLookup("helpers",t,"helper");return{params:n,name:r,callParams:["depth0"].concat(n).join(", "),helperMissingParams:["depth0",this.quotedString(t)].concat(n).join(", ")}},setupParams:function(e,t){var n=[],r=[],i=[],s,o,u;n.push("hash:"+this.popStack()),o=this.popStack(),u=this.popStack();if(u||o)u||(this.context.aliases.self="this",u="self.noop"),o||(this.context.aliases.self="this",o="self.noop"),n.push("inverse:"+o),n.push("fn:"+u);for(var a=0;ao&&(u=0,a={line:1,column:1,seenCR:!1}),t()),a}function v(){return e.substring(o,s)}function m(){return o}function g(){return d().line}function y(){return d().column}function b(e){if(sl&&(l=s,c=[]),c.push(e)}function w(){var e,t;e=[],t=E();while(t!==null)e.push(t),t=E();return e}function E(){var e;return e=T(),e===null&&(e=S(),e===null&&(e=x())),e}function S(){var e,t;return e=N(),e===null&&(e=k(),e===null&&(t=s,e=U(),e!==null&&(o=t,e=function(e){return e}(e)),e===null&&(s=t))),e}function x(){var e,t;return t=s,e=A(),e!==null&&(o=t,e=function(e){return e}(e)),e===null&&(s=t),e===null&&(e=L()),e}function T(){var t,n,r,i,u,a,l,c,h,p,d,v,m,g;n=s,r=s,e.charCodeAt(s)===47?(i="/",s++):(i=null,f===0&&b('"/"'));if(i!==null){u=lt();if(u!==null){a=ot();if(a!==null){c=s,h=it();if(h!==null){v=s,m=lt(),m!==null?(g=ot(),g!==null?d=[m,g]:(d=null,s=v)):(d=null,s=v);if(d!==null){p=[];while(d!==null)p.push(d),v=s,m=lt(),m!==null?(g=ot(),g!==null?d=[m,g]:(d=null,s=v)):(d=null,s=v)}else p=null;p!==null?(d=st(),d!==null?l=[h,p,d]:(l=null,s=c)):(l=null,s=c)}else l=null,s=c;l=l!==null?l:"",l!==null?t=[i,u,a,l]:(t=null,s=r)}else t=null,s=r}else t=null,s=r}else t=null,s=r;return t!==null&&(o=n,t=function(){return""}()),t===null&&(s=n),t}function N(){var e,t,n,r,i,u,a,f,l;return t=s,n=s,r=C(),r!==null?(u=s,a=it(),a!==null?(f=w(),f!==null?(l=st(),l!==null?i=[a,f,l]:(i=null,s=u)):(i=null,s=u)):(i=null,s=u),i=i!==null?i:"",i!==null?e=[r,i]:(e=null,s=n)):(e=null,s=n),e!==null&&(o=t,e=function(e,t){return e.nodes=t?t[1]:[],e}(r,i)),e===null&&(s=t),e}function C(){var e,t,n,r,i,u;return t=s,n=s,r=K(),r!==null?(i=at(),i!==null?(u=ot(),u!==null?e=[r,i,u]:(e=null,s=n)):(e=null,s=n)):(e=null,s=n),e!==null&&(o=t,e=function(e){return e.nodes=[],e}(r)),e===null&&(s=t),e}function k(){var e,t,n,r,i,u,a;return t=s,n=s,r=K(),r!==null?(i=ft(),i!==null?(u=R(),u!==null?(a=ot(),a!==null?e=[r,i,u,a]:(e=null,s=n)):(e=null,s=n)):(e=null,s=n)):(e=null,s=n),e!==null&&(o=t,e=function(e,t){return e.nodes=t,e}(r,u)),e===null&&(s=t),e}function L(){var e,t,n,r,i,u,a,f,l,c;return t=s,n=s,r=O(),r!==null?(i=ot(),i!==null?(a=s,f=it(),f!==null?(l=w(),l!==null?(c=st(),c!==null?u=[f,l,c]:(u=null,s=a)):(u=null,s=a)):(u=null,s=a),u=u!==null?u:"",u!==null?e=[r,i,u]:(e=null,s=n)):(e=null,s=n)):(e=null,s=n),e!==null&&(o=t,e=function(e,t){return e.nodes=t?t[1]:[],e}(r,u)),e===null&&(s=t),e}function A(){var e,t,n,r,i,u;return t=s,n=s,r=at(),r!==null?(i=J(),i!==null?(u=L(),u!==null?e=[r,i,u]:(e=null,s=n)):(e=null,s=n)):(e=null,s=n),e!==null&&(o=t,e=function(e,t){return t.forced=!0,t.escaped=e,t}(i,u)),e===null&&(s=t),e}function O(){var t,n,r,i,u,a;return n=s,r=s,u=s,f++,/^[A-Za-z]/.test(e.charAt(s))?(i=e.charAt(s),s++):(i=null,f===0&&b("[A-Za-z]")),f--,i!==null?(i="",s=u):i=null,i!==null?(u=M(),u!==null?(a=P(),a!==null?t=[i,u,a]:(t=null,s=r)):(t=null,s=r)):(t=null,s=r),t!==null&&(o=n,t=function(e,t){return{type:"mustache",params:e,hash:t}}(u,a)),t===null&&(s=n),t}function M(){var t,n,r,i,u,a,l,c,h;n=s,i=s,u=s,a=at(),a!==null?(l=_(),l!==null?(h=s,f++,e.charCodeAt(s)===61?(c="=",s++):(c=null,f===0&&b('"="')),f--,c===null?c="":(c=null,s=h),c!==null?(h=at(),h!==null?r=[a,l,c,h]:(r=null,s=u)):(r=null,s=u)):(r=null,s=u)):(r=null,s=u),r!==null&&(o=i,r=function(e){return e}(l)),r===null&&(s=i);if(r!==null){t=[];while(r!==null)t.push(r),i=s,u=s,a=at(),a!==null?(l=_(),l!==null?(h=s,f++,e.charCodeAt(s)===61?(c="=",s++):(c=null,f===0&&b('"="')),f--,c===null?c="":(c=null,s=h),c!==null?(h=at(),h!==null?r=[a,l,c,h]:(r=null,s=u)):(r=null,s=u)):(r=null,s=u)):(r=null,s=u),r!==null&&(o=i,r=function(e){return e}(l)),r===null&&(s=i)}else t=null;return t!==null&&(o=n,t=function(e){return e}(t)),t===null&&(s=n),t}function _(){var e,t,n;t=s,n=D();if(n!==null){e=[];while(n!==null)e.push(n),n=D()}else e=null;return e!==null&&(o=t,e=function(e){return e.join("")}(e)),e===null&&(s=t),e}function D(){var t;return t=q(),t===null&&(e.charCodeAt(s)===95?(t="_",s++):(t=null,f===0&&b('"_"')),t===null&&(e.charCodeAt(s)===45?(t="-",s++):(t=null,f===0&&b('"-"')),t===null&&(e.charCodeAt(s)===46?(t=".",s++):(t=null,f===0&&b('"."'))))),t}function P(){var t,n,r,i,u,a,l,c,h,p;n=s,t=[],i=s,u=s,a=at(),a!==null?(l=_(),l!==null?(e.charCodeAt(s)===61?(c="=",s++):(c=null,f===0&&b('"="')),c!==null?(h=H(),h!==null?(p=at(),p!==null?r=[a,l,c,h,p]:(r=null,s=u)):(r=null,s=u)):(r=null,s=u)):(r=null,s=u)):(r=null,s=u),r!==null&&(o=i,r=function(e,t){return{key:e,value:t}}(l,h)),r===null&&(s=i);while(r!==null)t.push(r),i=s,u=s,a=at(),a!==null?(l=_(),l!==null?(e.charCodeAt(s)===61?(c="=",s++):(c=null,f===0&&b('"="')),c!==null?(h=H(),h!==null?(p=at(),p!==null?r=[a,l,c,h,p]:(r=null,s=u)):(r=null,s=u)):(r=null,s=u)):(r=null,s=u)):(r=null,s=u),r!==null&&(o=i,r=function(e,t){return{key:e,value:t}}(l,h)),r===null&&(s=i);return t!==null&&(o=n,t=function(e){var t={};for(var n=0;n1?arguments[1]:{},i;if(r.startRule!==undefined){i=r.startRule;if(n[i]===undefined)throw new Error("Can't start parsing from rule "+t(i)+".")}else i="content";var s=0,o=0,u=0,a={line:1,column:1,seenCR:!1},f=0,l=0,c=[],ht=n[i]();if(ht===null||s!==e.length){o=Math.max(s,l);var pt=o0&&this.ss.check(RegExp("(?:"+this.indent+"){0,"+(c-1)+"}[^"+o+"]"))){d=0;while(this.discard(RegExp(""+this.indent)))++d;l=c-d;while(l--)this.context.observe(e),this.p(""+e)}else{if(!this.ss.check(RegExp("(?:"+this.indent+"){"+c+"}[^"+o+"]")))throw h=this.ss.str.substr(0,this.ss.pos).split(/\n/)||[""],p="Syntax error on line "+h.length+": invalid indentation",new Error(""+p);this.discard(RegExp("(?:"+this.indent+"){"+c+"}"))}}else if(this.indent=this.discard(RegExp("["+o+"]+")))this.context.observe(t),this.p(t)}this.scan(/[^\n\\]+/),(v=this.discard(/\//))&&this.context.observe(v),this.discard(/\n/)&&this.p(""+n),this.discard(i);break;case"/":this.discard(/.*\n/)&&this.context.observe("\n");break;case"\\":this.scan(/[\s\S]/)&&this.context.observe("end-\\")}if(s){this.scan(r);while(this.context.length&&t===this.context.peek())this.context.observe(e),this.p(""+e);if(this.context.length)throw new Error("Unclosed "+this.context.peek()+" at EOF")}}},u.prototype.processData=s(!1),u.prototype.processEnd=s(!0),u.processSync=function(e){var t;return e+="\n",t=new u,t.processData(e),t.processEnd(),t.output},u}();var ContentStack,Emblem,Handlebars,processNodes,__hasProp={}.hasOwnProperty;ContentStack=function(){function e(){this.current=""}return e.prototype.append=function(e){return this.current+=e},e.prototype.flatten=function(){var e;return e=this.current,this.current="",e},e}(),processNodes=function(e,t,n){var r,i,s,o,u,a,f,l,c,h,p,d,v,m,g,y,b,w,E,S,x,T,N,C,k,L,A,O,M,_,D;n==null&&(n=[]);for(N=0,L=e.length;N"),processNodes(v.nodes||[],t,n),t.append("")}else if(v.type==="mustache"){i=t.flatten(),i&&n.push(new Handlebars.AST.ContentNode(i)),a=v.params[0].charAt(0),!v.forced&&a===a.toUpperCase()&&(l="view",v.params.unshift(l)),b=[],_=v.params;for(C=0,A=_.length;Cthis.stackVars.length&&this.stackVars.push("stack"+this.stackSlot),"stack"+this.stackSlot},popStack:function(){var e=this.compileStack.pop();return e instanceof n?e.value:(this.stackSlot--,e)},topStack:function(){var e=this.compileStack[this.compileStack.length-1];return e instanceof n?e.value:e},quotedString:function(e){return'"'+e.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r")+'"'},setupHelper:function(e,t){var n=[];this.setupParams(e,n);var r=this.nameLookup("helpers",t,"helper");return{params:n,name:r,callParams:["depth0"].concat(n).join(", "),helperMissingParams:["depth0",this.quotedString(t)].concat(n).join(", ")}},setupParams:function(e,t){var n=[],r=[],i=[],s,o,u;n.push("hash:"+this.popStack()),o=this.popStack(),u=this.popStack();if(u||o)u||(this.context.aliases.self="this",u="self.noop"),o||(this.context.aliases.self="this",o="self.noop"),n.push("inverse:"+o),n.push("fn:"+u);for(var a=0;ao&&(u=0,a={line:1,column:1,seenCR:!1}),t()),a}function v(){return e.substring(o,s)}function m(){return o}function g(){return d().line}function y(){return d().column}function b(e){if(sl&&(l=s,c=[]),c.push(e)}function w(){var e,t,n;t=s,e=[],n=S();while(n!==null)e.push(n),n=S();return e!==null&&(o=t,e=function(e){var t=[],n=[];for(var r=0;r")),[u,new Handlebars.AST.ContentNode("")]}(e)),e===null&&(s=t),e}function vt(){var e;return e=mt(),e===null&&(e=gt()),e}function mt(){var e,t,n,r,i,u;t=s,n=s,r=Lt();if(r!==null){i=[],u=At();while(u!==null)i.push(u),u=At();i!==null?e=[r,i]:(e=null,s=n)}else e=null,s=n;return e!==null&&(o=t,e=function(e,t){return[e,t]}(r,i)),e===null&&(s=t),e}function gt(){var e,t,n;t=s,n=At();if(n!==null){e=[];while(n!==null)e.push(n),n=At()}else e=null;return e!==null&&(o=t,e=function(e){return[null,e]}(e)),e===null&&(s=t),e}function yt(){var t,n,r,i,u;n=s,r=s,e.charCodeAt(s)===32?(u=" ",s++):(u=null,f===0&&b('" "'));if(u!==null){i=[];while(u!==null)i.push(u),e.charCodeAt(s)===32?(u=" ",s++):(u=null,f===0&&b('" "'))}else i=null;return i!==null?(u=St(),u===null&&(u=xt(),u===null&&(u=Tt())),u!==null?t=[i,u]:(t=null,s=r)):(t=null,s=r),t!==null&&(o=n,t=function(e){return[new Handlebars.AST.ContentNode(" "),e]}(u)),t===null&&(s=n),t}function bt(){var t,n,r;n=s,/^[A-Za-z.:0-9]/.test(e.charAt(s))?(r=e.charAt(s),s++):(r=null,f===0&&b("[A-Za-z.:0-9]"));if(r!==null){t=[];while(r!==null)t.push(r),/^[A-Za-z.:0-9]/.test(e.charAt(s))?(r=e.charAt(s),s++):(r=null,f===0&&b("[A-Za-z.:0-9]"))}else t=null;return t!==null&&(o=n,t=function(e){return e.join("")}(t)),t===null&&(s=n),t}function wt(){var e,t;return e=Et(),e===null&&(t=s,e=U(),e!==null&&(o=t,e=function(e){return new Handlebars.AST.MustacheNode([e])}(e)),e===null&&(s=t)),e}function Et(){var t,n,r,i,u,a;return n=s,r=s,e.charCodeAt(s)===34?(i='"',s++):(i=null,f===0&&b('"\\""')),i!==null?(u=_(),u!==null?(e.charCodeAt(s)===34?(a='"',s++):(a=null,f===0&&b('"\\""')),a!==null?t=[i,u,a]:(t=null,s=r)):(t=null,s=r)):(t=null,s=r),t===null&&(r=s,e.charCodeAt(s)===39?(i="'",s++):(i=null,f===0&&b('"\'"')),i!==null?(u=_(),u!==null?(e.charCodeAt(s)===39?(a="'",s++):(a=null,f===0&&b('"\'"')),a!==null?t=[i,u,a]:(t=null,s=r)):(t=null,s=r)):(t=null,s=r)),t!==null&&(o=n,t=function(e){return e[1]}(t)),t===null&&(s=n),t}function St(){var t,n,r,i,u,a;return n=s,r=s,i=Ht(),i!==null?(e.charCodeAt(s)===61?(u="=",s++):(u=null,f===0&&b('"="')),u!==null?(a=wt(),a!==null?t=[i,u,a]:(t=null,s=r)):(t=null,s=r)):(t=null,s=r),t!==null&&(o=n,t=function(e,t){return Wt(t,"action",[["on",new Handlebars.AST.StringNode(e)]])}(i,a)),t===null&&(s=n),t}function xt(){var t,n,r,i,u,a;return n=s,r=s,i=Ot(),i!==null?(e.charCodeAt(s)===61?(u="=",s++):(u=null,f===0&&b('"="')),u!==null?(a=bt(),a!==null?t=[i,u,a]:(t=null,s=r)):(t=null,s=r)):(t=null,s=r),t!==null&&(o=n,t=function(e,t){var n=new Handlebars.AST.HashNode([[e,new Handlebars.AST.StringNode(t)]]),r=[new Handlebars.AST.IdNode(["bindAttr"])];return new Handlebars.AST.MustacheNode(r,n)}(i,a)),t===null&&(s=n),t}function Tt(){var t,n,r,i,u,a;return n=s,r=s,i=Ot(),i!==null?(e.charCodeAt(s)===61?(u="=",s++):(u=null,f===0&&b('"="')),u!==null?(a=J(),a!==null?t=[i,u,a]:(t=null,s=r)):(t=null,s=r)):(t=null,s=r),t!==null&&(o=n,t=function(e,t){var n=e+"="+'"'+t+'"';return new Handlebars.AST.ContentNode(n)}(i,a)),t===null&&(s=n),t}function Nt(){var e,t,n;t=s,e=[],n=kt();while(n!==null)e.push(n),n=kt();return e!==null&&(o=t,e=function(e){return e.join("")}(e)),e===null&&(s=t),e}function Ct(){var e;return e=J(),e===null&&(e=I()),e}function kt(){var t;return t=G(),t===null&&(/^[0-9]/.test(e.charAt(s))?(t=e.charAt(s),s++):(t=null,f===0&&b("[0-9]")),t===null&&(e.charCodeAt(s)===95?(t="_",s++):(t=null,f===0&&b('"_"')),t===null&&(e.charCodeAt(s)===45?(t="-",s++):(t=null,f===0&&b('"-"'))))),t}function Lt(){var t,n,r,i,u;return n=s,r=s,e.charCodeAt(s)===35?(i="#",s++):(i=null,f===0&&b('"#"')),i!==null?(u=Ot(),u!==null?t=[i,u]:(t=null,s=r)):(t=null,s=r),t!==null&&(o=n,t=function(e){return e}(u)),t===null&&(s=n),t}function At(){var t,n,r,i,u;return n=s,r=s,e.charCodeAt(s)===46?(i=".",s++):(i=null,f===0&&b('"."')),i!==null?(u=Ot(),u!==null?t=[i,u]:(t=null,s=r)):(t=null,s=r),t!==null&&(o=n,t=function(e){return e}(u)),t===null&&(s=n),t}function Ot(){var e,t,n,r,i,u;t=s,n=s,r=_t();if(r!==null){i=[],u=Mt();while(u!==null)i.push(u),u=Mt();i!==null?e=[r,i]:(e=null,s=n)}else e=null,s=n;return e!==null&&(o=t,e=function(e,t){return e+t.join("")}(r,i)),e===null&&(s=t),e}function Mt(){var t;return/^[_a-zA-Z0-9\-]/.test(e.charAt(s))?(t=e.charAt(s),s++):(t=null,f===0&&b("[_a-zA-Z0-9\\-]")),t===null&&(t=Dt()),t}function _t(){var t;return/^[_a-zA-Z]/.test(e.charAt(s))?(t=e.charAt(s),s++):(t=null,f===0&&b("[_a-zA-Z]")),t===null&&(t=Dt()),t}function Dt(){var t;return/^[\x80-\xFF]/.test(e.charAt(s))?(t=e.charAt(s),s++):(t=null,f===0&&b("[\\x80-\\xFF]")),t}function Pt(){var t;return f++,e.substr(s,10)==="figcaption"?(t="figcaption",s+=10):(t=null,f===0&&b('"figcaption"')),t===null&&(e.substr(s,10)==="blockquote"?(t="blockquote",s+=10):(t=null,f===0&&b('"blockquote"')),t===null&&(e.substr(s,9)==="plaintext"?(t="plaintext",s+=9):(t=null,f===0&&b('"plaintext"')),t===null&&(e.substr(s,8)==="textarea"?(t="textarea",s+=8):(t=null,f===0&&b('"textarea"')),t===null&&(e.substr(s,8)==="progress"?(t="progress",s+=8):(t=null,f===0&&b('"progress"')),t===null&&(e.substr(s,8)==="optgroup"?(t="optgroup",s+=8):(t=null,f===0&&b('"optgroup"')),t===null&&(e.substr(s,8)==="noscript"?(t="noscript",s+=8):(t=null,f===0&&b('"noscript"')),t===null&&(e.substr(s,8)==="noframes"?(t="noframes",s+=8):(t=null,f===0&&b('"noframes"')),t===null&&(e.substr(s,8)==="frameset"?(t="frameset",s+=8):(t=null,f===0&&b('"frameset"')),t===null&&(e.substr(s,8)==="fieldset"?(t="fieldset",s+=8):(t=null,f===0&&b('"fieldset"')),t===null&&(e.substr(s,8)==="datalist"?(t="datalist",s+=8):(t=null,f===0&&b('"datalist"')),t===null&&(e.substr(s,8)==="colgroup"?(t="colgroup",s+=8):(t=null,f===0&&b('"colgroup"')),t===null&&(e.substr(s,8)==="basefont"?(t="basefont",s+=8):(t=null,f===0&&b('"basefont"')),t===null&&(e.substr(s,7)==="summary"?(t="summary",s+=7):(t=null,f===0&&b('"summary"')),t===null&&(e.substr(s,7)==="section"?(t="section",s+=7):(t=null,f===0&&b('"section"')),t===null&&(e.substr(s,7)==="marquee"?(t="marquee",s+=7):(t=null,f===0&&b('"marquee"')),t===null&&(e.substr(s,7)==="listing"?(t="listing",s+=7):(t=null,f===0&&b('"listing"')),t===null&&(e.substr(s,7)==="isindex"?(t="isindex",s+=7):(t=null,f===0&&b('"isindex"')),t===null&&(e.substr(s,7)==="details"?(t="details",s+=7):(t=null,f===0&&b('"details"')),t===null&&(e.substr(s,7)==="command"?(t="command",s+=7):(t=null,f===0&&b('"command"')),t===null&&(e.substr(s,7)==="caption"?(t="caption",s+=7):(t=null,f===0&&b('"caption"')),t===null&&(e.substr(s,7)==="bgsound"?(t="bgsound",s+=7):(t=null,f===0&&b('"bgsound"')),t===null&&(e.substr(s,7)==="article"?(t="article",s+=7):(t=null,f===0&&b('"article"')),t===null&&(e.substr(s,7)==="address"?(t="address",s+=7):(t=null,f===0&&b('"address"')),t===null&&(e.substr(s,7)==="acronym"?(t="acronym",s+=7):(t=null,f===0&&b('"acronym"')),t===null&&(e.substr(s,6)==="strong"?(t="strong",s+=6):(t=null,f===0&&b('"strong"')),t===null&&(e.substr(s,6)==="strike"?(t="strike",s+=6):(t=null,f===0&&b('"strike"')),t===null&&(e.substr(s,6)==="spacer"?(t="spacer",s+=6):(t=null,f===0&&b('"spacer"')),t===null&&(e.substr(s,6)==="source"?(t="source",s+=6):(t=null,f===0&&b('"source"')),t===null&&(e.substr(s,6)==="select"?(t="select",s+=6):(t=null,f===0&&b('"select"')),t===null&&(e.substr(s,6)==="script"?(t="script",s+=6):(t=null,f===0&&b('"script"')),t===null&&(e.substr(s,6)==="output"?(t="output",s+=6):(t=null,f===0&&b('"output"')),t===null&&(e.substr(s,6)==="option"?(t="option",s+=6):(t=null,f===0&&b('"option"')),t===null&&(e.substr(s,6)==="object"?(t="object",s+=6):(t=null,f===0&&b('"object"')),t===null&&(e.substr(s,6)==="legend"?(t="legend",s+=6):(t=null,f===0&&b('"legend"')),t===null&&(e.substr(s,6)==="keygen"?(t="keygen",s+=6):(t=null,f===0&&b('"keygen"')),t===null&&(e.substr(s,6)==="iframe"?(t="iframe",s+=6):(t=null,f===0&&b('"iframe"')),t===null&&(e.substr(s,6)==="hgroup"?(t="hgroup",s+=6):(t=null,f===0&&b('"hgroup"')),t===null&&(e.substr(s,6)==="header"?(t="header",s+=6):(t=null,f===0&&b('"header"')),t===null&&(e.substr(s,6)==="footer"?(t="footer",s+=6):(t=null,f===0&&b('"footer"')),t===null&&(e.substr(s,6)==="figure"?(t="figure",s+=6):(t=null,f===0&&b('"figure"')),t===null&&(e.substr(s,6)==="center"?(t="center",s+=6):(t=null,f===0&&b('"center"')),t===null&&(e.substr(s,6)==="canvas"?(t="canvas",s+=6):(t=null,f===0&&b('"canvas"')),t===null&&(e.substr(s,6)==="button"?(t="button",s+=6):(t=null,f===0&&b('"button"')),t===null&&(e.substr(s,6)==="applet"?(t="applet",s+=6):(t=null,f===0&&b('"applet"')),t===null&&(e.substr(s,5)==="video"?(t="video",s+=5):(t=null,f===0&&b('"video"')),t===null&&(e.substr(s,5)==="track"?(t="track",s+=5):(t=null,f===0&&b('"track"')),t===null&&(e.substr(s,5)==="title"?(t="title",s+=5):(t=null,f===0&&b('"title"')),t===null&&(e.substr(s,5)==="thead"?(t="thead",s+=5):(t=null,f===0&&b('"thead"')),t===null&&(e.substr(s,5)==="tfoot"?(t="tfoot",s+=5):(t=null,f===0&&b('"tfoot"')),t===null&&(e.substr(s,5)==="tbody"?(t="tbody",s+=5):(t=null,f===0&&b('"tbody"')),t===null&&(e.substr(s,5)==="table"?(t="table",s+=5):(t=null,f===0&&b('"table"')),t===null&&(e.substr(s,5)==="style"?(t="style",s+=5):(t=null,f===0&&b('"style"')),t===null&&(e.substr(s,5)==="small"?(t="small",s+=5):(t=null,f===0&&b('"small"')),t===null&&(e.substr(s,5)==="param"?(t="param",s+=5):(t=null,f===0&&b('"param"')),t===null&&(e.substr(s,5)==="meter"?(t="meter",s+=5):(t=null,f===0&&b('"meter"')),t===null&&(e.substr(s,5)==="label"?(t="label",s+=5):(t=null,f===0&&b('"label"')),t===null&&(e.substr(s,5)==="input"?(t="input",s+=5):(t=null,f===0&&b('"input"')),t===null&&(e.substr(s,5)==="frame"?(t="frame",s+=5):(t=null,f===0&&b('"frame"')),t===null&&(e.substr(s,5)==="embed"?(t="embed",s+=5):(t=null,f===0&&b('"embed"')),t===null&&(e.substr(s,5)==="blink"?(t="blink",s+=5):(t=null,f===0&&b('"blink"')),t===null&&(e.substr(s,5)==="audio"?(t="audio",s+=5):(t=null,f===0&&b('"audio"')),t===null&&(e.substr(s,5)==="aside"?(t="aside",s+=5):(t=null,f===0&&b('"aside"')),t===null&&(e.substr(s,4)==="time"?(t="time",s+=4):(t=null,f===0&&b('"time"')),t===null&&(e.substr(s,4)==="span"?(t="span",s+=4):(t=null,f===0&&b('"span"')),t===null&&(e.substr(s,4)==="samp"?(t="samp",s+=4):(t=null,f===0&&b('"samp"')),t===null&&(e.substr(s,4)==="ruby"?(t="ruby",s+=4):(t=null,f===0&&b('"ruby"')),t===null&&(e.substr(s,4)==="nobr"?(t="nobr",s+=4):(t=null,f===0&&b('"nobr"')),t===null&&(e.substr(s,4)==="meta"?(t="meta",s+=4):(t=null,f===0&&b('"meta"')),t===null&&(e.substr(s,4)==="menu"?(t="menu",s+=4):(t=null,f===0&&b('"menu"')),t===null&&(e.substr(s,4)==="mark"?(t="mark",s+=4):(t=null,f===0&&b('"mark"')),t===null&&(e.substr(s,4)==="main"?(t="main",s+=4):(t=null,f===0&&b('"main"')),t===null&&(e.substr(s,4)==="link"?(t="link",s+=4):(t=null,f===0&&b('"link"')),t===null&&(e.substr(s,4)==="html"?(t="html",s+=4):(t=null,f===0&&b('"html"')),t===null&&(e.substr(s,4)==="head"?(t="head",s+=4):(t=null,f===0&&b('"head"')),t===null&&(e.substr(s,4)==="form"?(t="form",s+=4):(t=null,f===0&&b('"form"')),t===null&&(e.substr(s,4)==="font"?(t="font",s+=4):(t=null,f===0&&b('"font"')),t===null&&(e.substr(s,4)==="data"?(t="data",s+=4):(t=null,f===0&&b('"data"')),t===null&&(e.substr(s,4)==="code"?(t="code",s+=4):(t=null,f===0&&b('"code"')),t===null&&(e.substr(s,4)==="cite"?(t="cite",s+=4):(t=null,f===0&&b('"cite"')),t===null&&(e.substr(s,4)==="body"?(t="body",s+=4):(t=null,f===0&&b('"body"')),t===null&&(e.substr(s,4)==="base"?(t="base",s+=4):(t=null,f===0&&b('"base"')),t===null&&(e.substr(s,4)==="area"?(t="area",s+=4):(t=null,f===0&&b('"area"')),t===null&&(e.substr(s,4)==="abbr"?(t="abbr",s+=4):(t=null,f===0&&b('"abbr"')),t===null&&(e.substr(s,3)==="xmp"?(t="xmp",s+=3):(t=null,f===0&&b('"xmp"')),t===null&&(e.substr(s,3)==="wbr"?(t="wbr",s+=3):(t=null,f===0&&b('"wbr"')),t===null&&(e.substr(s,3)==="var"?(t="var",s+=3):(t=null,f===0&&b('"var"' +)),t===null&&(e.substr(s,3)==="sup"?(t="sup",s+=3):(t=null,f===0&&b('"sup"')),t===null&&(e.substr(s,3)==="sub"?(t="sub",s+=3):(t=null,f===0&&b('"sub"')),t===null&&(e.substr(s,3)==="pre"?(t="pre",s+=3):(t=null,f===0&&b('"pre"')),t===null&&(e.substr(s,3)==="nav"?(t="nav",s+=3):(t=null,f===0&&b('"nav"')),t===null&&(e.substr(s,3)==="map"?(t="map",s+=3):(t=null,f===0&&b('"map"')),t===null&&(e.substr(s,3)==="kbd"?(t="kbd",s+=3):(t=null,f===0&&b('"kbd"')),t===null&&(e.substr(s,3)==="ins"?(t="ins",s+=3):(t=null,f===0&&b('"ins"')),t===null&&(e.substr(s,3)==="img"?(t="img",s+=3):(t=null,f===0&&b('"img"')),t===null&&(e.substr(s,3)==="div"?(t="div",s+=3):(t=null,f===0&&b('"div"')),t===null&&(e.substr(s,3)==="dir"?(t="dir",s+=3):(t=null,f===0&&b('"dir"')),t===null&&(e.substr(s,3)==="dfn"?(t="dfn",s+=3):(t=null,f===0&&b('"dfn"')),t===null&&(e.substr(s,3)==="del"?(t="del",s+=3):(t=null,f===0&&b('"del"')),t===null&&(e.substr(s,3)==="col"?(t="col",s+=3):(t=null,f===0&&b('"col"')),t===null&&(e.substr(s,3)==="big"?(t="big",s+=3):(t=null,f===0&&b('"big"')),t===null&&(e.substr(s,3)==="bdo"?(t="bdo",s+=3):(t=null,f===0&&b('"bdo"')),t===null&&(e.substr(s,3)==="bdi"?(t="bdi",s+=3):(t=null,f===0&&b('"bdi"')),t===null&&(e.substr(s,2)==="ul"?(t="ul",s+=2):(t=null,f===0&&b('"ul"')),t===null&&(e.substr(s,2)==="tt"?(t="tt",s+=2):(t=null,f===0&&b('"tt"')),t===null&&(e.substr(s,2)==="tr"?(t="tr",s+=2):(t=null,f===0&&b('"tr"')),t===null&&(e.substr(s,2)==="th"?(t="th",s+=2):(t=null,f===0&&b('"th"')),t===null&&(e.substr(s,2)==="td"?(t="td",s+=2):(t=null,f===0&&b('"td"')),t===null&&(e.substr(s,2)==="rt"?(t="rt",s+=2):(t=null,f===0&&b('"rt"')),t===null&&(e.substr(s,2)==="rp"?(t="rp",s+=2):(t=null,f===0&&b('"rp"')),t===null&&(e.substr(s,2)==="ol"?(t="ol",s+=2):(t=null,f===0&&b('"ol"')),t===null&&(e.substr(s,2)==="li"?(t="li",s+=2):(t=null,f===0&&b('"li"')),t===null&&(e.substr(s,2)==="hr"?(t="hr",s+=2):(t=null,f===0&&b('"hr"')),t===null&&(e.substr(s,2)==="h6"?(t="h6",s+=2):(t=null,f===0&&b('"h6"')),t===null&&(e.substr(s,2)==="h5"?(t="h5",s+=2):(t=null,f===0&&b('"h5"')),t===null&&(e.substr(s,2)==="h4"?(t="h4",s+=2):(t=null,f===0&&b('"h4"')),t===null&&(e.substr(s,2)==="h3"?(t="h3",s+=2):(t=null,f===0&&b('"h3"')),t===null&&(e.substr(s,2)==="h2"?(t="h2",s+=2):(t=null,f===0&&b('"h2"')),t===null&&(e.substr(s,2)==="h1"?(t="h1",s+=2):(t=null,f===0&&b('"h1"')),t===null&&(e.substr(s,2)==="em"?(t="em",s+=2):(t=null,f===0&&b('"em"')),t===null&&(e.substr(s,2)==="dt"?(t="dt",s+=2):(t=null,f===0&&b('"dt"')),t===null&&(e.substr(s,2)==="dl"?(t="dl",s+=2):(t=null,f===0&&b('"dl"')),t===null&&(e.substr(s,2)==="dd"?(t="dd",s+=2):(t=null,f===0&&b('"dd"')),t===null&&(e.substr(s,2)==="br"?(t="br",s+=2):(t=null,f===0&&b('"br"')),t===null&&(e.charCodeAt(s)===117?(t="u",s++):(t=null,f===0&&b('"u"')),t===null&&(e.charCodeAt(s)===115?(t="s",s++):(t=null,f===0&&b('"s"')),t===null&&(e.charCodeAt(s)===113?(t="q",s++):(t=null,f===0&&b('"q"')),t===null&&(e.charCodeAt(s)===112?(t="p",s++):(t=null,f===0&&b('"p"')),t===null&&(e.charCodeAt(s)===105?(t="i",s++):(t=null,f===0&&b('"i"')),t===null&&(e.charCodeAt(s)===98?(t="b",s++):(t=null,f===0&&b('"b"')),t===null&&(e.charCodeAt(s)===97?(t="a",s++):(t=null,f===0&&b('"a"')))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))),f--,f===0&&t===null&&b("a valid HTML tag name"),t}function Ht(){var t;return f++,e.substr(s,10)==="touchStart"?(t="touchStart",s+=10):(t=null,f===0&&b('"touchStart"')),t===null&&(e.substr(s,9)==="touchMove"?(t="touchMove",s+=9):(t=null,f===0&&b('"touchMove"')),t===null&&(e.substr(s,8)==="touchEnd"?(t="touchEnd",s+=8):(t=null,f===0&&b('"touchEnd"')),t===null&&(e.substr(s,11)==="touchCancel"?(t="touchCancel",s+=11):(t=null,f===0&&b('"touchCancel"')),t===null&&(e.substr(s,7)==="keyDown"?(t="keyDown",s+=7):(t=null,f===0&&b('"keyDown"')),t===null&&(e.substr(s,5)==="keyUp"?(t="keyUp",s+=5):(t=null,f===0&&b('"keyUp"')),t===null&&(e.substr(s,8)==="keyPress"?(t="keyPress",s+=8):(t=null,f===0&&b('"keyPress"')),t===null&&(e.substr(s,9)==="mouseDown"?(t="mouseDown",s+=9):(t=null,f===0&&b('"mouseDown"')),t===null&&(e.substr(s,7)==="mouseUp"?(t="mouseUp",s+=7):(t=null,f===0&&b('"mouseUp"')),t===null&&(e.substr(s,11)==="contextMenu"?(t="contextMenu",s+=11):(t=null,f===0&&b('"contextMenu"')),t===null&&(e.substr(s,5)==="click"?(t="click",s+=5):(t=null,f===0&&b('"click"')),t===null&&(e.substr(s,11)==="doubleClick"?(t="doubleClick",s+=11):(t=null,f===0&&b('"doubleClick"')),t===null&&(e.substr(s,9)==="mouseMove"?(t="mouseMove",s+=9):(t=null,f===0&&b('"mouseMove"')),t===null&&(e.substr(s,7)==="focusIn"?(t="focusIn",s+=7):(t=null,f===0&&b('"focusIn"')),t===null&&(e.substr(s,8)==="focusOut"?(t="focusOut",s+=8):(t=null,f===0&&b('"focusOut"')),t===null&&(e.substr(s,10)==="mouseEnter"?(t="mouseEnter",s+=10):(t=null,f===0&&b('"mouseEnter"')),t===null&&(e.substr(s,10)==="mouseLeave"?(t="mouseLeave",s+=10):(t=null,f===0&&b('"mouseLeave"')),t===null&&(e.substr(s,6)==="submit"?(t="submit",s+=6):(t=null,f===0&&b('"submit"')),t===null&&(e.substr(s,5)==="input"?(t="input",s+=5):(t=null,f===0&&b('"input"')),t===null&&(e.substr(s,6)==="change"?(t="change",s+=6):(t=null,f===0&&b('"change"')),t===null&&(e.substr(s,9)==="dragStart"?(t="dragStart",s+=9):(t=null,f===0&&b('"dragStart"')),t===null&&(e.substr(s,4)==="drag"?(t="drag",s+=4):(t=null,f===0&&b('"drag"')),t===null&&(e.substr(s,9)==="dragEnter"?(t="dragEnter",s+=9):(t=null,f===0&&b('"dragEnter"')),t===null&&(e.substr(s,9)==="dragLeave"?(t="dragLeave",s+=9):(t=null,f===0&&b('"dragLeave"')),t===null&&(e.substr(s,8)==="dragOver"?(t="dragOver",s+=8):(t=null,f===0&&b('"dragOver"')),t===null&&(e.substr(s,4)==="drop"?(t="drop",s+=4):(t=null,f===0&&b('"drop"')),t===null&&(e.substr(s,7)==="dragEnd"?(t="dragEnd",s+=7):(t=null,f===0&&b('"dragEnd"')))))))))))))))))))))))))))),f--,f===0&&t===null&&b("a JS event"),t}function Bt(){var t,n;return f++,n=s,e.charCodeAt(s)===61423?(t="",s++):(t=null,f===0&&b('"\\uEFEF"')),t!==null&&(o=n,t=function(){return""}()),t===null&&(s=n),f--,f===0&&t===null&&b("INDENT"),t}function jt(){var t,n;return f++,n=s,e.charCodeAt(s)===61438?(t="",s++):(t=null,f===0&&b('"\\uEFFE"')),t!==null&&(o=n,t=function(){return""}()),t===null&&(s=n),f--,f===0&&t===null&&b("DEDENT"),t}function Ft(){var t,n;return f++,n=s,e.charCodeAt(s)===61439?(t="",s++):(t=null,f===0&&b('"\\uEFFF"')),t!==null&&(o=n,t=function(){return""}()),t===null&&(s=n),f--,f===0&&t===null&&b("TERM"),t}function It(){var e,t;f++,t=Rt();if(t!==null){e=[];while(t!==null)e.push(t),t=Rt()}else e=null;return f--,f===0&&e===null&&b("required whitespace"),e}function qt(){var e,t;f++,e=[],t=Rt();while(t!==null)e.push(t),t=Rt();return f--,f===0&&e===null&&b("whitespace"),e}function Rt(){var t;return/^[ \t\n\r]/.test(e.charAt(s))?(t=e.charAt(s),s++):(t=null,f===0&&b("[ \\t\\n\\r]")),t}function Ut(){var t,n,r;n=s,t=[],/^[^\uEFFF\uEFFE\uEFEF]/.test(e.charAt(s))?(r=e.charAt(s),s++):(r=null,f===0&&b("[^\\uEFFF\\uEFFE\\uEFEF]"));while(r!==null)t.push(r),/^[^\uEFFF\uEFFE\uEFEF]/.test(e.charAt(s))?(r=e.charAt(s),s++):(r=null,f===0&&b("[^\\uEFFF\\uEFFE\\uEFEF]"));return t!==null&&(o=n,t=function(e){return e.join("")}(t)),t===null&&(s=n),t}function zt(e){e.sort();var t=null,n=[];for(var r=0;r1?arguments[1]:{},i;if(r.startRule!==undefined){i=r.startRule;if(n[i]===undefined)throw new Error("Can't start parsing from rule "+t(i)+".")}else i="content";var s=0,o=0,u=0,a={line:1,column:1,seenCR:!1},f=0,l=0,c=[],Xt=n[i]();if(Xt===null||s!==e.length){o=Math.max(s,l);var Vt=o0&&this.ss.check(RegExp("(?:"+this.indent+"){0,"+(c-1)+"}[^"+o+"]"))){d=0;while(this.discard(RegExp(""+this.indent)))++d;l=c-d;while(l--)this.context.observe(e),this.p(""+e)}else{if(!this.ss.check(RegExp("(?:"+this.indent+"){"+c+"}[^"+o+"]")))throw h=this.ss.str.substr(0,this.ss.pos).split(/\n/)||[""],p="Syntax error on line "+h.length+": invalid indentation",new Error(""+p);this.discard(RegExp("(?:"+this.indent+"){"+c+"}"))}}else if(this.indent=this.discard(RegExp("["+o+"]+")))this.context.observe(t),this.p(t)}this.scan(/[^\n\\]+/),(v=this.discard(/\//))&&this.context.observe(v),this.discard(/\n/)&&this.p(""+n),this.discard(i);break;case"/":this.discard(/.*\n/)&&this.context.observe("\n");break;case"\\":this.scan(/[\s\S]/)&&this.context.observe("end-\\")}if(s){this.scan(r);while(this.context.length&&t===this.context.peek())this.context.observe(e),this.p(""+e);if(this.context.length)throw new Error("Unclosed "+this.context.peek()+" at EOF")}}},u.prototype.processData=s(!1),u.prototype.processEnd=s(!0),u.processSync=function(e){var t;return e+="\n",t=new u,t.processData(e),t.processEnd(),t.output},u}();var ENV,Emblem,_base;Emblem.bootstrap=function(e){return e==null&&(e=Ember.$(document)),Emblem.precompile=Emblem.precompileEmber,Emblem.compile=Emblem.compileEmber,Ember.$('script[type="text/x-emblem"]',e).each(function(){var e,t;return e=Ember.$(this),t=e.attr("data-template-name")||e.attr("id")||"application",Ember.TEMPLATES[t]=Emblem.compile(e.html()),e.remove()})},this.ENV||(this.ENV={}),ENV=this.ENV,ENV.EMBER_LOAD_HOOKS||(ENV.EMBER_LOAD_HOOKS={}),(_base=ENV.EMBER_LOAD_HOOKS).application||(_base.application=[]),ENV.EMBER_LOAD_HOOKS.application.push(function(){return Emblem.bootstrap()}); \ No newline at end of file diff --git a/lib/compiler.js b/lib/compiler.js index 153b326..8900c6f 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -1,4 +1,3 @@ -// Generated by CoffeeScript 1.4.0 var Emblem, Handlebars, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; @@ -6,6 +5,12 @@ Handlebars = require('handlebars'); Emblem = require('./emblem'); +Emblem.parse = function(string) { + var processed; + processed = Emblem.Preprocessor.processSync(string); + return new Handlebars.AST.ProgramNode(Emblem.Parser.parse(processed), []); +}; + Emblem.precompileRaw = function(string, options) { var ast, environment; if (options == null) { diff --git a/lib/emberties.js b/lib/emberties.js index 15dbf6d..d4bf3cd 100644 --- a/lib/emberties.js +++ b/lib/emberties.js @@ -1,4 +1,3 @@ -// Generated by CoffeeScript 1.4.0 var ENV, Emblem, _base; Emblem = require('./emblem'); diff --git a/lib/emblem.js b/lib/emblem.js index e5014c8..3920946 100644 --- a/lib/emblem.js +++ b/lib/emblem.js @@ -1,4 +1,3 @@ -// Generated by CoffeeScript 1.4.0 var Emblem; this.Emblem = {}; @@ -15,6 +14,4 @@ require('./compiler'); require('./preprocessor'); -require('./translation'); - require('./emberties'); diff --git a/lib/parser.js b/lib/parser.js index a889558..d6a9153 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -1,4 +1,5 @@ +var Handlebars = require('handlebars'); var Emblem = require('./emblem'); Emblem.Parser = (function(){ @@ -159,66 +160,185 @@ Emblem.Parser = (function(){ } function parse_content() { - var r0, r1; + var r0, r1, r2; + r1 = pos; r0 = []; - r1 = parse_statement(); - while (r1 !== null) { - r0.push(r1); - r1 = parse_statement(); + r2 = parse_statement(); + while (r2 !== null) { + r0.push(r2); + r2 = parse_statement(); + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(statements) { + // Coalesce all adjacent ContentNodes into one. + + var compressedStatements = []; + var buffer = []; + + for(var i = 0; i < statements.length; ++i) { + var nodes = statements[i]; + + for(var j = 0; j < nodes.length; ++j) { + var node = nodes[j] + if(node.type === "content") { + if(node.string) { + // Ignore empty strings (comments). + buffer.push(node.string); + } + continue; + } + + // Flush content if present. + if(buffer.length) { + compressedStatements.push(new Handlebars.AST.ContentNode(buffer.join(''))); + buffer = []; + } + compressedStatements.push(node); + } + } + + if(buffer.length) { + compressedStatements.push(new Handlebars.AST.ContentNode(buffer.join(''))); + } + + return compressedStatements; + })(r0); + } + if (r0 === null) { + pos = r1; } return r0; } - function parse_statement() { - var r0; + function parse_invertibleContent() { + var r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12; - r0 = parse_comment(); - if (r0 === null) { - r0 = parse_html(); - if (r0 === null) { - r0 = parse_mustache(); + r1 = pos; + r2 = pos; + r3 = parse_content(); + if (r3 !== null) { + r5 = pos; + r6 = pos; + r7 = parse_DEDENT(); + if (r7 !== null) { + if (input.substr(pos, 4) === "else") { + r8 = "else"; + pos += 4; + } else { + r8 = null; + if (reportFailures === 0) { + matchFailed("\"else\""); + } + } + if (r8 !== null) { + r9 = parse__(); + if (r9 !== null) { + r10 = parse_TERM(); + if (r10 !== null) { + r11 = parse_INDENT(); + if (r11 !== null) { + r12 = parse_content(); + if (r12 !== null) { + r4 = [r7, r8, r9, r10, r11, r12]; + } else { + r4 = null; + pos = r6; + } + } else { + r4 = null; + pos = r6; + } + } else { + r4 = null; + pos = r6; + } + } else { + r4 = null; + pos = r6; + } + } else { + r4 = null; + pos = r6; + } + } else { + r4 = null; + pos = r6; + } + if (r4 !== null) { + reportedPos = r5; + r4 = (function(c) {return c;})(r12); + } + if (r4 === null) { + pos = r5; + } + r4 = r4 !== null ? r4 : ""; + if (r4 !== null) { + r0 = [r3, r4]; + } else { + r0 = null; + pos = r2; } + } else { + r0 = null; + pos = r2; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(c, i) { + return new Handlebars.AST.ProgramNode(c, i || []); + })(r3, r4); + } + if (r0 === null) { + pos = r1; } return r0; } - function parse_html() { - var r0, r1; + function parse_statement() { + var r0; - r0 = parse_htmlMaybeBlock(); + r0 = parse_comment(); if (r0 === null) { - r0 = parse_htmlWithInlineContent(); + r0 = parse_htmlElement(); if (r0 === null) { - r1 = pos; r0 = parse_textLine(); - if (r0 !== null) { - reportedPos = r1; - r0 = (function(t) { return t; })(r0); - } if (r0 === null) { - pos = r1; + r0 = parse_mustache(); } } } return r0; } + function parse_htmlElement() { + var r0; + + r0 = parse_htmlElementMaybeBlock(); + if (r0 === null) { + r0 = parse_htmlElementWithInlineContent(); + } + return r0; + } + function parse_mustache() { var r0, r1; r1 = pos; - r0 = parse_forcedMustache(); + r0 = parse_explicitMustache(); + if (r0 === null) { + r0 = parse_lineStartingMustache(); + } if (r0 !== null) { reportedPos = r1; - r0 = (function(f) { return f; })(r0); + r0 = (function(m) { + return [m]; + })(r0); } if (r0 === null) { pos = r1; } - if (r0 === null) { - r0 = parse_mustacheMaybeBlock(); - } return r0; } @@ -317,7 +437,7 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function() { return ""; })(); + r0 = (function() { return []; })(); } if (r0 === null) { pos = r1; @@ -325,34 +445,41 @@ Emblem.Parser = (function(){ return r0; } - function parse_htmlMaybeBlock() { - var r0, r1, r2, r3, r4, r5, r6, r7, r8; + function parse_lineStartingMustache() { + var r0; + + r0 = parse_capitalizedLineStarterMustache(); + if (r0 === null) { + r0 = parse_mustacheMaybeBlock(); + } + return r0; + } + + function parse_capitalizedLineStarterMustache() { + var r0, r1, r2, r3, r4; r1 = pos; r2 = pos; - r3 = parse_htmlAttributesOnly(); - if (r3 !== null) { - r5 = pos; - r6 = parse_INDENT(); - if (r6 !== null) { - r7 = parse_content(); - if (r7 !== null) { - r8 = parse_DEDENT(); - if (r8 !== null) { - r4 = [r6, r7, r8]; - } else { - r4 = null; - pos = r5; - } - } else { - r4 = null; - pos = r5; - } - } else { - r4 = null; - pos = r5; + r4 = pos; + reportFailures++; + if (/^[A-Z]/.test(input.charAt(pos))) { + r3 = input.charAt(pos); + pos++; + } else { + r3 = null; + if (reportFailures === 0) { + matchFailed("[A-Z]"); } - r4 = r4 !== null ? r4 : ""; + } + reportFailures--; + if (r3 !== null) { + r3 = ""; + pos = r4; + } else { + r3 = null; + } + if (r3 !== null) { + r4 = parse_mustacheMaybeBlock(); if (r4 !== null) { r0 = [r3, r4]; } else { @@ -365,10 +492,19 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(h, c) { - h.nodes = c ? c[1] : []; - return h; - })(r3, r4); + r0 = (function(ret) { + // TODO make this configurable + var defaultCapitalizedHelper = 'view'; + + if(ret.mustache) { + // Block. Modify inner MustacheNode and return. + ret.mustache = unshiftParam(ret.mustache, defaultCapitalizedHelper); + return ret; + } else { + // ret is the MustacheNode + return unshiftParam(ret, defaultCapitalizedHelper); + } + })(r4); } if (r0 === null) { pos = r1; @@ -376,18 +512,44 @@ Emblem.Parser = (function(){ return r0; } - function parse_htmlAttributesOnly() { - var r0, r1, r2, r3, r4, r5; + function parse_htmlElementMaybeBlock() { + var r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10; r1 = pos; r2 = pos; - r3 = parse_htmlTag(); + r3 = parse_htmlTagAndOptionalAttributes(); if (r3 !== null) { r4 = parse__(); if (r4 !== null) { r5 = parse_TERM(); if (r5 !== null) { - r0 = [r3, r4, r5]; + r7 = pos; + r8 = parse_INDENT(); + if (r8 !== null) { + r9 = parse_content(); + if (r9 !== null) { + r10 = parse_DEDENT(); + if (r10 !== null) { + r6 = [r8, r9, r10]; + } else { + r6 = null; + pos = r7; + } + } else { + r6 = null; + pos = r7; + } + } else { + r6 = null; + pos = r7; + } + r6 = r6 !== null ? r6 : ""; + if (r6 !== null) { + r0 = [r3, r4, r5, r6]; + } else { + r0 = null; + pos = r2; + } } else { r0 = null; pos = r2; @@ -402,7 +564,15 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(t) { t.nodes = []; return t; })(r3); + r0 = (function(h, c) { + var ret = h[0]; + if(c) { + ret = ret.concat(c[1]); + } + ret.push(h[1]); + + return ret; + })(r3, r6); } if (r0 === null) { pos = r1; @@ -410,24 +580,26 @@ Emblem.Parser = (function(){ return r0; } - function parse_htmlWithInlineContent() { - var r0, r1, r2, r3, r4, r5, r6; + function parse_htmlElementWithInlineContent() { + var r0, r1, r2, r3, r4, r5; r1 = pos; r2 = pos; - r3 = parse_htmlTag(); + r3 = parse_htmlTagAndOptionalAttributes(); if (r3 !== null) { - r4 = parse_whitespace(); + if (input.charCodeAt(pos) === 32) { + r4 = " "; + pos++; + } else { + r4 = null; + if (reportFailures === 0) { + matchFailed("\" \""); + } + } if (r4 !== null) { r5 = parse_htmlInlineContent(); if (r5 !== null) { - r6 = parse_TERM(); - if (r6 !== null) { - r0 = [r3, r4, r5, r6]; - } else { - r0 = null; - pos = r2; - } + r0 = [r3, r4, r5]; } else { r0 = null; pos = r2; @@ -442,7 +614,15 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(t, c) { t.nodes = c; return t; })(r3, r5); + r0 = (function(h, c) { + var ret = h[0]; + if(c) { + ret = ret.concat(c); + } + ret.push(h[1]); + + return ret; + })(r3, r5); } if (r0 === null) { pos = r1; @@ -451,37 +631,43 @@ Emblem.Parser = (function(){ } function parse_mustacheMaybeBlock() { - var r0, r1, r2, r3, r4, r5, r6, r7, r8, r9; + var r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10; r1 = pos; r2 = pos; - r3 = parse_mustacheContent(); + r3 = parse_inMustache(); if (r3 !== null) { - r4 = parse_TERM(); + r4 = parse__(); if (r4 !== null) { - r6 = pos; - r7 = parse_INDENT(); - if (r7 !== null) { - r8 = parse_content(); + r5 = parse_TERM(); + if (r5 !== null) { + r7 = pos; + r8 = parse_INDENT(); if (r8 !== null) { - r9 = parse_DEDENT(); + r9 = parse_invertibleContent(); if (r9 !== null) { - r5 = [r7, r8, r9]; + r10 = parse_DEDENT(); + if (r10 !== null) { + r6 = [r8, r9, r10]; + } else { + r6 = null; + pos = r7; + } } else { - r5 = null; - pos = r6; + r6 = null; + pos = r7; } } else { - r5 = null; - pos = r6; + r6 = null; + pos = r7; + } + r6 = r6 !== null ? r6 : ""; + if (r6 !== null) { + r0 = [r3, r4, r5, r6]; + } else { + r0 = null; + pos = r2; } - } else { - r5 = null; - pos = r6; - } - r5 = r5 !== null ? r5 : ""; - if (r5 !== null) { - r0 = [r3, r4, r5]; } else { r0 = null; pos = r2; @@ -496,10 +682,11 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(t, c) { - t.nodes = c ? c[1] : []; - return t; - })(r3, r5); + r0 = (function(mustacheNode, block) { + if(!block) return mustacheNode; + var programNode = block[1]; + return new Handlebars.AST.BlockNode(mustacheNode, programNode, programNode.inverse, mustacheNode.id); + })(r3, r6); } if (r0 === null) { pos = r1; @@ -507,22 +694,16 @@ Emblem.Parser = (function(){ return r0; } - function parse_forcedMustache() { - var r0, r1, r2, r3, r4, r5; + function parse_explicitMustache() { + var r0, r1, r2, r3, r4; r1 = pos; r2 = pos; - r3 = parse__(); + r3 = parse_equalSign(); if (r3 !== null) { - r4 = parse_equalSign(); + r4 = parse_mustacheMaybeBlock(); if (r4 !== null) { - r5 = parse_mustacheMaybeBlock(); - if (r5 !== null) { - r0 = [r3, r4, r5]; - } else { - r0 = null; - pos = r2; - } + r0 = [r3, r4]; } else { r0 = null; pos = r2; @@ -533,7 +714,11 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(e, c) { c.forced = true; c.escaped = e; return c; })(r4, r5); + r0 = (function(e, ret) { + var mustache = ret.mustache || ret; + mustache.escaped = e; + return ret; + })(r3, r4); } if (r0 === null) { pos = r1; @@ -541,35 +726,31 @@ Emblem.Parser = (function(){ return r0; } - function parse_mustacheContent() { - var r0, r1, r2, r3, r4, r5; + function parse_inMustache() { + var r0, r1, r2, r3, r4, r5, r6; r1 = pos; r2 = pos; - r4 = pos; - reportFailures++; - if (/^[A-Za-z]/.test(input.charAt(pos))) { - r3 = input.charAt(pos); - pos++; - } else { - r3 = null; - if (reportFailures === 0) { - matchFailed("[A-Za-z]"); - } - } - reportFailures--; + r3 = parse_pathIdNode(); if (r3 !== null) { - r3 = ""; - pos = r4; - } else { - r3 = null; - } - if (r3 !== null) { - r4 = parse_params(); + r4 = parse_trailingModifier(); + r4 = r4 !== null ? r4 : ""; if (r4 !== null) { - r5 = parse_hash(); + r5 = []; + r6 = parse_inMustacheParam(); + while (r6 !== null) { + r5.push(r6); + r6 = parse_inMustacheParam(); + } if (r5 !== null) { - r0 = [r3, r4, r5]; + r6 = parse_hash(); + r6 = r6 !== null ? r6 : ""; + if (r6 !== null) { + r0 = [r3, r4, r5, r6]; + } else { + r0 = null; + pos = r2; + } } else { r0 = null; pos = r2; @@ -584,9 +765,21 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(p, h) { - return { type: 'mustache', params:p, hash:h }; - })(r4, r5); + r0 = (function(path, tm, params, hash) { + params.unshift(path); + + var mustacheNode = new Handlebars.AST.MustacheNode(params, hash); + + if(tm == '!') { + return unshiftParam(mustacheNode, 'unbound'); + } else if(tm == '?') { + return unshiftParam(mustacheNode, 'if'); + } else if(tm == '^') { + return unshiftParam(mustacheNode, 'unless'); + } + + return mustacheNode; + })(r3, r4, r5, r6); } if (r0 === null) { pos = r1; @@ -594,123 +787,59 @@ Emblem.Parser = (function(){ return r0; } - function parse_params() { - var r0, r1, r2, r3, r4, r5, r6, r7, r8; + function parse_modifiedParam() { + var r0, r1, r2, r3, r4; r1 = pos; - r3 = pos; - r4 = pos; - r5 = parse__(); - if (r5 !== null) { - r6 = parse_param(); - if (r6 !== null) { - r8 = pos; - reportFailures++; - if (input.charCodeAt(pos) === 61) { - r7 = "="; - pos++; - } else { - r7 = null; - if (reportFailures === 0) { - matchFailed("\"=\""); - } - } - reportFailures--; - if (r7 === null) { - r7 = ""; - } else { - r7 = null; - pos = r8; - } - if (r7 !== null) { - r8 = parse__(); - if (r8 !== null) { - r2 = [r5, r6, r7, r8]; - } else { - r2 = null; - pos = r4; - } - } else { - r2 = null; - pos = r4; - } + r2 = pos; + r3 = parse_param(); + if (r3 !== null) { + r4 = parse_trailingModifier(); + if (r4 !== null) { + r0 = [r3, r4]; } else { - r2 = null; - pos = r4; + r0 = null; + pos = r2; } } else { - r2 = null; - pos = r4; + r0 = null; + pos = r2; } - if (r2 !== null) { - reportedPos = r3; - r2 = (function(param) {return param;})(r6); + if (r0 !== null) { + reportedPos = r1; + r0 = (function(p, m) { + var ret = new String(p); + ret.trailingModifier = m; + return ret; + })(r3, r4); } - if (r2 === null) { - pos = r3; + if (r0 === null) { + pos = r1; } - if (r2 !== null) { - r0 = []; - while (r2 !== null) { - r0.push(r2); - r3 = pos; - r4 = pos; - r5 = parse__(); - if (r5 !== null) { - r6 = parse_param(); - if (r6 !== null) { - r8 = pos; - reportFailures++; - if (input.charCodeAt(pos) === 61) { - r7 = "="; - pos++; - } else { - r7 = null; - if (reportFailures === 0) { - matchFailed("\"=\""); - } - } - reportFailures--; - if (r7 === null) { - r7 = ""; - } else { - r7 = null; - pos = r8; - } - if (r7 !== null) { - r8 = parse__(); - if (r8 !== null) { - r2 = [r5, r6, r7, r8]; - } else { - r2 = null; - pos = r4; - } - } else { - r2 = null; - pos = r4; - } - } else { - r2 = null; - pos = r4; - } - } else { - r2 = null; - pos = r4; - } - if (r2 !== null) { - reportedPos = r3; - r2 = (function(param) {return param;})(r6); - } - if (r2 === null) { - pos = r3; - } + return r0; + } + + function parse_inMustacheParam() { + var r0, r1, r2, r3, r4; + + r1 = pos; + r2 = pos; + r3 = parse__(); + if (r3 !== null) { + r4 = parse_param(); + if (r4 !== null) { + r0 = [r3, r4]; + } else { + r0 = null; + pos = r2; } } else { r0 = null; + pos = r2; } if (r0 !== null) { reportedPos = r1; - r0 = (function(p) { return p; })(r0); + r0 = (function(p) { return p; })(r4); } if (r0 === null) { pos = r1; @@ -718,23 +847,38 @@ Emblem.Parser = (function(){ return r0; } - function parse_param() { + function parse_trailingModifier() { + var r0; + + if (/^[!?*\^]/.test(input.charAt(pos))) { + r0 = input.charAt(pos); + pos++; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("[!?*\\^]"); + } + } + return r0; + } + + function parse_hash() { var r0, r1, r2; r1 = pos; - r2 = parse_paramChar(); + r2 = parse_hashSegment(); if (r2 !== null) { r0 = []; while (r2 !== null) { r0.push(r2); - r2 = parse_paramChar(); + r2 = parse_hashSegment(); } } else { r0 = null; } if (r0 !== null) { reportedPos = r1; - r0 = (function(p) { return p.join(''); })(r0); + r0 = (function(h) { return new Handlebars.AST.HashNode(h); })(r0); } if (r0 === null) { pos = r1; @@ -742,56 +886,107 @@ Emblem.Parser = (function(){ return r0; } - function parse_paramChar() { - var r0; + function parse_pathIdent() { + var r0, r1, r2, r3, r4, r5; - r0 = parse_alpha(); + if (input.substr(pos, 2) === "..") { + r0 = ".."; + pos += 2; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"..\""); + } + } if (r0 === null) { - if (input.charCodeAt(pos) === 95) { - r0 = "_"; + if (input.charCodeAt(pos) === 46) { + r0 = "."; pos++; } else { r0 = null; if (reportFailures === 0) { - matchFailed("\"_\""); + matchFailed("\".\""); } } if (r0 === null) { - if (input.charCodeAt(pos) === 45) { - r0 = "-"; + r1 = pos; + r2 = pos; + if (/^[a-zA-Z0-9_$\-]/.test(input.charAt(pos))) { + r4 = input.charAt(pos); pos++; } else { - r0 = null; + r4 = null; if (reportFailures === 0) { - matchFailed("\"-\""); + matchFailed("[a-zA-Z0-9_$\\-]"); } } - if (r0 === null) { - if (input.charCodeAt(pos) === 46) { - r0 = "."; + if (r4 !== null) { + r3 = []; + while (r4 !== null) { + r3.push(r4); + if (/^[a-zA-Z0-9_$\-]/.test(input.charAt(pos))) { + r4 = input.charAt(pos); + pos++; + } else { + r4 = null; + if (reportFailures === 0) { + matchFailed("[a-zA-Z0-9_$\\-]"); + } + } + } + } else { + r3 = null; + } + if (r3 !== null) { + r5 = pos; + reportFailures++; + if (input.charCodeAt(pos) === 61) { + r4 = "="; pos++; } else { - r0 = null; + r4 = null; if (reportFailures === 0) { - matchFailed("\".\""); + matchFailed("\"=\""); } } + reportFailures--; + if (r4 === null) { + r4 = ""; + } else { + r4 = null; + pos = r5; + } + if (r4 !== null) { + r0 = [r3, r4]; + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(s) { return s.join(''); })(r3); + } + if (r0 === null) { + pos = r1; } } } return r0; } - function parse_hash() { - var r0, r1, r2, r3, r4, r5, r6, r7, r8, r9; + function parse_hashSegment() { + var r0, r1, r2, r3, r4, r5, r6, r7, r8; r1 = pos; - r0 = []; - r3 = pos; - r4 = pos; - r5 = parse__(); - if (r5 !== null) { - r6 = parse_param(); + r2 = pos; + r3 = parse__(); + if (r3 !== null) { + r5 = pos; + r6 = parse_ident(); if (r6 !== null) { if (input.charCodeAt(pos) === 61) { r7 = "="; @@ -803,45 +998,24 @@ Emblem.Parser = (function(){ } } if (r7 !== null) { - r8 = parse_hashValue(); + r8 = parse_pathIdNode(); if (r8 !== null) { - r9 = parse__(); - if (r9 !== null) { - r2 = [r5, r6, r7, r8, r9]; - } else { - r2 = null; - pos = r4; - } + r4 = [r6, r7, r8]; } else { - r2 = null; - pos = r4; + r4 = null; + pos = r5; } } else { - r2 = null; - pos = r4; + r4 = null; + pos = r5; } } else { - r2 = null; - pos = r4; + r4 = null; + pos = r5; } - } else { - r2 = null; - pos = r4; - } - if (r2 !== null) { - reportedPos = r3; - r2 = (function(k, v) { return { key: k, value: v }; })(r6, r8); - } - if (r2 === null) { - pos = r3; - } - while (r2 !== null) { - r0.push(r2); - r3 = pos; - r4 = pos; - r5 = parse__(); - if (r5 !== null) { - r6 = parse_param(); + if (r4 === null) { + r5 = pos; + r6 = parse_ident(); if (r6 !== null) { if (input.charCodeAt(pos) === 61) { r7 = "="; @@ -853,67 +1027,299 @@ Emblem.Parser = (function(){ } } if (r7 !== null) { - r8 = parse_hashValue(); + r8 = parse_stringNode(); if (r8 !== null) { - r9 = parse__(); - if (r9 !== null) { - r2 = [r5, r6, r7, r8, r9]; - } else { - r2 = null; - pos = r4; - } + r4 = [r6, r7, r8]; } else { - r2 = null; - pos = r4; + r4 = null; + pos = r5; } } else { - r2 = null; - pos = r4; + r4 = null; + pos = r5; } } else { - r2 = null; - pos = r4; + r4 = null; + pos = r5; } - } else { - r2 = null; - pos = r4; - } - if (r2 !== null) { - reportedPos = r3; - r2 = (function(k, v) { return { key: k, value: v }; })(r6, r8); - } - if (r2 === null) { - pos = r3; - } - } - if (r0 !== null) { - reportedPos = r1; - r0 = (function(h) { - var ret = {}; - for(var i = 0; i < h.length; ++i) { - var pair = h[i]; - ret[pair.key] = pair.value; - } - return ret; - })(r0); - } - if (r0 === null) { - pos = r1; - } - return r0; - } - - function parse_hashValue() { - var r0; - - r0 = parse_string(); - if (r0 === null) { - r0 = parse_param(); - if (r0 === null) { - r0 = parse_integer(); - } - } - return r0; + if (r4 === null) { + r5 = pos; + r6 = parse_ident(); + if (r6 !== null) { + if (input.charCodeAt(pos) === 61) { + r7 = "="; + pos++; + } else { + r7 = null; + if (reportFailures === 0) { + matchFailed("\"=\""); + } + } + if (r7 !== null) { + r8 = parse_integerNode(); + if (r8 !== null) { + r4 = [r6, r7, r8]; + } else { + r4 = null; + pos = r5; + } + } else { + r4 = null; + pos = r5; + } + } else { + r4 = null; + pos = r5; + } + if (r4 === null) { + r5 = pos; + r6 = parse_ident(); + if (r6 !== null) { + if (input.charCodeAt(pos) === 61) { + r7 = "="; + pos++; + } else { + r7 = null; + if (reportFailures === 0) { + matchFailed("\"=\""); + } + } + if (r7 !== null) { + r8 = parse_booleanNode(); + if (r8 !== null) { + r4 = [r6, r7, r8]; + } else { + r4 = null; + pos = r5; + } + } else { + r4 = null; + pos = r5; + } + } else { + r4 = null; + pos = r5; + } + } + } + } + if (r4 !== null) { + r0 = [r3, r4]; + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(h) { return [h[0], h[2]]; })(r4); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_param() { + var r0; + + r0 = parse_pathIdNode(); + if (r0 === null) { + r0 = parse_stringNode(); + if (r0 === null) { + r0 = parse_integerNode(); + if (r0 === null) { + r0 = parse_booleanNode(); + } + } + } + return r0; + } + + function parse_path() { + var r0, r1, r2, r3, r4, r5, r6, r7, r8, r9; + + r1 = pos; + r2 = pos; + r3 = parse_pathIdent(); + if (r3 !== null) { + r4 = []; + r6 = pos; + r7 = pos; + r8 = parse_seperator(); + if (r8 !== null) { + r9 = parse_pathIdent(); + if (r9 !== null) { + r5 = [r8, r9]; + } else { + r5 = null; + pos = r7; + } + } else { + r5 = null; + pos = r7; + } + if (r5 !== null) { + reportedPos = r6; + r5 = (function(p) { return p; })(r9); + } + if (r5 === null) { + pos = r6; + } + while (r5 !== null) { + r4.push(r5); + r6 = pos; + r7 = pos; + r8 = parse_seperator(); + if (r8 !== null) { + r9 = parse_pathIdent(); + if (r9 !== null) { + r5 = [r8, r9]; + } else { + r5 = null; + pos = r7; + } + } else { + r5 = null; + pos = r7; + } + if (r5 !== null) { + reportedPos = r6; + r5 = (function(p) { return p; })(r9); + } + if (r5 === null) { + pos = r6; + } + } + if (r4 !== null) { + r0 = [r3, r4]; + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(first, tail) { + var ret = [first]; + for(var i = 0; i < tail.length; ++i) { + //ret = ret.concat(tail[i]); + ret.push(tail[i]); + } + return ret; + })(r3, r4); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_seperator() { + var r0; + + if (/^[\/.]/.test(input.charAt(pos))) { + r0 = input.charAt(pos); + pos++; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("[\\/.]"); + } + } + return r0; + } + + function parse_pathIdNode() { + var r0, r1; + + r1 = pos; + r0 = parse_path(); + if (r0 !== null) { + reportedPos = r1; + r0 = (function(v) { return new Handlebars.AST.IdNode(v); })(r0); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_stringNode() { + var r0, r1; + + r1 = pos; + r0 = parse_string(); + if (r0 !== null) { + reportedPos = r1; + r0 = (function(v) { return new Handlebars.AST.StringNode(v); })(r0); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_integerNode() { + var r0, r1; + + r1 = pos; + r0 = parse_integer(); + if (r0 !== null) { + reportedPos = r1; + r0 = (function(v) { return new Handlebars.AST.IntegerNode(v); })(r0); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_booleanNode() { + var r0, r1; + + r1 = pos; + r0 = parse_boolean(); + if (r0 !== null) { + reportedPos = r1; + r0 = (function(v) { return new Handlebars.AST.BooleanNode(v); })(r0); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_boolean() { + var r0; + + if (input.substr(pos, 4) === "true") { + r0 = "true"; + pos += 4; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"true\""); + } + } + if (r0 === null) { + if (input.substr(pos, 5) === "false") { + r0 = "false"; + pos += 5; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"false\""); + } + } + } + return r0; } function parse_integer() { @@ -1036,7 +1442,7 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(p) { return p.join(''); })(r0); + r0 = (function(p) { return p[1]; })(r0); } if (r0 === null) { pos = r1; @@ -1135,7 +1541,7 @@ Emblem.Parser = (function(){ var r0, r1; r1 = pos; - r0 = parse_forcedMustache(); + r0 = parse_explicitMustache(); if (r0 !== null) { reportedPos = r1; r0 = (function(m) { return [m]; })(r0); @@ -1150,7 +1556,7 @@ Emblem.Parser = (function(){ } function parse_textLine() { - var r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17; + var r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12; r1 = pos; r2 = pos; @@ -1177,176 +1583,68 @@ Emblem.Parser = (function(){ if (r4 !== null) { r5 = parse_textNodes(); if (r5 !== null) { - r6 = parse_TERM(); - if (r6 !== null) { - r7 = []; - r9 = pos; - r10 = pos; - r11 = parse_INDENT(); + r6 = []; + r8 = pos; + r9 = pos; + r10 = parse_INDENT(); + if (r10 !== null) { + r11 = parse_textNodes(); if (r11 !== null) { - r14 = pos; - r15 = pos; - r16 = parse_textNodes(); - if (r16 !== null) { - r17 = parse_TERM(); - if (r17 !== null) { - r13 = [r16, r17]; - } else { - r13 = null; - pos = r15; - } - } else { - r13 = null; - pos = r15; - } - if (r13 !== null) { - reportedPos = r14; - r13 = (function(n) { return n;})(r16); - } - if (r13 === null) { - pos = r14; - } - if (r13 !== null) { - r12 = []; - while (r13 !== null) { - r12.push(r13); - r14 = pos; - r15 = pos; - r16 = parse_textNodes(); - if (r16 !== null) { - r17 = parse_TERM(); - if (r17 !== null) { - r13 = [r16, r17]; - } else { - r13 = null; - pos = r15; - } - } else { - r13 = null; - pos = r15; - } - if (r13 !== null) { - reportedPos = r14; - r13 = (function(n) { return n;})(r16); - } - if (r13 === null) { - pos = r14; - } - } - } else { - r12 = null; - } + r12 = parse_DEDENT(); if (r12 !== null) { - r13 = parse_DEDENT(); - if (r13 !== null) { - r8 = [r11, r12, r13]; - } else { - r8 = null; - pos = r10; - } + r7 = [r10, r11, r12]; } else { - r8 = null; - pos = r10; + r7 = null; + pos = r9; } } else { - r8 = null; - pos = r10; - } - if (r8 !== null) { - reportedPos = r9; - r8 = (function(n) { return n; })(r12); - } - if (r8 === null) { + r7 = null; pos = r9; } - while (r8 !== null) { - r7.push(r8); - r9 = pos; - r10 = pos; - r11 = parse_INDENT(); + } else { + r7 = null; + pos = r9; + } + if (r7 !== null) { + reportedPos = r8; + r7 = (function(t) { return t; })(r11); + } + if (r7 === null) { + pos = r8; + } + while (r7 !== null) { + r6.push(r7); + r8 = pos; + r9 = pos; + r10 = parse_INDENT(); + if (r10 !== null) { + r11 = parse_textNodes(); if (r11 !== null) { - r14 = pos; - r15 = pos; - r16 = parse_textNodes(); - if (r16 !== null) { - r17 = parse_TERM(); - if (r17 !== null) { - r13 = [r16, r17]; - } else { - r13 = null; - pos = r15; - } - } else { - r13 = null; - pos = r15; - } - if (r13 !== null) { - reportedPos = r14; - r13 = (function(n) { return n;})(r16); - } - if (r13 === null) { - pos = r14; - } - if (r13 !== null) { - r12 = []; - while (r13 !== null) { - r12.push(r13); - r14 = pos; - r15 = pos; - r16 = parse_textNodes(); - if (r16 !== null) { - r17 = parse_TERM(); - if (r17 !== null) { - r13 = [r16, r17]; - } else { - r13 = null; - pos = r15; - } - } else { - r13 = null; - pos = r15; - } - if (r13 !== null) { - reportedPos = r14; - r13 = (function(n) { return n;})(r16); - } - if (r13 === null) { - pos = r14; - } - } - } else { - r12 = null; - } + r12 = parse_DEDENT(); if (r12 !== null) { - r13 = parse_DEDENT(); - if (r13 !== null) { - r8 = [r11, r12, r13]; - } else { - r8 = null; - pos = r10; - } + r7 = [r10, r11, r12]; } else { - r8 = null; - pos = r10; + r7 = null; + pos = r9; } } else { - r8 = null; - pos = r10; - } - if (r8 !== null) { - reportedPos = r9; - r8 = (function(n) { return n; })(r12); - } - if (r8 === null) { + r7 = null; pos = r9; } - } - if (r7 !== null) { - r0 = [r3, r4, r5, r6, r7]; } else { - r0 = null; - pos = r2; + r7 = null; + pos = r9; } + if (r7 !== null) { + reportedPos = r8; + r7 = (function(t) { return t; })(r11); + } + if (r7 === null) { + pos = r8; + } + } + if (r6 !== null) { + r0 = [r3, r4, r5, r6]; } else { r0 = null; pos = r2; @@ -1366,11 +1664,11 @@ Emblem.Parser = (function(){ if (r0 !== null) { reportedPos = r1; r0 = (function(nodes, indentedNodes) { - if(indentedNodes.length) { - nodes = nodes.concat(indentedNodes[0][0]); + for(var i = 0; i < indentedNodes.length; ++i) { + nodes = nodes.concat(indentedNodes[i]); } return nodes; - })(r5, r7); + })(r5, r6); } if (r0 === null) { pos = r1; @@ -1421,7 +1719,13 @@ Emblem.Parser = (function(){ } } if (r4 !== null) { - r0 = [r3, r4]; + r5 = parse_TERM(); + if (r5 !== null) { + r0 = [r3, r4, r5]; + } else { + r0 = null; + pos = r2; + } } else { r0 = null; pos = r2; @@ -1452,43 +1756,119 @@ Emblem.Parser = (function(){ function parse_rawMustache() { var r0; - r0 = parse_rawMustacheEscaped(); + r0 = parse_rawMustacheUnescaped(); if (r0 === null) { - r0 = parse_rawMustacheUnescaped(); + r0 = parse_rawMustacheEscaped(); } return r0; } - function parse_rawMustacheUnescaped() { + function parse_rawMustacheSingle() { var r0, r1, r2, r3, r4, r5, r6, r7; r1 = pos; r2 = pos; - if (input.substr(pos, 2) === "{{") { - r3 = "{{"; - pos += 2; - } else { - r3 = null; - if (reportFailures === 0) { - matchFailed("\"{{\""); + r3 = parse_singleOpen(); + if (r3 !== null) { + r4 = parse__(); + if (r4 !== null) { + r5 = parse_inMustache(); + if (r5 !== null) { + r6 = parse__(); + if (r6 !== null) { + r7 = parse_singleClose(); + if (r7 !== null) { + r0 = [r3, r4, r5, r6, r7]; + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; } + } else { + r0 = null; + pos = r2; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(m) { m.escaped = true; return m; })(r5); } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_rawMustacheEscaped() { + var r0, r1, r2, r3, r4, r5, r6, r7; + + r1 = pos; + r2 = pos; + r3 = parse_doubleOpen(); if (r3 !== null) { r4 = parse__(); if (r4 !== null) { - r5 = parse_mustacheContent(); + r5 = parse_inMustache(); if (r5 !== null) { r6 = parse__(); if (r6 !== null) { - if (input.substr(pos, 2) === "}}") { - r7 = "}}"; - pos += 2; + r7 = parse_doubleClose(); + if (r7 !== null) { + r0 = [r3, r4, r5, r6, r7]; } else { - r7 = null; - if (reportFailures === 0) { - matchFailed("\"}}\""); - } + r0 = null; + pos = r2; } + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(m) { m.escaped = true; return m; })(r5); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_rawMustacheUnescaped() { + var r0, r1, r2, r3, r4, r5, r6, r7; + + r1 = pos; + r2 = pos; + r3 = parse_tripleOpen(); + if (r3 !== null) { + r4 = parse__(); + if (r4 !== null) { + r5 = parse_inMustache(); + if (r5 !== null) { + r6 = parse__(); + if (r6 !== null) { + r7 = parse_tripleClose(); if (r7 !== null) { r0 = [r3, r4, r5, r6, r7]; } else { @@ -1513,7 +1893,409 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(m) { m.forced = true; return m; })(r5); + r0 = (function(m) { m.escaped = false; return m; })(r5); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_preMustacheText() { + var r0, r1, r2; + + r1 = pos; + if (/^[^{\uEFFF]/.test(input.charAt(pos))) { + r2 = input.charAt(pos); + pos++; + } else { + r2 = null; + if (reportFailures === 0) { + matchFailed("[^{\\uEFFF]"); + } + } + if (r2 !== null) { + r0 = []; + while (r2 !== null) { + r0.push(r2); + if (/^[^{\uEFFF]/.test(input.charAt(pos))) { + r2 = input.charAt(pos); + pos++; + } else { + r2 = null; + if (reportFailures === 0) { + matchFailed("[^{\\uEFFF]"); + } + } + } + } else { + r0 = null; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(a) { return new Handlebars.AST.ContentNode(a.join('')); })(r0); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_inTagMustache() { + var r0; + + r0 = parse_rawMustacheSingle(); + if (r0 === null) { + r0 = parse_rawMustacheUnescaped(); + if (r0 === null) { + r0 = parse_rawMustacheEscaped(); + } + } + return r0; + } + + function parse_singleOpen() { + var r0; + + if (input.charCodeAt(pos) === 123) { + r0 = "{"; + pos++; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"{\""); + } + } + return r0; + } + + function parse_doubleOpen() { + var r0; + + if (input.substr(pos, 2) === "{{") { + r0 = "{{"; + pos += 2; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"{{\""); + } + } + return r0; + } + + function parse_tripleOpen() { + var r0; + + if (input.substr(pos, 3) === "{{{") { + r0 = "{{{"; + pos += 3; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"{{{\""); + } + } + return r0; + } + + function parse_singleClose() { + var r0; + + if (input.charCodeAt(pos) === 125) { + r0 = "}"; + pos++; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"}\""); + } + } + return r0; + } + + function parse_doubleClose() { + var r0; + + if (input.substr(pos, 2) === "}}") { + r0 = "}}"; + pos += 2; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"}}\""); + } + } + return r0; + } + + function parse_tripleClose() { + var r0; + + if (input.substr(pos, 3) === "}}}") { + r0 = "}}}"; + pos += 3; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"}}}\""); + } + } + return r0; + } + + function parse_equalSign() { + var r0, r1, r2, r3, r4; + + r1 = pos; + r2 = pos; + if (input.substr(pos, 2) === "==") { + r3 = "=="; + pos += 2; + } else { + r3 = null; + if (reportFailures === 0) { + matchFailed("\"==\""); + } + } + if (r3 !== null) { + if (input.charCodeAt(pos) === 32) { + r4 = " "; + pos++; + } else { + r4 = null; + if (reportFailures === 0) { + matchFailed("\" \""); + } + } + r4 = r4 !== null ? r4 : ""; + if (r4 !== null) { + r0 = [r3, r4]; + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function() { return false; })(); + } + if (r0 === null) { + pos = r1; + } + if (r0 === null) { + r1 = pos; + r2 = pos; + if (input.charCodeAt(pos) === 61) { + r3 = "="; + pos++; + } else { + r3 = null; + if (reportFailures === 0) { + matchFailed("\"=\""); + } + } + if (r3 !== null) { + if (input.charCodeAt(pos) === 32) { + r4 = " "; + pos++; + } else { + r4 = null; + if (reportFailures === 0) { + matchFailed("\" \""); + } + } + r4 = r4 !== null ? r4 : ""; + if (r4 !== null) { + r0 = [r3, r4]; + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function() { return true; })(); + } + if (r0 === null) { + pos = r1; + } + } + return r0; + } + + function parse_htmlTagAndOptionalAttributes() { + var r0, r1, r2, r3, r4, r5, r6, r7, r8; + + r1 = pos; + r2 = pos; + r3 = pos; + r4 = parse_htmlTagName(); + if (r4 !== null) { + r5 = parse_shorthandAttributes(); + r5 = r5 !== null ? r5 : ""; + if (r5 !== null) { + r6 = []; + r7 = parse_inTagMustache(); + while (r7 !== null) { + r6.push(r7); + r7 = parse_inTagMustache(); + } + if (r6 !== null) { + r7 = []; + r8 = parse_fullAttribute(); + while (r8 !== null) { + r7.push(r8); + r8 = parse_fullAttribute(); + } + if (r7 !== null) { + r0 = [r4, r5, r6, r7]; + } else { + r0 = null; + pos = r3; + } + } else { + r0 = null; + pos = r3; + } + } else { + r0 = null; + pos = r3; + } + } else { + r0 = null; + pos = r3; + } + if (r0 !== null) { + reportedPos = r2; + r0 = (function(h, s, m, f) { return [h, s, m, f]; })(r4, r5, r6, r7); + } + if (r0 === null) { + pos = r2; + } + if (r0 === null) { + r2 = pos; + r3 = pos; + r4 = parse_shorthandAttributes(); + if (r4 !== null) { + r5 = []; + r6 = parse_inTagMustache(); + while (r6 !== null) { + r5.push(r6); + r6 = parse_inTagMustache(); + } + if (r5 !== null) { + r6 = []; + r7 = parse_fullAttribute(); + while (r7 !== null) { + r6.push(r7); + r7 = parse_fullAttribute(); + } + if (r6 !== null) { + r0 = [r4, r5, r6]; + } else { + r0 = null; + pos = r3; + } + } else { + r0 = null; + pos = r3; + } + } else { + r0 = null; + pos = r3; + } + if (r0 !== null) { + reportedPos = r2; + r0 = (function(s, m, f) { return [null, s, m, f] })(r4, r5, r6); + } + if (r0 === null) { + pos = r2; + } + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(h) { + var tagName = h[0] || 'div', + shorthandAttributes = h[1] || [], + inTagMustaches = h[2], + fullAttributes = h[3], + id = shorthandAttributes[0], + classes = shorthandAttributes[1]; + + var tagOpenContent = []; + tagOpenContent.push(new Handlebars.AST.ContentNode('<' + tagName)); + + if(id) { + tagOpenContent.push(new Handlebars.AST.ContentNode(' id="' + id + '"')); + } + + if(classes && classes.length) { + tagOpenContent.push(new Handlebars.AST.ContentNode(' class="' + classes.join(' ') + '"')); + } + + // Pad in tag mustaches with spaces. + for(var i = 0; i < inTagMustaches.length; ++i) { + tagOpenContent.push(new Handlebars.AST.ContentNode(' ')); + tagOpenContent.push(inTagMustaches[i]); + } + + for(var i = 0; i < fullAttributes.length; ++i) { + tagOpenContent = tagOpenContent.concat(fullAttributes[i]); + } + tagOpenContent.push(new Handlebars.AST.ContentNode('>')); + + return [tagOpenContent, new Handlebars.AST.ContentNode('')]; + })(r0); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_shorthandAttributes() { + var r0; + + r0 = parse_attributesAtLeastID(); + if (r0 === null) { + r0 = parse_attributesAtLeastClass(); + } + return r0; + } + + function parse_attributesAtLeastID() { + var r0, r1, r2, r3, r4, r5; + + r1 = pos; + r2 = pos; + r3 = parse_idShorthand(); + if (r3 !== null) { + r4 = []; + r5 = parse_classShorthand(); + while (r5 !== null) { + r4.push(r5); + r5 = parse_classShorthand(); + } + if (r4 !== null) { + r0 = [r3, r4]; + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(id, classes) { return [id, classes]; })(r3, r4); } if (r0 === null) { pos = r1; @@ -1521,50 +2303,71 @@ Emblem.Parser = (function(){ return r0; } - function parse_rawMustacheEscaped() { - var r0, r1, r2, r3, r4, r5, r6, r7; + function parse_attributesAtLeastClass() { + var r0, r1, r2; + + r1 = pos; + r2 = parse_classShorthand(); + if (r2 !== null) { + r0 = []; + while (r2 !== null) { + r0.push(r2); + r2 = parse_classShorthand(); + } + } else { + r0 = null; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(classes) { return [null, classes]; })(r0); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_fullAttribute() { + var r0, r1, r2, r3, r4; r1 = pos; r2 = pos; - if (input.substr(pos, 3) === "{{{") { - r3 = "{{{"; - pos += 3; + if (input.charCodeAt(pos) === 32) { + r4 = " "; + pos++; } else { - r3 = null; + r4 = null; if (reportFailures === 0) { - matchFailed("\"{{{\""); + matchFailed("\" \""); } } - if (r3 !== null) { - r4 = parse__(); - if (r4 !== null) { - r5 = parse_mustacheContent(); - if (r5 !== null) { - r6 = parse__(); - if (r6 !== null) { - if (input.substr(pos, 3) === "}}}") { - r7 = "}}}"; - pos += 3; - } else { - r7 = null; - if (reportFailures === 0) { - matchFailed("\"}}}\""); - } - } - if (r7 !== null) { - r0 = [r3, r4, r5, r6, r7]; - } else { - r0 = null; - pos = r2; - } - } else { - r0 = null; - pos = r2; - } + if (r4 !== null) { + r3 = []; + while (r4 !== null) { + r3.push(r4); + if (input.charCodeAt(pos) === 32) { + r4 = " "; + pos++; } else { - r0 = null; - pos = r2; + r4 = null; + if (reportFailures === 0) { + matchFailed("\" \""); + } + } + } + } else { + r3 = null; + } + if (r3 !== null) { + r4 = parse_actionAttribute(); + if (r4 === null) { + r4 = parse_boundAttribute(); + if (r4 === null) { + r4 = parse_normalAttribute(); } + } + if (r4 !== null) { + r0 = [r3, r4]; } else { r0 = null; pos = r2; @@ -1575,7 +2378,9 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(m) { m.forced = true; m.escaped = true; return m; })(r5); + r0 = (function(a) { + return [new Handlebars.AST.ContentNode(' '), a]; + })(r4); } if (r0 === null) { pos = r1; @@ -1583,30 +2388,30 @@ Emblem.Parser = (function(){ return r0; } - function parse_preMustacheText() { + function parse_boundAttributeValueText() { var r0, r1, r2; r1 = pos; - if (/^[^{\uEFFF]/.test(input.charAt(pos))) { + if (/^[A-Za-z.:0-9]/.test(input.charAt(pos))) { r2 = input.charAt(pos); pos++; } else { r2 = null; if (reportFailures === 0) { - matchFailed("[^{\\uEFFF]"); + matchFailed("[A-Za-z.:0-9]"); } } if (r2 !== null) { r0 = []; while (r2 !== null) { r0.push(r2); - if (/^[^{\uEFFF]/.test(input.charAt(pos))) { + if (/^[A-Za-z.:0-9]/.test(input.charAt(pos))) { r2 = input.charAt(pos); pos++; } else { r2 = null; if (reportFailures === 0) { - matchFailed("[^{\\uEFFF]"); + matchFailed("[A-Za-z.:0-9]"); } } } @@ -1615,7 +2420,7 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(a) { return a.join(''); })(r0); + r0 = (function(s) { return s.join(''); })(r0); } if (r0 === null) { pos = r1; @@ -1623,24 +2428,56 @@ Emblem.Parser = (function(){ return r0; } - function parse_equalSign() { - var r0, r1, r2, r3, r4; + function parse_actionValue() { + var r0, r1; + + r0 = parse_quotedActionValue(); + if (r0 === null) { + r1 = pos; + r0 = parse_pathIdNode(); + if (r0 !== null) { + reportedPos = r1; + r0 = (function(id) { return new Handlebars.AST.MustacheNode([id]); })(r0); + } + if (r0 === null) { + pos = r1; + } + } + return r0; + } + + function parse_quotedActionValue() { + var r0, r1, r2, r3, r4, r5; r1 = pos; r2 = pos; - if (input.substr(pos, 2) === "==") { - r3 = "=="; - pos += 2; + if (input.charCodeAt(pos) === 34) { + r3 = "\""; + pos++; } else { r3 = null; if (reportFailures === 0) { - matchFailed("\"==\""); + matchFailed("\"\\\"\""); } } if (r3 !== null) { - r4 = parse__(); + r4 = parse_inMustache(); if (r4 !== null) { - r0 = [r3, r4]; + if (input.charCodeAt(pos) === 34) { + r5 = "\""; + pos++; + } else { + r5 = null; + if (reportFailures === 0) { + matchFailed("\"\\\"\""); + } + } + if (r5 !== null) { + r0 = [r3, r4, r5]; + } else { + r0 = null; + pos = r2; + } } else { r0 = null; pos = r2; @@ -1649,29 +2486,35 @@ Emblem.Parser = (function(){ r0 = null; pos = r2; } - if (r0 !== null) { - reportedPos = r1; - r0 = (function() { return true; })(); - } if (r0 === null) { - pos = r1; - } - if (r0 === null) { - r1 = pos; r2 = pos; - if (input.charCodeAt(pos) === 61) { - r3 = "="; + if (input.charCodeAt(pos) === 39) { + r3 = "'"; pos++; } else { r3 = null; if (reportFailures === 0) { - matchFailed("\"=\""); + matchFailed("\"'\""); } } if (r3 !== null) { - r4 = parse__(); + r4 = parse_inMustache(); if (r4 !== null) { - r0 = [r3, r4]; + if (input.charCodeAt(pos) === 39) { + r5 = "'"; + pos++; + } else { + r5 = null; + if (reportFailures === 0) { + matchFailed("\"'\""); + } + } + if (r5 !== null) { + r0 = [r3, r4, r5]; + } else { + r0 = null; + pos = r2; + } } else { r0 = null; pos = r2; @@ -1680,28 +2523,41 @@ Emblem.Parser = (function(){ r0 = null; pos = r2; } - if (r0 !== null) { - reportedPos = r1; - r0 = (function() { return false; })(); - } - if (r0 === null) { - pos = r1; - } + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(p) { return p[1]; })(r0); + } + if (r0 === null) { + pos = r1; } return r0; } - function parse_htmlTag() { - var r0, r1, r2, r3, r4; + function parse_actionAttribute() { + var r0, r1, r2, r3, r4, r5; r1 = pos; r2 = pos; - r3 = parse_htmlTagName(); + r3 = parse_knownEvent(); if (r3 !== null) { - r4 = parse_attrShortcuts(); - r4 = r4 !== null ? r4 : ""; + if (input.charCodeAt(pos) === 61) { + r4 = "="; + pos++; + } else { + r4 = null; + if (reportFailures === 0) { + matchFailed("\"=\""); + } + } if (r4 !== null) { - r0 = [r3, r4]; + r5 = parse_actionValue(); + if (r5 !== null) { + r0 = [r3, r4, r5]; + } else { + r0 = null; + pos = r2; + } } else { r0 = null; pos = r2; @@ -1712,40 +2568,88 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(h, t) { return { type: 'html', tagName: h, attrs:(t||{}) }; })(r3, r4); + r0 = (function(event, mustacheNode) { + // Unshift the action helper and augment the hash + return unshiftParam(mustacheNode, 'action', [['on', new Handlebars.AST.StringNode(event)]]); + })(r3, r5); } if (r0 === null) { pos = r1; } - if (r0 === null) { - r1 = pos; - r0 = parse_attrShortcuts(); - if (r0 !== null) { - reportedPos = r1; - r0 = (function(t) { return { type: 'html', tagName: null, attrs: t }; })(r0); + return r0; + } + + function parse_boundAttribute() { + var r0, r1, r2, r3, r4, r5; + + r1 = pos; + r2 = pos; + r3 = parse_ident(); + if (r3 !== null) { + if (input.charCodeAt(pos) === 61) { + r4 = "="; + pos++; + } else { + r4 = null; + if (reportFailures === 0) { + matchFailed("\"=\""); + } } - if (r0 === null) { - pos = r1; + if (r4 !== null) { + r5 = parse_boundAttributeValueText(); + if (r5 !== null) { + r0 = [r3, r4, r5]; + } else { + r0 = null; + pos = r2; + } + } else { + r0 = null; + pos = r2; } + } else { + r0 = null; + pos = r2; + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(key, value) { + var hashNode = new Handlebars.AST.HashNode([[key, new Handlebars.AST.StringNode(value)]]); + var params = [new Handlebars.AST.IdNode(['bindAttr'])]; + + return new Handlebars.AST.MustacheNode(params, hashNode); + })(r3, r5); + } + if (r0 === null) { + pos = r1; } return r0; } - function parse_attrShortcuts() { + function parse_normalAttribute() { var r0, r1, r2, r3, r4, r5; r1 = pos; r2 = pos; - r3 = parse_idShortcut(); + r3 = parse_ident(); if (r3 !== null) { - r4 = []; - r5 = parse_classShortcut(); - while (r5 !== null) { - r4.push(r5); - r5 = parse_classShortcut(); + if (input.charCodeAt(pos) === 61) { + r4 = "="; + pos++; + } else { + r4 = null; + if (reportFailures === 0) { + matchFailed("\"=\""); + } } if (r4 !== null) { - r0 = [r3, r4]; + r5 = parse_string(); + if (r5 !== null) { + r0 = [r3, r4, r5]; + } else { + r0 = null; + pos = r2; + } } else { r0 = null; pos = r2; @@ -1756,45 +2660,88 @@ Emblem.Parser = (function(){ } if (r0 !== null) { reportedPos = r1; - r0 = (function(id, classes) { - var ret = { id: id }; - var classString = classes.join(' '); - if(classString) { - ret['class'] = classString; - } - return ret; - })(r3, r4); + r0 = (function(key, value) { + var s = key + '=' + '"' + value + '"'; + return new Handlebars.AST.ContentNode(s); + })(r3, r5); + } + if (r0 === null) { + pos = r1; + } + return r0; + } + + function parse_attributeName() { + var r0, r1, r2; + + r1 = pos; + r0 = []; + r2 = parse_attributeChar(); + while (r2 !== null) { + r0.push(r2); + r2 = parse_attributeChar(); + } + if (r0 !== null) { + reportedPos = r1; + r0 = (function(a) { return a.join(''); })(r0); } if (r0 === null) { pos = r1; } + return r0; + } + + function parse_attributeValue() { + var r0; + + r0 = parse_string(); if (r0 === null) { - r1 = pos; - r2 = parse_classShortcut(); - if (r2 !== null) { - r0 = []; - while (r2 !== null) { - r0.push(r2); - r2 = parse_classShortcut(); - } + r0 = parse_param(); + } + return r0; + } + + function parse_attributeChar() { + var r0; + + r0 = parse_alpha(); + if (r0 === null) { + if (/^[0-9]/.test(input.charAt(pos))) { + r0 = input.charAt(pos); + pos++; } else { r0 = null; - } - if (r0 !== null) { - reportedPos = r1; - r0 = (function(classes) { - - return { 'class': classes.join(' ') }; - })(r0); + if (reportFailures === 0) { + matchFailed("[0-9]"); + } } if (r0 === null) { - pos = r1; + if (input.charCodeAt(pos) === 95) { + r0 = "_"; + pos++; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"_\""); + } + } + if (r0 === null) { + if (input.charCodeAt(pos) === 45) { + r0 = "-"; + pos++; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"-\""); + } + } + } } } return r0; } - function parse_idShortcut() { + function parse_idShorthand() { var r0, r1, r2, r3, r4; r1 = pos; @@ -1830,7 +2777,7 @@ Emblem.Parser = (function(){ return r0; } - function parse_classShortcut() { + function parse_classShorthand() { var r0, r1, r2, r3, r4; r1 = pos; @@ -3400,6 +4347,312 @@ Emblem.Parser = (function(){ return r0; } + function parse_knownEvent() { + var r0; + + reportFailures++; + if (input.substr(pos, 10) === "touchStart") { + r0 = "touchStart"; + pos += 10; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"touchStart\""); + } + } + if (r0 === null) { + if (input.substr(pos, 9) === "touchMove") { + r0 = "touchMove"; + pos += 9; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"touchMove\""); + } + } + if (r0 === null) { + if (input.substr(pos, 8) === "touchEnd") { + r0 = "touchEnd"; + pos += 8; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"touchEnd\""); + } + } + if (r0 === null) { + if (input.substr(pos, 11) === "touchCancel") { + r0 = "touchCancel"; + pos += 11; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"touchCancel\""); + } + } + if (r0 === null) { + if (input.substr(pos, 7) === "keyDown") { + r0 = "keyDown"; + pos += 7; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"keyDown\""); + } + } + if (r0 === null) { + if (input.substr(pos, 5) === "keyUp") { + r0 = "keyUp"; + pos += 5; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"keyUp\""); + } + } + if (r0 === null) { + if (input.substr(pos, 8) === "keyPress") { + r0 = "keyPress"; + pos += 8; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"keyPress\""); + } + } + if (r0 === null) { + if (input.substr(pos, 9) === "mouseDown") { + r0 = "mouseDown"; + pos += 9; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"mouseDown\""); + } + } + if (r0 === null) { + if (input.substr(pos, 7) === "mouseUp") { + r0 = "mouseUp"; + pos += 7; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"mouseUp\""); + } + } + if (r0 === null) { + if (input.substr(pos, 11) === "contextMenu") { + r0 = "contextMenu"; + pos += 11; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"contextMenu\""); + } + } + if (r0 === null) { + if (input.substr(pos, 5) === "click") { + r0 = "click"; + pos += 5; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"click\""); + } + } + if (r0 === null) { + if (input.substr(pos, 11) === "doubleClick") { + r0 = "doubleClick"; + pos += 11; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"doubleClick\""); + } + } + if (r0 === null) { + if (input.substr(pos, 9) === "mouseMove") { + r0 = "mouseMove"; + pos += 9; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"mouseMove\""); + } + } + if (r0 === null) { + if (input.substr(pos, 7) === "focusIn") { + r0 = "focusIn"; + pos += 7; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"focusIn\""); + } + } + if (r0 === null) { + if (input.substr(pos, 8) === "focusOut") { + r0 = "focusOut"; + pos += 8; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"focusOut\""); + } + } + if (r0 === null) { + if (input.substr(pos, 10) === "mouseEnter") { + r0 = "mouseEnter"; + pos += 10; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"mouseEnter\""); + } + } + if (r0 === null) { + if (input.substr(pos, 10) === "mouseLeave") { + r0 = "mouseLeave"; + pos += 10; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"mouseLeave\""); + } + } + if (r0 === null) { + if (input.substr(pos, 6) === "submit") { + r0 = "submit"; + pos += 6; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"submit\""); + } + } + if (r0 === null) { + if (input.substr(pos, 5) === "input") { + r0 = "input"; + pos += 5; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"input\""); + } + } + if (r0 === null) { + if (input.substr(pos, 6) === "change") { + r0 = "change"; + pos += 6; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"change\""); + } + } + if (r0 === null) { + if (input.substr(pos, 9) === "dragStart") { + r0 = "dragStart"; + pos += 9; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"dragStart\""); + } + } + if (r0 === null) { + if (input.substr(pos, 4) === "drag") { + r0 = "drag"; + pos += 4; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"drag\""); + } + } + if (r0 === null) { + if (input.substr(pos, 9) === "dragEnter") { + r0 = "dragEnter"; + pos += 9; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"dragEnter\""); + } + } + if (r0 === null) { + if (input.substr(pos, 9) === "dragLeave") { + r0 = "dragLeave"; + pos += 9; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"dragLeave\""); + } + } + if (r0 === null) { + if (input.substr(pos, 8) === "dragOver") { + r0 = "dragOver"; + pos += 8; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"dragOver\""); + } + } + if (r0 === null) { + if (input.substr(pos, 4) === "drop") { + r0 = "drop"; + pos += 4; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"drop\""); + } + } + if (r0 === null) { + if (input.substr(pos, 7) === "dragEnd") { + r0 = "dragEnd"; + pos += 7; + } else { + r0 = null; + if (reportFailures === 0) { + matchFailed("\"dragEnd\""); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + reportFailures--; + if (reportFailures === 0 && r0 === null) { + matchFailed("a JS event"); + } + return r0; + } + function parse_INDENT() { var r0, r1; @@ -3589,6 +4842,26 @@ Emblem.Parser = (function(){ } + // Returns a new MustacheNode with a new preceding param (id). + function unshiftParam(mustacheNode, helperName, newHashPairs) { + + var hash = mustacheNode.hash; + + // Merge hash. + if(newHashPairs) { + hash = hash || new Handlebars.AST.HashNode([]); + + for(var i = 0; i < newHashPairs.length; ++i) { + hash.pairs.push(newHashPairs[i]); + } + } + + var params = [mustacheNode.id].concat(mustacheNode.params); + params.unshift(new Handlebars.AST.IdNode([helperName])); + return new Handlebars.AST.MustacheNode(params, hash, !mustacheNode.escaped); + } + + var result = parseFunctions[startRule](); /* diff --git a/lib/preprocessor.js b/lib/preprocessor.js index 8cf7e0f..45a2549 100644 --- a/lib/preprocessor.js +++ b/lib/preprocessor.js @@ -1,4 +1,3 @@ -// Generated by CoffeeScript 1.4.0 var Emblem, Preprocessor, StringScanner; StringScanner = require('StringScanner'); diff --git a/lib/translation.js b/lib/translation.js deleted file mode 100644 index 22700f1..0000000 --- a/lib/translation.js +++ /dev/null @@ -1,115 +0,0 @@ -// Generated by CoffeeScript 1.4.0 -var ContentStack, Emblem, Handlebars, processNodes, - __hasProp = {}.hasOwnProperty; - -Handlebars = require('handlebars'); - -Emblem = require('./emblem'); - -ContentStack = (function() { - - function ContentStack() { - this.current = ""; - } - - ContentStack.prototype.append = function(s) { - return this.current += s; - }; - - ContentStack.prototype.flatten = function() { - var ret; - ret = this.current; - this.current = ""; - return ret; - }; - - return ContentStack; - -})(); - -processNodes = function(nodes, stack, statements) { - var attributesString, c, classNames, classes, closeId, firstChar, hash, helper, id, ids, k, name, node, openStache, pairs, param, params, result, substatements, tagName, v, value, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2; - if (statements == null) { - statements = []; - } - for (_i = 0, _len = nodes.length; _i < _len; _i++) { - node = nodes[_i]; - if (node.type === 'html') { - tagName = node.tagName || 'div'; - classes = node.attrs.classes || []; - classNames = classes.join(' '); - attributesString = ""; - _ref = node.attrs || {}; - for (name in _ref) { - if (!__hasProp.call(_ref, name)) continue; - value = _ref[name]; - attributesString += ' ' + name + '=' + '"' + value + '"'; - } - stack.append("<" + tagName + attributesString + ">"); - processNodes(node.nodes || [], stack, statements); - stack.append(""); - } else if (node.type === 'mustache') { - c = stack.flatten(); - if (c) { - statements.push(new Handlebars.AST.ContentNode(c)); - } - firstChar = node.params[0].charAt(0); - if (!node.forced && firstChar === firstChar.toUpperCase()) { - helper = "view"; - node.params.unshift(helper); - } - params = []; - _ref1 = node.params; - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - param = _ref1[_j]; - ids = param.split('.'); - result = []; - for (_k = 0, _len2 = ids.length; _k < _len2; _k++) { - id = ids[_k]; - result.push(id); - result.push('.'); - } - result.pop(); - params.push(new Handlebars.AST.IdNode(result)); - } - pairs = []; - _ref2 = node.hash; - for (k in _ref2) { - if (!__hasProp.call(_ref2, k)) continue; - v = _ref2[k]; - pairs.push([k, v]); - } - hash = null; - if (pairs.length) { - hash = new Handlebars.AST.HashNode(pairs); - } - if (node.nodes && node.nodes.length) { - closeId = params[0]; - substatements = processNodes(node.nodes, new ContentStack); - statements.push(new Handlebars.AST.ProgramNode(substatements, [])); - openStache = new Handlebars.AST.MustacheNode(params, hash, node.escaped); - statements.push(new Handlebars.AST.BlockNode(openStache, statements, [], closeId)); - } else { - statements.push(new Handlebars.AST.MustacheNode(params, hash, node.escaped)); - } - } else if (node instanceof Array) { - processNodes(node, stack, statements); - } else { - stack.append(node.toString()); - } - } - return statements; -}; - -Emblem.parse = function(string) { - var c, emblemAST, processed, stack, statements; - stack = new ContentStack; - processed = Emblem.Preprocessor.processSync(string); - emblemAST = Emblem.Parser.parse(processed); - statements = processNodes(emblemAST, stack); - c = stack.flatten(); - if (c) { - statements.push(new Handlebars.AST.ContentNode(c)); - } - return new Handlebars.AST.ProgramNode(statements, []); -}; diff --git a/spec/qunit_spec.coffee b/spec/qunit_spec.coffee index 8d2bc51..d9c54a9 100644 --- a/spec/qunit_spec.coffee +++ b/spec/qunit_spec.coffee @@ -21,18 +21,30 @@ unless CompilerContext? templateSpec = Emblem.precompile(template, options) Handlebars.template eval "(#{templateSpec})" +shouldCompileToString = (string, hashOrArray, expected) -> + + if hashOrArray.constructor == String + shouldCompileToWithPartials(string, {}, false, hashOrArray, null, true) + else + shouldCompileToWithPartials(string, hashOrArray, false, expected, null, true) + shouldCompileTo = (string, hashOrArray, expected, message) -> if hashOrArray.constructor == String shouldCompileToWithPartials(string, {}, false, hashOrArray, message) else shouldCompileToWithPartials(string, hashOrArray, false, expected, message) -shouldCompileToWithPartials = (string, hashOrArray, partials, expected, message) -> - result = compileWithPartials(string, hashOrArray, partials) +shouldCompileToWithPartials = (string, hashOrArray, partials, expected, message, strings) -> + options = null + if strings + options = {} + options.stringParams = true + + result = compileWithPartials(string, hashOrArray, partials, options) equal(expected, result, "'" + expected + "' should === '" + result + "': " + message) -compileWithPartials = (string, hashOrArray, partials) -> - template = CompilerContext.compile(string) +compileWithPartials = (string, hashOrArray, partials, options = {}) -> + template = CompilerContext.compile(string, options) if Object::toString.call(hashOrArray) == "[object Array]" if helpers = hashOrArray[1] for prop of Handlebars.helpers @@ -237,17 +249,24 @@ test "class shorthand", -> shouldCompileTo "span.woot.loot", '' -suite "full attributes" +suite "full attributes - tags without content" -test "tags without content", -> +test "class only", -> shouldCompileTo 'p class="yes"', '

' +test "id only", -> shouldCompileTo 'p id="yes"', '

' +test "class and i", -> shouldCompileTo 'p id="yes" class="no"', '

' + +suite "full attributes - tags with content" -test "tags with content", -> +test "class only", -> shouldCompileTo 'p class="yes" Blork', '

Blork

' +test "id only", -> shouldCompileTo 'p id="yes" Hyeah', '

Hyeah

' +test "class and id", -> shouldCompileTo 'p id="yes" class="no" Blork', '

Blork

' +test "class and id and embedded html one-liner", -> shouldCompileTo 'p id="yes" class="no" One asd!', '

One asd!

' test "nesting", -> @@ -308,6 +327,7 @@ test "various one-liners", -> { foo: "ASD", arf: "QWE", goo: "WER" }, 'ASDQWE

ASD

WER

' + test "double =='s un-escape", -> emblem = """ @@ -339,17 +359,54 @@ Handlebars.registerHelper 'frank', -> options = arguments[arguments.length - 1] "WOO: #{options.hash.text} #{options.hash.text2}" +Handlebars.registerHelper 'sally', -> + options = arguments[arguments.length - 1] + params = Array::slice.call arguments, 0, -1 + param = params[0] || 'none' + if options.fn + content = options.fn @ + new Handlebars.SafeString """#{content}""" + else + content = param + new Handlebars.SafeString """#{content}""" + test "basic", -> shouldCompileTo 'ahelper foo', {foo: "YES"}, 'HELPED YES' test "hashed parameters should work", -> shouldCompileTo 'frank text="YES" text2="NO"', 'WOO: YES NO' +test "nesting", -> + emblem = + """ + sally + p Hello + """ + shouldCompileTo emblem, '

Hello

' -Handlebars.registerHelper 'view', (param) -> +test "recursive nesting", -> + emblem = + """ + sally + sally + p Hello + """ + shouldCompileTo emblem, '

Hello

' + +test "recursive nesting pt 2", -> + emblem = + """ + sally + sally thing + p Hello + """ + shouldCompileTo emblem, { thing: "woot" }, '

Hello

' + +Handlebars.registerHelper 'view', (param, a, b, c) -> options = arguments[arguments.length - 1] content = param content = options.fn @ if options.fn - new Handlebars.SafeString """#{content}'""" + #Handlebars.logger.log 9, "" + new Handlebars.SafeString """#{content}""" suite "capitalized line-starter" @@ -358,7 +415,7 @@ test "should invoke `view` helper by default", -> """ SomeView """ - shouldCompileTo emblem, 'SomeView' + shouldCompileToString emblem, 'SomeView' test "should support block mode", -> emblem = @@ -366,7 +423,7 @@ test "should support block mode", -> SomeView p View content """ - shouldCompileTo emblem, '

View content

' + shouldCompileToString emblem, '

View content

' test "should not kick in if preceded by equal sign", -> emblem = @@ -391,10 +448,10 @@ suite "bang syntax defaults to `unbound` helper syntax" Handlebars.registerHelper 'unbound', -> options = arguments[arguments.length - 1] - params = Array::slice.call arguments, -1 + params = Array::slice.call arguments, 0, -1 stringedParams = params.join(' ') content = if options.fn then options.fn @ else stringedParams - new Handlebars.SafeString """#{content}'""" + new Handlebars.SafeString """#{content}""" test "bang helper defaults to `unbound` invocation", -> emblem = @@ -402,7 +459,7 @@ test "bang helper defaults to `unbound` invocation", -> foo! Yar = foo! """ - shouldCompileTo emblem, 'foo Yarfoo' + shouldCompileToString emblem, 'foo Yarfoo' test "bang helper works with blocks", -> emblem = @@ -410,10 +467,61 @@ test "bang helper works with blocks", -> hey! you suck = foo! """ - shouldCompileTo emblem, 'foo' + shouldCompileToString emblem, 'foo' + + +suite "question mark syntax defaults to `if` helper syntax" + +test "? helper defaults to `if` invocation", -> + emblem = + """ + foo? + p Yeah + """ + shouldCompileTo emblem, { foo: true }, '

Yeah

' + + +test "else works", -> + emblem = + """ + foo? + p Yeah + else + p No + """ + shouldCompileTo emblem, { foo: false }, '

No

' + + +test "compound", -> + emblem = + """ + p = foo? + | Hooray + else + | No + p = bar? + | Hooray + else + | No + """ + shouldCompileTo emblem, { foo: true, bar: false }, '

Hooray

No

' + + +test "compound", -> + emblem = + """ + p = foo? + bar + else + baz + """ + shouldCompileTo emblem, { foo: true, bar: "borf", baz: "narsty" }, '

borf

' + + + + -# TODO test overriding the default bang helper name (instead of always "unbound") suite "conditionals" @@ -445,42 +553,77 @@ test "if else ", -> """ shouldCompileTo emblem, {foo: true, bar: false}, 'FooWootHooray' +test "unless", -> + emblem = + """ + unless bar + | Foo + unless foo + | Bar + else + | Woot + else + | WRONG + unless foo + | WRONG + else + | Hooray + """ + shouldCompileTo emblem, {foo: true, bar: false}, 'FooWootHooray' Handlebars.registerHelper 'bindAttr', -> options = arguments[arguments.length - 1] - - binding = null - for own k, v of options.hash - binding = [k,v] - break - "#{k}BoundTo#{v}" + params = Array::slice.call arguments, 0, -1 + bindingString = "" + for own k,v of options.hash + bindingString += " #{k} to #{v}" + bindingString = " narf" unless bindingString + param = params[0] || 'none' + "bindAttr#{bindingString}" suite "bindAttr behavior for unquoted attribute values" test "basic", -> - shouldCompileTo 'p class=foo', '

' + shouldCompileTo 'p class=foo', '

' test "multiple", -> shouldCompileTo 'p class=foo id="yup" data-thinger=yeah Hooray', - '

Hooray

' + '

Hooray

' test "class bindAttr special syntax", -> - shouldCompileTo 'p class=foo:bar:baz', '

' - + shouldCompileTo 'p class=foo:bar:baz', '

' suite "in-tag explicit mustache" -test "basic", -> - shouldCompileTo 'p{{bindAttr class="foo"}}', '

' +Handlebars.registerHelper 'inTagHelper', (p) -> + return p; + +test "single", -> + shouldCompileTo 'p{inTagHelper foo}', {foo: "ALEX"}, '

' + +test "double", -> + shouldCompileTo 'p{inTagHelper foo}', {foo: "ALEX"}, '

' + +test "triple", -> + shouldCompileTo 'p{inTagHelper foo}', {foo: "ALEX"}, '

' + +Handlebars.registerHelper 'insertClass', (p) -> + return 'class="' + p + '"' + +test "with singlestache", -> + shouldCompileTo 'p{insertClass foo} Hello', {foo: "yar"}, '

Hello

' + +test "with doublestache", -> + shouldCompileTo 'p{{insertClass foo}} Hello', {foo: "yar"}, '

Hello

' + +test "with triplestache", -> + shouldCompileTo 'p{{{insertClass foo}}} Hello', {foo: "yar"}, '

Hello

' + +test "multiple", -> + shouldCompileTo 'p{{{insertClass foo}}}{{{insertClass boo}}} Hello', + {foo: "yar", boo: "nar"}, + '

Hello

' -test "with inline content", -> - emblem = - """ - p{{bindAttr class="foo"}} Hello - p{{bindAttr class="foo"}} = foo - """ - shouldCompileTo emblem, {foo: "yar"}, - '

Hello

yar

' test "with nesting", -> emblem = @@ -489,31 +632,32 @@ test "with nesting", -> span Hello """ shouldCompileTo emblem, {foo: "yar"}, - '

Hello

' - -test "multiple", -> - emblem = - """ - p{{bindAttr class="foo"}}{{bindAttr thing="yar"}} Hello - """ - shouldCompileTo emblem, {foo: "yar"}, - '

Hello

' + '

Hello

' suite "actions" -Handlebars.registerHelper 'bindAttr', (actionName) -> +Handlebars.registerHelper 'action', -> options = arguments[arguments.length - 1] - params = Array::slice.call arguments, -1 - onString = options.hash.on - targetString = "target=#{options.hash.target || "default"}" - "action|#{onString}|#{params[0]}|#{targetString}" + params = Array::slice.call arguments, 0, -1 + + hashString = "" + paramsString = params.join('|') + + # TODO: bad because it relies on hash ordering? + # is this guaranteed? guess it doesn't rreeeeeally + # matter since order's not being tested. + for own k,v of options.hash + hashString += " #{k}=#{v}" + hashString = " nohash" unless hashString + "action #{paramsString}#{hashString}" + test "basic (click)", -> emblem = """ button click="submitComment" Submit Comment """ - shouldCompileTo emblem, '' + shouldCompileToString emblem, '' test "nested (mouseEnter)", -> emblem = @@ -521,5 +665,32 @@ test "nested (mouseEnter)", -> a mouseEnter='submitComment target="view"' | Submit Comment """ - shouldCompileTo emblem, 'Submit Comment' + shouldCompileToString emblem, 'Submit Comment' + +test "nested (mouseEnter, doublequoted)", -> + emblem = + """ + a mouseEnter="submitComment target='view'" + | Submit Comment + """ + shouldCompileToString emblem, 'Submit Comment' + +test "manual", -> + emblem = + """ + a{action submitComment target="view"} Submit Comment + """ + shouldCompileToString emblem, 'Submit Comment' + +test "manual nested", -> + emblem = + """ + a{action submitComment target="view"} + p Submit Comment + """ + shouldCompileToString emblem, '

Submit Comment

' + + + + diff --git a/spec/qunit_spec.js b/spec/qunit_spec.js index ef5bc14..1b2b926 100644 --- a/spec/qunit_spec.js +++ b/spec/qunit_spec.js @@ -1,5 +1,5 @@ // Generated by CoffeeScript 1.4.0 -var CompilerContext, Emblem, Handlebars, assert, compileWithPartials, equal, equals, ok, shouldCompileTo, shouldCompileToWithPartials, shouldThrow, throws, _equal, +var CompilerContext, Emblem, Handlebars, assert, compileWithPartials, equal, equals, ok, shouldCompileTo, shouldCompileToString, shouldCompileToWithPartials, shouldThrow, throws, _equal, __hasProp = {}.hasOwnProperty; if (!((typeof Handlebars !== "undefined" && Handlebars !== null) && (typeof Emblem !== "undefined" && Emblem !== null))) { @@ -24,6 +24,14 @@ if (typeof CompilerContext === "undefined" || CompilerContext === null) { }; } +shouldCompileToString = function(string, hashOrArray, expected) { + if (hashOrArray.constructor === String) { + return shouldCompileToWithPartials(string, {}, false, hashOrArray, null, true); + } else { + return shouldCompileToWithPartials(string, hashOrArray, false, expected, null, true); + } +}; + shouldCompileTo = function(string, hashOrArray, expected, message) { if (hashOrArray.constructor === String) { return shouldCompileToWithPartials(string, {}, false, hashOrArray, message); @@ -32,15 +40,23 @@ shouldCompileTo = function(string, hashOrArray, expected, message) { } }; -shouldCompileToWithPartials = function(string, hashOrArray, partials, expected, message) { - var result; - result = compileWithPartials(string, hashOrArray, partials); +shouldCompileToWithPartials = function(string, hashOrArray, partials, expected, message, strings) { + var options, result; + options = null; + if (strings) { + options = {}; + options.stringParams = true; + } + result = compileWithPartials(string, hashOrArray, partials, options); return equal(expected, result, "'" + expected + "' should === '" + result + "': " + message); }; -compileWithPartials = function(string, hashOrArray, partials) { +compileWithPartials = function(string, hashOrArray, partials, options) { var ary, helpers, prop, template; - template = CompilerContext.compile(string); + if (options == null) { + options = {}; + } + template = CompilerContext.compile(string, options); if (Object.prototype.toString.call(hashOrArray) === "[object Array]") { if (helpers = hashOrArray[1]) { for (prop in Handlebars.helpers) { @@ -227,18 +243,35 @@ test("class shorthand", function() { return shouldCompileTo("span.woot.loot", ''); }); -suite("full attributes"); +suite("full attributes - tags without content"); -test("tags without content", function() { - shouldCompileTo('p class="yes"', '

'); - shouldCompileTo('p id="yes"', '

'); +test("class only", function() { + return shouldCompileTo('p class="yes"', '

'); +}); + +test("id only", function() { + return shouldCompileTo('p id="yes"', '

'); +}); + +test("class and i", function() { return shouldCompileTo('p id="yes" class="no"', '

'); }); -test("tags with content", function() { - shouldCompileTo('p class="yes" Blork', '

Blork

'); - shouldCompileTo('p id="yes" Hyeah', '

Hyeah

'); - shouldCompileTo('p id="yes" class="no" Blork', '

Blork

'); +suite("full attributes - tags with content"); + +test("class only", function() { + return shouldCompileTo('p class="yes" Blork', '

Blork

'); +}); + +test("id only", function() { + return shouldCompileTo('p id="yes" Hyeah', '

Hyeah

'); +}); + +test("class and id", function() { + return shouldCompileTo('p id="yes" class="no" Blork', '

Blork

'); +}); + +test("class and id and embedded html one-liner", function() { return shouldCompileTo('p id="yes" class="no" One asd!', '

One asd!

'); }); @@ -314,6 +347,20 @@ Handlebars.registerHelper('frank', function() { return "WOO: " + options.hash.text + " " + options.hash.text2; }); +Handlebars.registerHelper('sally', function() { + var content, options, param, params; + options = arguments[arguments.length - 1]; + params = Array.prototype.slice.call(arguments, 0, -1); + param = params[0] || 'none'; + if (options.fn) { + content = options.fn(this); + return new Handlebars.SafeString("" + content + ""); + } else { + content = param; + return new Handlebars.SafeString("" + content + ""); + } +}); + test("basic", function() { return shouldCompileTo('ahelper foo', { foo: "YES" @@ -324,14 +371,34 @@ test("hashed parameters should work", function() { return shouldCompileTo('frank text="YES" text2="NO"', 'WOO: YES NO'); }); -Handlebars.registerHelper('view', function(param) { +test("nesting", function() { + var emblem; + emblem = "sally\n p Hello"; + return shouldCompileTo(emblem, '

Hello

'); +}); + +test("recursive nesting", function() { + var emblem; + emblem = "sally\n sally\n p Hello"; + return shouldCompileTo(emblem, '

Hello

'); +}); + +test("recursive nesting pt 2", function() { + var emblem; + emblem = "sally\n sally thing\n p Hello"; + return shouldCompileTo(emblem, { + thing: "woot" + }, '

Hello

'); +}); + +Handlebars.registerHelper('view', function(param, a, b, c) { var content, options; options = arguments[arguments.length - 1]; content = param; if (options.fn) { content = options.fn(this); } - return new Handlebars.SafeString("" + content + "'"); + return new Handlebars.SafeString("" + content + ""); }); suite("capitalized line-starter"); @@ -339,13 +406,13 @@ suite("capitalized line-starter"); test("should invoke `view` helper by default", function() { var emblem; emblem = "SomeView"; - return shouldCompileTo(emblem, 'SomeView'); + return shouldCompileToString(emblem, 'SomeView'); }); test("should support block mode", function() { var emblem; emblem = "SomeView\n p View content"; - return shouldCompileTo(emblem, '

View content

'); + return shouldCompileToString(emblem, '

View content

'); }); test("should not kick in if preceded by equal sign", function() { @@ -369,22 +436,59 @@ suite("bang syntax defaults to `unbound` helper syntax"); Handlebars.registerHelper('unbound', function() { var content, options, params, stringedParams; options = arguments[arguments.length - 1]; - params = Array.prototype.slice.call(arguments, -1); + params = Array.prototype.slice.call(arguments, 0, -1); stringedParams = params.join(' '); content = options.fn ? options.fn(this) : stringedParams; - return new Handlebars.SafeString("" + content + "'"); + return new Handlebars.SafeString("" + content + ""); }); test("bang helper defaults to `unbound` invocation", function() { var emblem; emblem = "foo! Yar\n= foo!"; - return shouldCompileTo(emblem, 'foo Yarfoo'); + return shouldCompileToString(emblem, 'foo Yarfoo'); }); test("bang helper works with blocks", function() { var emblem; emblem = "hey! you suck\n = foo!"; - return shouldCompileTo(emblem, 'foo'); + return shouldCompileToString(emblem, 'foo'); +}); + +suite("question mark syntax defaults to `if` helper syntax"); + +test("? helper defaults to `if` invocation", function() { + var emblem; + emblem = "foo?\n p Yeah"; + return shouldCompileTo(emblem, { + foo: true + }, '

Yeah

'); +}); + +test("else works", function() { + var emblem; + emblem = "foo?\n p Yeah\nelse\n p No"; + return shouldCompileTo(emblem, { + foo: false + }, '

No

'); +}); + +test("compound", function() { + var emblem; + emblem = "p = foo? \n | Hooray\nelse\n | No\np = bar? \n | Hooray\nelse\n | No"; + return shouldCompileTo(emblem, { + foo: true, + bar: false + }, '

Hooray

No

'); +}); + +test("compound", function() { + var emblem; + emblem = "p = foo? \n bar\nelse\n baz"; + return shouldCompileTo(emblem, { + foo: true, + bar: "borf", + baz: "narsty" + }, '

borf

'); }); suite("conditionals"); @@ -407,83 +511,154 @@ test("if else ", function() { }, 'FooWootHooray'); }); +test("unless", function() { + var emblem; + emblem = "unless bar\n | Foo\n unless foo\n | Bar\n else\n | Woot\nelse\n | WRONG\nunless foo\n | WRONG\nelse\n | Hooray"; + return shouldCompileTo(emblem, { + foo: true, + bar: false + }, 'FooWootHooray'); +}); + Handlebars.registerHelper('bindAttr', function() { - var binding, k, options, v, _ref; + var bindingString, k, options, param, params, v, _ref; options = arguments[arguments.length - 1]; - binding = null; + params = Array.prototype.slice.call(arguments, 0, -1); + bindingString = ""; _ref = options.hash; for (k in _ref) { if (!__hasProp.call(_ref, k)) continue; v = _ref[k]; - binding = [k, v]; - break; + bindingString += " " + k + " to " + v; + } + if (!bindingString) { + bindingString = " narf"; } - return "" + k + "BoundTo" + v; + param = params[0] || 'none'; + return "bindAttr" + bindingString; }); suite("bindAttr behavior for unquoted attribute values"); test("basic", function() { - return shouldCompileTo('p class=foo', '

'); + return shouldCompileTo('p class=foo', '

'); }); test("multiple", function() { - return shouldCompileTo('p class=foo id="yup" data-thinger=yeah Hooray', '

Hooray

'); + return shouldCompileTo('p class=foo id="yup" data-thinger=yeah Hooray', '

Hooray

'); }); test("class bindAttr special syntax", function() { - return shouldCompileTo('p class=foo:bar:baz', '

'); + return shouldCompileTo('p class=foo:bar:baz', '

'); }); suite("in-tag explicit mustache"); -test("basic", function() { - return shouldCompileTo('p{{bindAttr class="foo"}}', '

'); +Handlebars.registerHelper('inTagHelper', function(p) { + return p; }); -test("with inline content", function() { - var emblem; - emblem = "p{{bindAttr class=\"foo\"}} Hello\np{{bindAttr class=\"foo\"}} = foo"; - return shouldCompileTo(emblem, { +test("single", function() { + return shouldCompileTo('p{inTagHelper foo}', { + foo: "ALEX" + }, '

'); +}); + +test("double", function() { + return shouldCompileTo('p{inTagHelper foo}', { + foo: "ALEX" + }, '

'); +}); + +test("triple", function() { + return shouldCompileTo('p{inTagHelper foo}', { + foo: "ALEX" + }, '

'); +}); + +Handlebars.registerHelper('insertClass', function(p) { + return 'class="' + p + '"'; +}); + +test("with singlestache", function() { + return shouldCompileTo('p{insertClass foo} Hello', { foo: "yar" - }, '

Hello

yar

'); + }, '

Hello

'); }); -test("with nesting", function() { - var emblem; - emblem = "p{{bindAttr class=\"foo\"}}\n span Hello"; - return shouldCompileTo(emblem, { +test("with doublestache", function() { + return shouldCompileTo('p{{insertClass foo}} Hello', { foo: "yar" - }, '

Hello

'); + }, '

Hello

'); +}); + +test("with triplestache", function() { + return shouldCompileTo('p{{{insertClass foo}}} Hello', { + foo: "yar" + }, '

Hello

'); }); test("multiple", function() { + return shouldCompileTo('p{{{insertClass foo}}}{{{insertClass boo}}} Hello', { + foo: "yar", + boo: "nar" + }, '

Hello

'); +}); + +test("with nesting", function() { var emblem; - emblem = "p{{bindAttr class=\"foo\"}}{{bindAttr thing=\"yar\"}} Hello"; + emblem = "p{{bindAttr class=\"foo\"}}\n span Hello"; return shouldCompileTo(emblem, { foo: "yar" - }, '

Hello

'); + }, '

Hello

'); }); suite("actions"); -Handlebars.registerHelper('bindAttr', function(actionName) { - var onString, options, params, targetString; +Handlebars.registerHelper('action', function() { + var hashString, k, options, params, paramsString, v, _ref; options = arguments[arguments.length - 1]; - params = Array.prototype.slice.call(arguments, -1); - onString = options.hash.on; - targetString = "target=" + (options.hash.target || "default"); - return "action|" + onString + "|" + params[0] + "|" + targetString; + params = Array.prototype.slice.call(arguments, 0, -1); + hashString = ""; + paramsString = params.join('|'); + _ref = options.hash; + for (k in _ref) { + if (!__hasProp.call(_ref, k)) continue; + v = _ref[k]; + hashString += " " + k + "=" + v; + } + if (!hashString) { + hashString = " nohash"; + } + return "action " + paramsString + hashString; }); test("basic (click)", function() { var emblem; emblem = "button click=\"submitComment\" Submit Comment"; - return shouldCompileTo(emblem, ''); + return shouldCompileToString(emblem, ''); }); test("nested (mouseEnter)", function() { var emblem; emblem = "a mouseEnter='submitComment target=\"view\"'\n | Submit Comment"; - return shouldCompileTo(emblem, 'Submit Comment'); + return shouldCompileToString(emblem, 'Submit Comment'); +}); + +test("nested (mouseEnter, doublequoted)", function() { + var emblem; + emblem = "a mouseEnter=\"submitComment target='view'\"\n | Submit Comment"; + return shouldCompileToString(emblem, 'Submit Comment'); +}); + +test("manual", function() { + var emblem; + emblem = "a{action submitComment target=\"view\"} Submit Comment"; + return shouldCompileToString(emblem, 'Submit Comment'); +}); + +test("manual nested", function() { + var emblem; + emblem = "a{action submitComment target=\"view\"}\n p Submit Comment"; + return shouldCompileToString(emblem, '

Submit Comment

'); }); diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ef49d9f..e5d11b0 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -75,7 +75,6 @@ def self.js_load(context, file) Emblem::Spec.js_load(context, 'lib/parser.js') Emblem::Spec.js_load(context, 'lib/compiler.js') Emblem::Spec.js_load(context, 'lib/preprocessor.js') - Emblem::Spec.js_load(context, 'lib/translation.js') Emblem::Spec.js_load(context, 'lib/emberties.js') context["Handlebars"]["logger"]["level"] = ENV["DEBUG_JS"] ? context["Handlebars"]["logger"][ENV["DEBUG_JS"]] : 4 diff --git a/src/compiler.coffee b/src/compiler.coffee index fc996c5..bbce30f 100644 --- a/src/compiler.coffee +++ b/src/compiler.coffee @@ -1,9 +1,15 @@ Handlebars = require 'handlebars' Emblem = require './emblem' +Emblem.parse = (string) -> + # Pre-process, parse + processed = Emblem.Preprocessor.processSync string + new Handlebars.AST.ProgramNode(Emblem.Parser.parse(processed), []) + Emblem.precompileRaw = (string, options = {}) -> if typeof string isnt 'string' throw new Handlebars.Exception("You must pass a string to Emblem.precompile. You passed " + string) + #options.stringParams = true unless 'stringParams' in options options.data = true unless 'data' in options ast = Emblem.parse string @@ -13,6 +19,7 @@ Emblem.precompileRaw = (string, options = {}) -> Emblem.compileRaw = (string, options = {}) -> if typeof string isnt 'string' throw new Handlebars.Exception("You must pass a string to Emblem.compile. You passed " + string) + #options.stringParams = true unless 'stringParams' in options options.data = true unless 'data' in options compiled = null @@ -29,7 +36,6 @@ Emblem.compileRaw = (string, options = {}) -> Emblem.precompile = Emblem.precompileRaw Emblem.compile = Emblem.compileRaw - # See ember-handlebars-compiler code in Ember.js codebase # for where the following functions came from Emblem.precompileEmber = (string) -> diff --git a/src/emblem.coffee b/src/emblem.coffee index 8aa6101..7467688 100644 --- a/src/emblem.coffee +++ b/src/emblem.coffee @@ -8,6 +8,5 @@ require 'handlebars'; require './parser'; require './compiler'; require './preprocessor'; -require './translation'; require './emberties'; diff --git a/src/grammar.pegjs b/src/grammar.pegjs index d96b9cb..12694bc 100644 --- a/src/grammar.pegjs +++ b/src/grammar.pegjs @@ -1,87 +1,244 @@ +{ + // Returns a new MustacheNode with a new preceding param (id). + function unshiftParam(mustacheNode, helperName, newHashPairs) { + + var hash = mustacheNode.hash; + + // Merge hash. + if(newHashPairs) { + hash = hash || new Handlebars.AST.HashNode([]); + + for(var i = 0; i < newHashPairs.length; ++i) { + hash.pairs.push(newHashPairs[i]); + } + } + + var params = [mustacheNode.id].concat(mustacheNode.params); + params.unshift(new Handlebars.AST.IdNode([helperName])); + return new Handlebars.AST.MustacheNode(params, hash, !mustacheNode.escaped); + } +} + start = content -content = statement* +content = statements:statement* +{ + // Coalesce all adjacent ContentNodes into one. + + var compressedStatements = []; + var buffer = []; + + for(var i = 0; i < statements.length; ++i) { + var nodes = statements[i]; + + for(var j = 0; j < nodes.length; ++j) { + var node = nodes[j] + if(node.type === "content") { + if(node.string) { + // Ignore empty strings (comments). + buffer.push(node.string); + } + continue; + } + + // Flush content if present. + if(buffer.length) { + compressedStatements.push(new Handlebars.AST.ContentNode(buffer.join(''))); + buffer = []; + } + compressedStatements.push(node); + } + } + + if(buffer.length) { + compressedStatements.push(new Handlebars.AST.ContentNode(buffer.join(''))); + } + + return compressedStatements; +} + +invertibleContent = c:content i:( DEDENT 'else' _ TERM INDENT c:content {return c;})? +{ + return new Handlebars.AST.ProgramNode(c, i || []); +} + +// A statement is an array of nodes. +// Often they're single-element arrays, but for things +// like text lines, there might be multiple elements. statement = comment - / html + / htmlElement + / textLine / mustache -html - = htmlMaybeBlock - / htmlWithInlineContent - / t:textLine { return t; } +htmlElement + = htmlElementMaybeBlock / htmlElementWithInlineContent -mustache - = f:forcedMustache { return f; } - / mustacheMaybeBlock +// Returns [MustacheNode] or [BlockNode] +mustache + = m:(explicitMustache / lineStartingMustache) +{ + return [m]; +} -comment - = '/' lineContent TERM ( INDENT (lineContent TERM)+ DEDENT )? { return ""; } +comment + = '/' lineContent TERM ( INDENT (lineContent TERM)+ DEDENT )? { return []; } +lineStartingMustache + = capitalizedLineStarterMustache / mustacheMaybeBlock +capitalizedLineStarterMustache + = &[A-Z] ret:mustacheMaybeBlock +{ + // TODO make this configurable + var defaultCapitalizedHelper = 'view'; + + if(ret.mustache) { + // Block. Modify inner MustacheNode and return. + ret.mustache = unshiftParam(ret.mustache, defaultCapitalizedHelper); + return ret; + } else { + // ret is the MustacheNode + return unshiftParam(ret, defaultCapitalizedHelper); + } +} +htmlElementMaybeBlock + = h:htmlTagAndOptionalAttributes _ TERM c:(INDENT content DEDENT)? +{ + var ret = h[0]; + if(c) { + ret = ret.concat(c[1]); + } + ret.push(h[1]); + return ret; +} -htmlMaybeBlock = h:htmlAttributesOnly c:(INDENT content DEDENT)? +htmlElementWithInlineContent + = h:htmlTagAndOptionalAttributes ' ' c:htmlInlineContent { - h.nodes = c ? c[1] : []; - return h; + var ret = h[0]; + if(c) { + ret = ret.concat(c); + } + ret.push(h[1]); + + return ret; +} + +mustacheMaybeBlock + = mustacheNode:inMustache _ TERM block:(INDENT invertibleContent DEDENT)? +{ + if(!block) return mustacheNode; + var programNode = block[1]; + return new Handlebars.AST.BlockNode(mustacheNode, programNode, programNode.inverse, mustacheNode.id); } -htmlAttributesOnly = t:htmlTag _ TERM { t.nodes = []; return t; } +explicitMustache + = e:equalSign ret:mustacheMaybeBlock +{ + var mustache = ret.mustache || ret; + mustache.escaped = e; + return ret; +} + +inMustache + = path:pathIdNode tm:trailingModifier? params:inMustacheParam* hash:hash? +{ + params.unshift(path); + + var mustacheNode = new Handlebars.AST.MustacheNode(params, hash); -htmlWithInlineContent = t:htmlTag ws c:htmlInlineContent TERM { t.nodes = c; return t; } + if(tm == '!') { + return unshiftParam(mustacheNode, 'unbound'); + } else if(tm == '?') { + return unshiftParam(mustacheNode, 'if'); + } else if(tm == '^') { + return unshiftParam(mustacheNode, 'unless'); + } + + return mustacheNode; +} -mustacheMaybeBlock = t:mustacheContent TERM c:(INDENT content DEDENT)? +// TODO: this +modifiedParam = p:param m:trailingModifier { - t.nodes = c ? c[1] : []; - return t; + var ret = new String(p); + ret.trailingModifier = m; + return ret; } -forcedMustache = _ e:equalSign c:mustacheMaybeBlock { c.forced = true; c.escaped = e; return c; } +inMustacheParam + = _ p:param { return p; } -mustacheContent = &[A-Za-z] p:params h:hash -{ - return { type: 'mustache', params:p, hash:h }; -} +trailingModifier + = [!?*^] + +hash + = h:hashSegment+ { return new Handlebars.AST.HashNode(h); } + +pathIdent + = '..' / '.' / s:[a-zA-Z0-9_$-]+ !'=' { return s.join(''); } -params = p:(_ param:param !'=' _ {return param;})+ { return p; } -param = p:paramChar+ { return p.join(''); } -paramChar = alpha / '_' / '-' / '.' +key + = ident -hash = h:(_ k:param '=' v:hashValue _ { return { key: k, value: v }; } )* +hashSegment + = _ h:( key '=' pathIdNode + / key '=' stringNode + / key '=' integerNode + / key '=' booleanNode ) { return [h[0], h[2]]; } + +param + = pathIdNode + / stringNode + / integerNode + / booleanNode + +path = first:pathIdent tail:(seperator p:pathIdent { return p; })* { - var ret = {}; - for(var i = 0; i < h.length; ++i) { - var pair = h[i]; - ret[pair.key] = pair.value; + var ret = [first]; + for(var i = 0; i < tail.length; ++i) { + //ret = ret.concat(tail[i]); + ret.push(tail[i]); } return ret; } -hashValue = string / param / integer +seperator = [\/.] + +pathIdNode = v:path { return new Handlebars.AST.IdNode(v); } +stringNode = v:string { return new Handlebars.AST.StringNode(v); } +integerNode = v:integer { return new Handlebars.AST.IntegerNode(v); } +booleanNode = v:boolean { return new Handlebars.AST.BooleanNode(v); } + +boolean = 'true' / 'false' + integer = s:[0-9]+ { return parseInt(s.join('')); } -string = p:('"' hashDoubleQuoteStringValue '"' / "'" hashSingleQuoteStringValue "'") { return p.join(''); } +string = p:('"' hashDoubleQuoteStringValue '"' / "'" hashSingleQuoteStringValue "'") { return p[1]; } + hashDoubleQuoteStringValue = s:[^"}]* { return s.join(''); } hashSingleQuoteStringValue = s:[^'}]* { return s.join(''); } alpha = [A-Za-z] -htmlInlineContent - = m:forcedMustache { return [m]; } - / textNodes +// returns an array of nodes. +htmlInlineContent + = m:explicitMustache { return [m]; } + / t:textNodes -textLine = '|' ' '? nodes:textNodes TERM indentedNodes:( INDENT n:(n:textNodes TERM { return n;})+ DEDENT { return n; })* +textLine = '|' ' '? nodes:textNodes indentedNodes:(INDENT t:textNodes DEDENT { return t; })* { - if(indentedNodes.length) { - nodes = nodes.concat(indentedNodes[0][0]); + for(var i = 0; i < indentedNodes.length; ++i) { + nodes = nodes.concat(indentedNodes[i]); } return nodes; } -textNodes = first:preMustacheText? tail:(rawMustache preMustacheText?)* +textNodes = first:preMustacheText? tail:(rawMustache preMustacheText?)* TERM { var ret = []; if(first) { ret.push(first); } @@ -93,37 +250,125 @@ textNodes = first:preMustacheText? tail:(rawMustache preMustacheText?)* return ret; } -rawMustache = rawMustacheEscaped / rawMustacheUnescaped -rawMustacheUnescaped = '{{' _ m:mustacheContent _ '}}' { m.forced = true; return m; } -rawMustacheEscaped = '{{{' _ m:mustacheContent _ '}}}' { m.forced = true; m.escaped = true; return m; } +rawMustache = rawMustacheUnescaped / rawMustacheEscaped + +rawMustacheSingle + = singleOpen _ m:inMustache _ singleClose { m.escaped = true; return m; } -preMustacheText = a:[^{\uEFFF]+ { return a.join(''); } +rawMustacheEscaped + = doubleOpen _ m:inMustache _ doubleClose { m.escaped = true; return m; } +rawMustacheUnescaped + = tripleOpen _ m:inMustache _ tripleClose { m.escaped = false; return m; } -equalSign = "==" _ { return true; } / "=" _ { return false; } +preMustacheText + = a:[^{\uEFFF]+ { return new Handlebars.AST.ContentNode(a.join('')); } -// TODO: how to DRY this? -htmlTag - = h:htmlTagName t:attrShortcuts? { return { type: 'html', tagName: h, attrs:(t||{}) }; } - / t:attrShortcuts { return { type: 'html', tagName: null, attrs: t }; } +// Support for div#id.whatever{ bindAttr whatever="asd" } +inTagMustache = rawMustacheSingle / rawMustacheUnescaped / rawMustacheEscaped -attrShortcuts -= id:idShortcut classes:classShortcut* { - var ret = { id: id }; - var classString = classes.join(' '); - if(classString) { - ret['class'] = classString; +singleOpen = '{' +doubleOpen = '{{' +tripleOpen = '{{{' +singleClose = '}' +doubleClose = '}}' +tripleClose = '}}}' + +// Returns whether the mustache should be escaped. +equalSign = "==" ' '? { return false; } / "=" ' '? { return true; } + +// #div.clasdsd{ bindAttr class="funky" } attr="whatever" Hello +htmlTagAndOptionalAttributes + = h:(h:htmlTagName s:shorthandAttributes? m:inTagMustache* f:fullAttribute* { return [h, s, m, f]; } + / s:shorthandAttributes m:inTagMustache* f:fullAttribute* { return [null, s, m, f] } ) +{ + var tagName = h[0] || 'div', + shorthandAttributes = h[1] || [], + inTagMustaches = h[2], + fullAttributes = h[3], + id = shorthandAttributes[0], + classes = shorthandAttributes[1]; + + var tagOpenContent = []; + tagOpenContent.push(new Handlebars.AST.ContentNode('<' + tagName)); + + if(id) { + tagOpenContent.push(new Handlebars.AST.ContentNode(' id="' + id + '"')); } - return ret; + + if(classes && classes.length) { + tagOpenContent.push(new Handlebars.AST.ContentNode(' class="' + classes.join(' ') + '"')); + } + + // Pad in tag mustaches with spaces. + for(var i = 0; i < inTagMustaches.length; ++i) { + tagOpenContent.push(new Handlebars.AST.ContentNode(' ')); + tagOpenContent.push(inTagMustaches[i]); + } + + for(var i = 0; i < fullAttributes.length; ++i) { + tagOpenContent = tagOpenContent.concat(fullAttributes[i]); + } + tagOpenContent.push(new Handlebars.AST.ContentNode('>')); + + return [tagOpenContent, new Handlebars.AST.ContentNode('')]; } -/ classes:classShortcut+ { - return { 'class': classes.join(' ') }; +shorthandAttributes + = attributesAtLeastID / attributesAtLeastClass + +attributesAtLeastID + = id:idShorthand classes:classShorthand* { return [id, classes]; } + +attributesAtLeastClass + = classes:classShorthand+ { return [null, classes]; } + +fullAttribute + = ' '+ a:(actionAttribute / boundAttribute / normalAttribute) +{ + return [new Handlebars.AST.ContentNode(' '), a]; } -idShortcut = '#' t:cssIdentifier { return t;} -classShortcut = '.' c:cssIdentifier { return c; } +boundAttributeValueText = s:[A-Za-z.:0-9]+ { return s.join(''); } + +// Value of an action can be an unwrapped string, or a single or double quoted string +actionValue + = quotedActionValue + / id:pathIdNode { return new Handlebars.AST.MustacheNode([id]); } +quotedActionValue = p:('"' inMustache '"' / "'" inMustache "'") { return p[1]; } + +actionAttribute + = event:knownEvent '=' mustacheNode:actionValue +{ + // Unshift the action helper and augment the hash + return unshiftParam(mustacheNode, 'action', [['on', new Handlebars.AST.StringNode(event)]]); +} + +boundAttribute + = key:key '=' value:boundAttributeValueText +{ + var hashNode = new Handlebars.AST.HashNode([[key, new Handlebars.AST.StringNode(value)]]); + var params = [new Handlebars.AST.IdNode(['bindAttr'])]; + + return new Handlebars.AST.MustacheNode(params, hashNode); +} + +normalAttribute + = key:key '=' value:string +{ + var s = key + '=' + '"' + value + '"'; + return new Handlebars.AST.ContentNode(s); +} + +attributeName = a:attributeChar* { return a.join(''); } +attributeValue = string / param + + +attributeChar = alpha / [0-9] /'_' / '-' + +idShorthand = '#' t:cssIdentifier { return t;} +classShorthand = '.' c:cssIdentifier { return c; } cssIdentifier = ident @@ -157,6 +402,15 @@ htmlTagName "a valid HTML tag name" = "h3"/"h2"/"h1"/"em"/"dt"/"dl"/"dd"/"br"/ "u"/"s"/"q"/"p"/"i"/"b"/"a" +knownEvent "a JS event" = +"touchStart"/"touchMove"/"touchEnd"/"touchCancel"/ +"keyDown"/"keyUp"/"keyPress"/"mouseDown"/"mouseUp"/ +"contextMenu"/"click"/"doubleClick"/"mouseMove"/ +"focusIn"/"focusOut"/"mouseEnter"/"mouseLeave"/ +"submit"/"input"/"change"/"dragStart"/ +"drag"/"dragEnter"/"dragLeave"/ +"dragOver"/"drop"/"dragEnd" + INDENT "INDENT" = "\uEFEF" { return ''; } DEDENT "DEDENT" = "\uEFFE" { return ''; } TERM "TERM" = "\uEFFF" { return ''; } diff --git a/src/parser-prefix.js b/src/parser-prefix.js index 6997d8f..7e7ae2a 100644 --- a/src/parser-prefix.js +++ b/src/parser-prefix.js @@ -1,3 +1,4 @@ +var Handlebars = require('handlebars'); var Emblem = require('./emblem'); diff --git a/src/translation.coffee b/src/translation.coffee deleted file mode 100644 index e6992d8..0000000 --- a/src/translation.coffee +++ /dev/null @@ -1,122 +0,0 @@ -Handlebars = require 'handlebars' -Emblem = require './emblem' - -# Simple wrapped around a string. Gets passed around for the purpose -# of coalescing adjacent content nodes into one -class ContentStack - constructor: -> - @current = "" - - append: (s) -> - @current += s - - flatten: -> - ret = @current - @current = "" - ret - -# We basically need to "unpeel" Emblem's ast, which consists -# of "statements" of html elements or mustache invocations, both -# of which can have nested content. Handlebars' AST on the other -# hand features ContentNodes (i.e. any static text between -# mustache nodes) and all the nodes for describing a mustache. - -# Handlebar's root ProgramNode statements that we'll be building -# up and nesting over the course of the translation. - -processNodes = (nodes, stack, statements = []) -> - - for node in nodes - if node.type == 'html' - # TODO defaults - tagName = node.tagName || 'div' - - # Coalesce attributes - - classes = node.attrs.classes || [] - classNames = classes.join ' ' - attributesString = "" - attributesString += ' ' + name + '=' + '"' + value + '"' for own name, value of node.attrs || {} - - stack.append """<#{tagName}#{attributesString}>""" - - processNodes(node.nodes || [], stack, statements) - - stack.append """""" - - else if node.type == 'mustache' - - # Create content node if we've stored up some. - c = stack.flatten() - statements.push new Handlebars.AST.ContentNode c if c - - # Check for uppercase special case. - firstChar = node.params[0].charAt(0) - if !node.forced && firstChar == firstChar.toUpperCase() - # TODO defaults - helper = "view" - node.params.unshift helper - - # The Mustache node expects params as an array of IdNode's - params = [] - for param in node.params - # an IdNode has a parts array which includes the period separators - # between identifiers, e.g. ['App', '.', 'Whatever'] - # TODO: clean this up, use grammar parse to do thie splitting - ids = param.split('.') - result = [] - for id in ids - result.push id - result.push '.' - result.pop() - - params.push new Handlebars.AST.IdNode(result) - - # Block - # Need array of hash key value pairs - pairs = [] - pairs.push [k,v] for own k,v of node.hash - hash = null - hash = new Handlebars.AST.HashNode(pairs) if pairs.length - - # Determine whether this is just a single mustache - # or a blockstache. - if node.nodes && node.nodes.length - - closeId = params[0] - substatements = processNodes node.nodes, new ContentStack - statements.push new Handlebars.AST.ProgramNode(substatements, []) - # TODO handle else substatements - openStache = new Handlebars.AST.MustacheNode(params, hash, node.escaped) # TODO reverse polarity on `escape`. whoops. - - statements.push new Handlebars.AST.BlockNode(openStache, statements, [], closeId) - else - # Singlestache - statements.push new Handlebars.AST.MustacheNode(params, hash, node.escaped) # TODO escaped polarity - - else if node instanceof Array - # One liner, could be strings or mustaches - processNodes node, stack, statements - else - # Assume string - stack.append node.toString() - statements - -Emblem.parse = (string) -> - stack = new ContentStack - - # Pre-process, parse, translate. - processed = Emblem.Preprocessor.processSync string - - emblemAST = Emblem.Parser.parse(processed) - - statements = processNodes emblemAST, stack - - # Flush out any remaining static text content - c = stack.flatten() - statements.push new Handlebars.AST.ContentNode c if c - - new Handlebars.AST.ProgramNode(statements, []) - - -