{I" class:ETI"BundledAsset;FI"logical_path;TI"clientside-haml.js;FI" pathname;TI"^/Applications/XAMPP/xamppfiles/htdocs/polyblock/app/assets/javascripts/clientside-haml.js;FI"content_type;TI"application/javascript;TI" mtime;Tl+URI" length;Ti-:I" digest;TI"%67eafc6db63e29ec4e99627c76674162;FI" source;TI"-:// Generated by CoffeeScript 1.6.2 /* clientside HAML compiler for Javascript and Coffeescript (Version 5) Copyright 2011-12, Ronald Holshausen (https://github.com/uglyog) Released under the MIT License (http://www.opensource.org/licenses/MIT) */ (function() { var Buffer, CodeGenerator, CoffeeCodeGenerator, HamlRuntime, JsCodeGenerator, ProductionJsCodeGenerator, Tokeniser, filters, haml, root, _ref, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; root = this; /* Haml runtime functions. These are used both by the compiler and the generated template functions */ HamlRuntime = { /* Taken from underscore.string.js escapeHTML, and replace the apos entity with character 39 so that it renders correctly in IE7 */ escapeHTML: function(str) { return String(str || '').replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/'/g, "'"); }, /* Provides the implementation to preserve the whitespace as per the HAML reference */ perserveWhitespace: function(str) { var i, out, re, result; re = /<[a-zA-Z]+>[^<]*<\/[a-zA-Z]+>/g; out = ''; i = 0; result = re.exec(str); if (result) { while (result) { out += str.substring(i, result.index); out += result[0].replace(/\n/g, ' '); i = result.index + result[0].length; result = re.exec(str); } out += str.substring(i); } else { out = str; } return out; }, /* Generates a error message including the current line in the source where the error occurred */ templateError: function(lineNumber, characterNumber, currentLine, error) { var i, message; message = error + " at line " + lineNumber + " and character " + characterNumber + ":\n" + currentLine + '\n'; i = 0; while (i < characterNumber - 1) { message += '-'; i++; } message += '^'; return message; }, /* Generates the attributes for the element by combining all the various sources together */ generateElementAttributes: function(context, id, classes, objRefFn, attrList, attrFunction, lineNumber, characterNumber, currentLine, handleError) { var attr, attributes, className, e, ex, hash, html, object, objectId, value; if (handleError == null) { handleError = this._raiseError; } attributes = {}; attributes = this.combineAttributes(attributes, 'id', id); if (classes.length > 0 && classes[0].length > 0) { attributes = this.combineAttributes(attributes, 'class', classes); } if (attrList != null) { for (attr in attrList) { if (!__hasProp.call(attrList, attr)) continue; value = attrList[attr]; attributes = this.combineAttributes(attributes, attr, value); } } if (objRefFn != null) { try { object = objRefFn.call(context, context); if (object != null) { objectId = null; if (object.id != null) { objectId = object.id; } else if (object.get) { objectId = object.get('id'); } attributes = this.combineAttributes(attributes, 'id', objectId); className = null; if (object['class']) { className = object['class']; } else if (object.get) { className = object.get('class'); } attributes = this.combineAttributes(attributes, 'class', className); } } catch (_error) { e = _error; handleError(haml.HamlRuntime.templateError(lineNumber, characterNumber, currentLine, "Error evaluating object reference - " + e)); } } if (attrFunction != null) { try { hash = attrFunction.call(context, context); if (hash != null) { hash = this._flattenHash(null, hash); for (attr in hash) { if (!__hasProp.call(hash, attr)) continue; value = hash[attr]; attributes = this.combineAttributes(attributes, attr, value); } } } catch (_error) { ex = _error; handleError(haml.HamlRuntime.templateError(lineNumber, characterNumber, currentLine, "Error evaluating attribute hash - " + ex)); } } html = ''; if (attributes) { for (attr in attributes) { if (!__hasProp.call(attributes, attr)) continue; if (haml.hasValue(attributes[attr])) { if ((attr === 'id' || attr === 'for') && attributes[attr] instanceof Array) { html += ' ' + attr + '="' + _(attributes[attr]).flatten().join('-') + '"'; } else if (attr === 'class' && attributes[attr] instanceof Array) { html += ' ' + attr + '="' + _(attributes[attr]).flatten().join(' ') + '"'; } else { html += ' ' + attr + '="' + haml.attrValue(attr, attributes[attr]) + '"'; } } } } return html; }, /* Returns a white space string with a length of indent * 2 */ indentText: function(indent) { var i, text; text = ''; i = 0; while (i < indent) { text += ' '; i++; } return text; }, /* Combines the attributes in the attributres hash with the given attribute and value ID, FOR and CLASS attributes will expand to arrays when multiple values are provided */ combineAttributes: function(attributes, attrName, attrValue) { var classes; if (haml.hasValue(attrValue)) { if (attrName === 'id' && attrValue.toString().length > 0) { if (attributes && attributes.id instanceof Array) { attributes.id.unshift(attrValue); } else if (attributes && attributes.id) { attributes.id = [attributes.id, attrValue]; } else if (attributes) { attributes.id = attrValue; } else { attributes = { id: attrValue }; } } else if (attrName === 'for' && attrValue.toString().length > 0) { if (attributes && attributes['for'] instanceof Array) { attributes['for'].unshift(attrValue); } else if (attributes && attributes['for']) { attributes['for'] = [attributes['for'], attrValue]; } else if (attributes) { attributes['for'] = attrValue; } else { attributes = { 'for': attrValue }; } } else if (attrName === 'class') { classes = []; if (attrValue instanceof Array) { classes = classes.concat(attrValue); } else { classes.push(attrValue); } if (attributes && attributes['class']) { attributes['class'] = attributes['class'].concat(classes); } else if (attributes) { attributes['class'] = classes; } else { attributes = { 'class': classes }; } } else if (attrName !== 'id') { attributes || (attributes = {}); attributes[attrName] = attrValue; } } return attributes; }, /* Flattens a deeply nested hash into a single hash by combining the keys with a minus */ _flattenHash: function(rootKey, object) { var attr, flattenedValue, key, keys, newKey, newValue, result, value; result = {}; if (this._isHash(object)) { for (attr in object) { if (!__hasProp.call(object, attr)) continue; value = object[attr]; keys = []; if (rootKey != null) { keys.push(rootKey); } keys.push(attr); key = keys.join('-'); flattenedValue = this._flattenHash(key, value); if (this._isHash(flattenedValue)) { for (newKey in flattenedValue) { if (!__hasProp.call(flattenedValue, newKey)) continue; newValue = flattenedValue[newKey]; result[newKey] = newValue; } } else { result[key] = flattenedValue; } } } else if (rootKey != null) { result[rootKey] = object; } else { result = object; } return result; }, _isHash: function(object) { return (object != null) && typeof object === 'object' && !(object instanceof Array || object instanceof Date); }, _logError: function(message) { return typeof console !== "undefined" && console !== null ? console.log(message) : void 0; }, _raiseError: function(message) { throw new Error(message); }, /* trims the first number of characters from a string */ trim: function(str, chars) { return str.substring(chars); } }; /* HAML Tokiniser: This class is responsible for parsing the haml source into tokens */ Tokeniser = (function() { Tokeniser.prototype.currentLineMatcher = /[^\n]*/g; Tokeniser.prototype.tokenMatchers = { whitespace: /[ \t]+/g, element: /%[a-zA-Z][a-zA-Z0-9]*/g, idSelector: /#[a-zA-Z_\-][a-zA-Z0-9_\-]*/g, classSelector: /\.[a-zA-Z0-9_\-]+/g, identifier: /[a-zA-Z][a-zA-Z0-9\-]*/g, quotedString: /[\'][^\'\n]*[\']/g, quotedString2: /[\"][^\"\n]*[\"]/g, comment: /\-#/g, escapeHtml: /\&=/g, unescapeHtml: /\!=/g, objectReference: /\[[a-zA-Z_@][a-zA-Z0-9_]*\]/g, doctype: /!!!/g, continueLine: /\|\s*\n/g, filter: /:\w+/g }; function Tokeniser(options) { var errorFn, successFn, template, _this = this; this.buffer = null; this.bufferIndex = null; this.prevToken = null; this.token = null; if (options.templateId != null) { template = document.getElementById(options.templateId); if (template) { this.buffer = template.text; this.bufferIndex = 0; } else { throw "Did not find a template with ID '" + options.templateId + "'"; } } else if (options.template != null) { this.buffer = options.template; this.bufferIndex = 0; } else if (options.templateUrl != null) { errorFn = function(jqXHR, textStatus, errorThrown) { throw "Failed to fetch haml template at URL " + options.templateUrl + ": " + textStatus + " " + errorThrown; }; successFn = function(data) { _this.buffer = data; return _this.bufferIndex = 0; }; jQuery.ajax({ url: options.templateUrl, success: successFn, error: errorFn, dataType: 'text', async: false, beforeSend: function(xhr) { return xhr.withCredentials = true; } }); } } /* Try to match a token with the given regexp */ Tokeniser.prototype.matchToken = function(matcher) { var result; matcher.lastIndex = this.bufferIndex; result = matcher.exec(this.buffer); if ((result != null ? result.index : void 0) === this.bufferIndex) { return result[0]; } }; /* Match a multi-character token */ Tokeniser.prototype.matchMultiCharToken = function(matcher, token, tokenStr) { var matched, _ref; if (!this.token) { matched = this.matchToken(matcher); if (matched) { this.token = token; this.token.tokenString = (_ref = typeof tokenStr === "function" ? tokenStr(matched) : void 0) != null ? _ref : matched; this.token.matched = matched; return this.advanceCharsInBuffer(matched.length); } } }; /* Match a single character token */ Tokeniser.prototype.matchSingleCharToken = function(ch, token) { if (!this.token && this.buffer.charAt(this.bufferIndex) === ch) { this.token = token; this.token.tokenString = ch; this.token.matched = ch; return this.advanceCharsInBuffer(1); } }; /* Match and return the next token in the input buffer */ Tokeniser.prototype.getNextToken = function() { var ch, ch1, str; if (isNaN(this.bufferIndex)) { throw haml.HamlRuntime.templateError(this.lineNumber, this.characterNumber, this.currentLine, "An internal parser error has occurred in the HAML parser"); } this.prevToken = this.token; this.token = null; if (this.buffer === null || this.buffer.length === this.bufferIndex) { this.token = { eof: true, token: 'EOF' }; } else { this.initLine(); if (!this.token) { ch = this.buffer.charCodeAt(this.bufferIndex); ch1 = this.buffer.charCodeAt(this.bufferIndex + 1); if (ch === 10 || (ch === 13 && ch1 === 10)) { this.token = { eol: true, token: 'EOL' }; if (ch === 13 && ch1 === 10) { this.advanceCharsInBuffer(2); this.token.matched = String.fromCharCode(ch) + String.fromCharCode(ch1); } else { this.advanceCharsInBuffer(1); this.token.matched = String.fromCharCode(ch); } this.characterNumber = 0; this.currentLine = this.getCurrentLine(); } } this.matchMultiCharToken(this.tokenMatchers.whitespace, { ws: true, token: 'WS' }); this.matchMultiCharToken(this.tokenMatchers.continueLine, { continueLine: true, token: 'CONTINUELINE' }); this.matchMultiCharToken(this.tokenMatchers.element, { element: true, token: 'ELEMENT' }, function(matched) { return matched.substring(1); }); this.matchMultiCharToken(this.tokenMatchers.idSelector, { idSelector: true, token: 'ID' }, function(matched) { return matched.substring(1); }); this.matchMultiCharToken(this.tokenMatchers.classSelector, { classSelector: true, token: 'CLASS' }, function(matched) { return matched.substring(1); }); this.matchMultiCharToken(this.tokenMatchers.identifier, { identifier: true, token: 'IDENTIFIER' }); this.matchMultiCharToken(this.tokenMatchers.doctype, { doctype: true, token: 'DOCTYPE' }); this.matchMultiCharToken(this.tokenMatchers.filter, { filter: true, token: 'FILTER' }, function(matched) { return matched.substring(1); }); if (!this.token) { str = this.matchToken(this.tokenMatchers.quotedString); if (!str) { str = this.matchToken(this.tokenMatchers.quotedString2); } if (str) { this.token = { string: true, token: 'STRING', tokenString: str.substring(1, str.length - 1), matched: str }; this.advanceCharsInBuffer(str.length); } } this.matchMultiCharToken(this.tokenMatchers.comment, { comment: true, token: 'COMMENT' }); this.matchMultiCharToken(this.tokenMatchers.escapeHtml, { escapeHtml: true, token: 'ESCAPEHTML' }); this.matchMultiCharToken(this.tokenMatchers.unescapeHtml, { unescapeHtml: true, token: 'UNESCAPEHTML' }); this.matchMultiCharToken(this.tokenMatchers.objectReference, { objectReference: true, token: 'OBJECTREFERENCE' }, function(matched) { return matched.substring(1, matched.length - 1); }); if (!this.token && this.buffer && this.buffer.charAt(this.bufferIndex) === '{') { this.matchJavascriptHash(); } this.matchSingleCharToken('(', { openBracket: true, token: 'OPENBRACKET' }); this.matchSingleCharToken(')', { closeBracket: true, token: 'CLOSEBRACKET' }); this.matchSingleCharToken('=', { equal: true, token: 'EQUAL' }); this.matchSingleCharToken('/', { slash: true, token: 'SLASH' }); this.matchSingleCharToken('!', { exclamation: true, token: 'EXCLAMATION' }); this.matchSingleCharToken('-', { minus: true, token: 'MINUS' }); this.matchSingleCharToken('&', { amp: true, token: 'AMP' }); this.matchSingleCharToken('<', { lt: true, token: 'LT' }); this.matchSingleCharToken('>', { gt: true, token: 'GT' }); this.matchSingleCharToken('~', { tilde: true, token: 'TILDE' }); if (this.token === null) { this.token = { unknown: true, token: 'UNKNOWN', matched: this.buffer.charAt(this.bufferIndex) }; this.advanceCharsInBuffer(1); } } return this.token; }; /* Look ahead a number of tokens and return the token found */ Tokeniser.prototype.lookAhead = function(numberOfTokens) { var bufferIndex, characterNumber, currentLine, currentToken, i, lineNumber, prevToken, token; token = null; if (numberOfTokens > 0) { currentToken = this.token; prevToken = this.prevToken; currentLine = this.currentLine; lineNumber = this.lineNumber; characterNumber = this.characterNumber; bufferIndex = this.bufferIndex; i = 0; while (i++ < numberOfTokens) { token = this.getNextToken(); } this.token = currentToken; this.prevToken = prevToken; this.currentLine = currentLine; this.lineNumber = lineNumber; this.characterNumber = characterNumber; this.bufferIndex = bufferIndex; } return token; }; /* Initilise the line and character counters */ Tokeniser.prototype.initLine = function() { if (!this.currentLine && this.currentLine !== "") { this.currentLine = this.getCurrentLine(); this.lineNumber = 1; return this.characterNumber = 0; } }; /* Returns the current line in the input buffer */ Tokeniser.prototype.getCurrentLine = function(index) { var line; this.currentLineMatcher.lastIndex = this.bufferIndex + (index != null ? index : 0); line = this.currentLineMatcher.exec(this.buffer); if (line) { return line[0]; } else { return ''; } }; /* Returns an error string filled out with the line and character counters */ Tokeniser.prototype.parseError = function(error) { return haml.HamlRuntime.templateError(this.lineNumber, this.characterNumber, this.currentLine, error); }; /* Skips to the end of the line and returns the string that was skipped */ Tokeniser.prototype.skipToEOLorEOF = function() { var contents, line, text; text = ''; if (!(this.token.eof || this.token.eol)) { if (this.token.matched != null) { text += this.token.matched; } this.currentLineMatcher.lastIndex = this.bufferIndex; line = this.currentLineMatcher.exec(this.buffer); if (line && line.index === this.bufferIndex) { contents = (_.str || _).rtrim(line[0]); if ((_.str || _).endsWith(contents, '|')) { text += contents.substring(0, contents.length - 1); this.advanceCharsInBuffer(contents.length - 1); this.getNextToken(); text += this.parseMultiLine(); } else { text += line[0]; this.advanceCharsInBuffer(line[0].length); this.getNextToken(); } } } return text; }; /* Parses a multiline code block and returns the parsed text */ Tokeniser.prototype.parseMultiLine = function() { var contents, line, text; text = ''; while (this.token.continueLine) { this.currentLineMatcher.lastIndex = this.bufferIndex; line = this.currentLineMatcher.exec(this.buffer); if (line && line.index === this.bufferIndex) { contents = (_.str || _).rtrim(line[0]); if ((_.str || _).endsWith(contents, '|')) { text += contents.substring(0, contents.length - 1); this.advanceCharsInBuffer(contents.length - 1); } this.getNextToken(); } } return text; }; /* Advances the input buffer pointer by a number of characters, updating the line and character counters */ Tokeniser.prototype.advanceCharsInBuffer = function(numChars) { var ch, ch1, i; i = 0; while (i < numChars) { ch = this.buffer.charCodeAt(this.bufferIndex + i); ch1 = this.buffer.charCodeAt(this.bufferIndex + i + 1); if (ch === 13 && ch1 === 10) { this.lineNumber++; this.characterNumber = 0; this.currentLine = this.getCurrentLine(i); i++; } else if (ch === 10) { this.lineNumber++; this.characterNumber = 0; this.currentLine = this.getCurrentLine(i); } else { this.characterNumber++; } i++; } return this.bufferIndex += numChars; }; /* Returns the current line and character counters */ Tokeniser.prototype.currentParsePoint = function() { return { lineNumber: this.lineNumber, characterNumber: this.characterNumber, currentLine: this.currentLine }; }; /* Pushes back the current token onto the front of the input buffer */ Tokeniser.prototype.pushBackToken = function() { if (!this.token.eof) { this.bufferIndex -= this.token.matched.length; return this.token = this.prevToken; } }; /* Is the current token an end of line or end of input buffer */ Tokeniser.prototype.isEolOrEof = function() { return this.token.eol || this.token.eof; }; /* Match a Javascript Hash {...} */ Tokeniser.prototype.matchJavascriptHash = function() { var braceCount, ch, chCode, characterNumberStart, currentIndent, i, lineNumberStart; currentIndent = this.calculateCurrentIndent(); i = this.bufferIndex + 1; characterNumberStart = this.characterNumber; lineNumberStart = this.lineNumber; braceCount = 1; while (i < this.buffer.length && (braceCount > 1 || this.buffer.charAt(i) !== '}')) { ch = this.buffer.charAt(i); chCode = this.buffer.charCodeAt(i); if (ch === '{') { braceCount++; i++; } else if (ch === '}') { braceCount--; i++; } else if (chCode === 10 || chCode === 13) { i++; } else { i++; } } if (i === this.buffer.length) { this.characterNumber = characterNumberStart + 1; this.lineNumber = lineNumberStart; throw this.parseError('Error parsing attribute hash - Did not find a terminating "}"'); } else { this.token = { attributeHash: true, token: 'ATTRHASH', tokenString: this.buffer.substring(this.bufferIndex, i + 1), matched: this.buffer.substring(this.bufferIndex, i + 1) }; return this.advanceCharsInBuffer(i - this.bufferIndex + 1); } }; /* Calculate the indent value of the current line */ Tokeniser.prototype.calculateCurrentIndent = function() { var result; this.tokenMatchers.whitespace.lastIndex = 0; result = this.tokenMatchers.whitespace.exec(this.currentLine); if ((result != null ? result.index : void 0) === 0) { return this.calculateIndent(result[0]); } else { return 0; } }; /* Calculate the indent level of the provided whitespace */ Tokeniser.prototype.calculateIndent = function(whitespace) { var i, indent; indent = 0; i = 0; while (i < whitespace.length) { if (whitespace.charCodeAt(i) === 9) { indent += 2; } else { indent++; } i++; } return Math.floor((indent + 1) / 2); }; return Tokeniser; })(); /* Provides buffering between the generated javascript and html contents */ Buffer = (function() { function Buffer(generator) { this.generator = generator; this.buffer = ''; this.outputBuffer = ''; } Buffer.prototype.append = function(str) { if ((this.generator != null) && this.buffer.length === 0) { this.generator.mark(); } if ((str != null ? str.length : void 0) > 0) { return this.buffer += str; } }; Buffer.prototype.appendToOutputBuffer = function(str) { if ((str != null ? str.length : void 0) > 0) { this.flush(); return this.outputBuffer += str; } }; Buffer.prototype.flush = function() { var _ref; if (((_ref = this.buffer) != null ? _ref.length : void 0) > 0) { this.outputBuffer += this.generator.generateFlush(this.buffer); } return this.buffer = ''; }; Buffer.prototype.output = function() { return this.outputBuffer; }; Buffer.prototype.trimWhitespace = function() { var ch, i; if (this.buffer.length > 0) { i = this.buffer.length - 1; while (i > 0) { ch = this.buffer.charAt(i); if (this._isWhitespace(ch)) { i--; } else if (i > 1 && (ch === 'n' || ch === 't') && (this.buffer.charAt(i - 1) === '\\')) { i -= 2; } else { break; } } if (i > 0 && i < this.buffer.length - 1) { return this.buffer = this.buffer.substring(0, i + 1); } else if (i === 0 && this._isWhitespace(this.buffer.charAt(0))) { return this.buffer = ''; } } }; Buffer.prototype._isWhitespace = function(ch) { return ch === ' ' || ch === '\t' || ch === '\n'; }; return Buffer; })(); /* Common code shared across all code generators */ CodeGenerator = (function() { function CodeGenerator() {} CodeGenerator.prototype.embeddedCodeBlockMatcher = /#{([^}]*)}/g; return CodeGenerator; })(); /* Code generator that generates a Javascript function body */ JsCodeGenerator = (function(_super) { __extends(JsCodeGenerator, _super); function JsCodeGenerator(options) { this.options = options; this.outputBuffer = new haml.Buffer(this); } /* Append a line with embedded javascript code */ JsCodeGenerator.prototype.appendEmbeddedCode = function(indentText, expression, escapeContents, perserveWhitespace, currentParsePoint) { this.outputBuffer.flush(); this.outputBuffer.appendToOutputBuffer(indentText + 'try {\n'); this.outputBuffer.appendToOutputBuffer(indentText + ' var value = eval("' + (_.str || _).trim(expression).replace(/"/g, '\\"').replace(/\\n/g, '\\\\n') + '");\n'); this.outputBuffer.appendToOutputBuffer(indentText + ' value = value === null ? "" : value;'); if (escapeContents) { this.outputBuffer.appendToOutputBuffer(indentText + ' html.push(haml.HamlRuntime.escapeHTML(String(value)));\n'); } else if (perserveWhitespace) { this.outputBuffer.appendToOutputBuffer(indentText + ' html.push(haml.HamlRuntime.perserveWhitespace(String(value)));\n'); } else { this.outputBuffer.appendToOutputBuffer(indentText + ' html.push(String(value));\n'); } this.outputBuffer.appendToOutputBuffer(indentText + '} catch (e) {\n'); this.outputBuffer.appendToOutputBuffer(indentText + ' handleError(haml.HamlRuntime.templateError(' + currentParsePoint.lineNumber + ', ' + currentParsePoint.characterNumber + ', "' + this.escapeCode(currentParsePoint.currentLine) + '",\n'); this.outputBuffer.appendToOutputBuffer(indentText + ' "Error evaluating expression - " + e));\n'); return this.outputBuffer.appendToOutputBuffer(indentText + '}\n'); }; /* Initilising the output buffer with any variables or code */ JsCodeGenerator.prototype.initOutput = function() { var _ref; if ((_ref = this.options) != null ? _ref.tolerateFaults : void 0) { this.outputBuffer.appendToOutputBuffer(' var handleError = haml.HamlRuntime._logError;'); } else { this.outputBuffer.appendToOutputBuffer(' var handleError = haml.HamlRuntime._raiseError;'); } return this.outputBuffer.appendToOutputBuffer('var html = [];\nvar hashFunction = null, hashObject = null, objRef = null, objRefFn = null;\nwith (context || {}) {'); }; /* Flush and close the output buffer and return the contents */ JsCodeGenerator.prototype.closeAndReturnOutput = function() { this.outputBuffer.flush(); return this.outputBuffer.output() + ' }\n return html.join("");\n'; }; /* Append a line of code to the output buffer */ JsCodeGenerator.prototype.appendCodeLine = function(line, eol) { this.outputBuffer.flush(); this.outputBuffer.appendToOutputBuffer(HamlRuntime.indentText(this.indent)); this.outputBuffer.appendToOutputBuffer(line); return this.outputBuffer.appendToOutputBuffer(eol); }; /* Does the current line end with a function declaration? */ JsCodeGenerator.prototype.lineMatchesStartFunctionBlock = function(line) { return line.match(/function\s*\((,?\s*\w+)*\)\s*\{\s*$/); }; /* Does the current line end with a starting code block */ JsCodeGenerator.prototype.lineMatchesStartBlock = function(line) { return line.match(/\{\s*$/); }; /* Generate the code to close off a code block */ JsCodeGenerator.prototype.closeOffCodeBlock = function(tokeniser) { if (!(tokeniser.token.minus && tokeniser.matchToken(/\s*\}/g))) { this.outputBuffer.flush(); return this.outputBuffer.appendToOutputBuffer(HamlRuntime.indentText(this.indent) + '}\n'); } }; /* Generate the code to close off a function parameter */ JsCodeGenerator.prototype.closeOffFunctionBlock = function(tokeniser) { if (!(tokeniser.token.minus && tokeniser.matchToken(/\s*\}/g))) { this.outputBuffer.flush(); return this.outputBuffer.appendToOutputBuffer(HamlRuntime.indentText(this.indent) + '});\n'); } }; /* Generate the code for dynamic attributes ({} form) */ JsCodeGenerator.prototype.generateCodeForDynamicAttributes = function(id, classes, attributeList, attributeHash, objectRef, currentParsePoint) { this.outputBuffer.flush(); if (attributeHash.length > 0) { attributeHash = this.replaceReservedWordsInHash(attributeHash); this.outputBuffer.appendToOutputBuffer(' hashFunction = function () { return eval("hashObject = ' + attributeHash.replace(/"/g, '\\"').replace(/\n/g, '\\n') + '"); };\n'); } else { this.outputBuffer.appendToOutputBuffer(' hashFunction = null;\n'); } if (objectRef.length > 0) { this.outputBuffer.appendToOutputBuffer(' objRefFn = function () { return eval("objRef = ' + objectRef.replace(/"/g, '\\"') + '"); };\n'); } else { this.outputBuffer.appendToOutputBuffer(' objRefFn = null;\n'); } return this.outputBuffer.appendToOutputBuffer(' html.push(haml.HamlRuntime.generateElementAttributes(context, "' + id + '", ["' + classes.join('","') + '"], objRefFn, ' + JSON.stringify(attributeList) + ', hashFunction, ' + currentParsePoint.lineNumber + ', ' + currentParsePoint.characterNumber + ', "' + this.escapeCode(currentParsePoint.currentLine) + '", handleError));\n'); }; /* Clean any reserved words in the given hash */ JsCodeGenerator.prototype.replaceReservedWordsInHash = function(hash) { var reservedWord, resultHash, _i, _len, _ref; resultHash = hash; _ref = ['class', 'for']; for (_i = 0, _len = _ref.length; _i < _len; _i++) { reservedWord = _ref[_i]; resultHash = resultHash.replace(reservedWord + ':', '"' + reservedWord + '":'); } return resultHash; }; /* Escape the line so it is safe to put into a javascript string */ JsCodeGenerator.prototype.escapeCode = function(jsStr) { return jsStr.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n').replace(/\r/g, '\\r'); }; /* Generate a function from the function body */ JsCodeGenerator.prototype.generateJsFunction = function(functionBody) { var e; try { return new Function('context', functionBody); } catch (_error) { e = _error; throw "Incorrect embedded code has resulted in an invalid Haml function - " + e + "\nGenerated Function:\n" + functionBody; } }; /* Generate the code required to support a buffer flush */ JsCodeGenerator.prototype.generateFlush = function(bufferStr) { return ' html.push("' + this.escapeCode(bufferStr) + '");\n'; }; /* Set the current indent level */ JsCodeGenerator.prototype.setIndent = function(indent) { return this.indent = indent; }; /* Save the current indent level if required */ JsCodeGenerator.prototype.mark = function() {}; /* Append the text contents to the buffer, expanding any embedded code */ JsCodeGenerator.prototype.appendTextContents = function(text, shouldInterpolate, currentParsePoint, options) { if (options == null) { options = {}; } if (shouldInterpolate && text.match(/#{[^}]*}/)) { return this.interpolateString(text, currentParsePoint, options); } else { return this.outputBuffer.append(this.processText(text, options)); } }; /* Interpolate any embedded code in the text */ JsCodeGenerator.prototype.interpolateString = function(text, currentParsePoint, options) { var index, precheedingChar, precheedingChar2, result; index = 0; result = this.embeddedCodeBlockMatcher.exec(text); while (result) { if (result.index > 0) { precheedingChar = text.charAt(result.index - 1); } if (result.index > 1) { precheedingChar2 = text.charAt(result.index - 2); } if (precheedingChar === '\\' && precheedingChar2 !== '\\') { if (result.index !== 0) { this.outputBuffer.append(this.processText(text.substring(index, result.index - 1), options)); } this.outputBuffer.append(this.processText(result[0]), options); } else { this.outputBuffer.append(this.processText(text.substring(index, result.index)), options); this.appendEmbeddedCode(HamlRuntime.indentText(this.indent + 1), result[1], options.escapeHTML, options.perserveWhitespace, currentParsePoint); } index = this.embeddedCodeBlockMatcher.lastIndex; result = this.embeddedCodeBlockMatcher.exec(text); } if (index < text.length) { return this.outputBuffer.append(this.processText(text.substring(index), options)); } }; /* process text based on escape and preserve flags */ JsCodeGenerator.prototype.processText = function(text, options) { if (options != null ? options.escapeHTML : void 0) { return haml.HamlRuntime.escapeHTML(text); } else if (options != null ? options.perserveWhitespace : void 0) { return haml.HamlRuntime.perserveWhitespace(text); } else { return text; } }; return JsCodeGenerator; })(CodeGenerator); /* Code generator that generates javascript code without runtime evaluation */ ProductionJsCodeGenerator = (function(_super) { __extends(ProductionJsCodeGenerator, _super); function ProductionJsCodeGenerator() { _ref = ProductionJsCodeGenerator.__super__.constructor.apply(this, arguments); return _ref; } /* Append a line with embedded javascript code */ ProductionJsCodeGenerator.prototype.appendEmbeddedCode = function(indentText, expression, escapeContents, perserveWhitespace, currentParsePoint) { this.outputBuffer.flush(); this.outputBuffer.appendToOutputBuffer(indentText + ' value = ' + (_.str || _).trim(expression) + ';\n'); this.outputBuffer.appendToOutputBuffer(indentText + ' value = value === null ? "" : value;'); if (escapeContents) { return this.outputBuffer.appendToOutputBuffer(indentText + ' html.push(haml.HamlRuntime.escapeHTML(String(value)));\n'); } else if (perserveWhitespace) { return this.outputBuffer.appendToOutputBuffer(indentText + ' html.push(haml.HamlRuntime.perserveWhitespace(String(value)));\n'); } else { return this.outputBuffer.appendToOutputBuffer(indentText + ' html.push(String(value));\n'); } }; /* Generate the code for dynamic attributes ({} form) */ ProductionJsCodeGenerator.prototype.generateCodeForDynamicAttributes = function(id, classes, attributeList, attributeHash, objectRef, currentParsePoint) { this.outputBuffer.flush(); if (attributeHash.length > 0) { attributeHash = this.replaceReservedWordsInHash(attributeHash); this.outputBuffer.appendToOutputBuffer(' hashFunction = function () { return ' + attributeHash + '; };\n'); } else { this.outputBuffer.appendToOutputBuffer(' hashFunction = null;\n'); } if (objectRef.length > 0) { this.outputBuffer.appendToOutputBuffer(' objRefFn = function () { return ' + objectRef + '; };\n'); } else { this.outputBuffer.appendToOutputBuffer(' objRefFn = null;\n'); } return this.outputBuffer.appendToOutputBuffer(' html.push(haml.HamlRuntime.generateElementAttributes(context, "' + id + '", ["' + classes.join('","') + '"], objRefFn, ' + JSON.stringify(attributeList) + ', hashFunction, ' + currentParsePoint.lineNumber + ', ' + currentParsePoint.characterNumber + ', "' + this.escapeCode(currentParsePoint.currentLine) + '"));\n'); }; /* Initilising the output buffer with any variables or code */ ProductionJsCodeGenerator.prototype.initOutput = function() { return this.outputBuffer.appendToOutputBuffer(' var html = [];\n' + ' var hashFunction = null, hashObject = null, objRef = null, objRefFn = null, value= null;\n with (context || {}) {\n'); }; return ProductionJsCodeGenerator; })(JsCodeGenerator); /* Code generator that generates a coffeescript function body */ CoffeeCodeGenerator = (function(_super) { __extends(CoffeeCodeGenerator, _super); function CoffeeCodeGenerator(options) { this.options = options; this.outputBuffer = new haml.Buffer(this); } CoffeeCodeGenerator.prototype.appendEmbeddedCode = function(indentText, expression, escapeContents, perserveWhitespace, currentParsePoint) { var indent; this.outputBuffer.flush(); indent = this.calcCodeIndent(); this.outputBuffer.appendToOutputBuffer(indent + "try\n"); this.outputBuffer.appendToOutputBuffer(indent + " exp = CoffeeScript.compile('" + expression.replace(/'/g, "\\'").replace(/\\n/g, '\\\\n') + "', bare: true)\n"); this.outputBuffer.appendToOutputBuffer(indent + " value = eval(exp)\n"); this.outputBuffer.appendToOutputBuffer(indent + " value ?= ''\n"); if (escapeContents) { this.outputBuffer.appendToOutputBuffer(indent + " html.push(haml.HamlRuntime.escapeHTML(String(value)))\n"); } else if (perserveWhitespace) { this.outputBuffer.appendToOutputBuffer(indent + " html.push(haml.HamlRuntime.perserveWhitespace(String(value)))\n"); } else { this.outputBuffer.appendToOutputBuffer(indent + " html.push(String(value))\n"); } this.outputBuffer.appendToOutputBuffer(indent + "catch e \n"); this.outputBuffer.appendToOutputBuffer(indent + " handleError new Error(haml.HamlRuntime.templateError(" + currentParsePoint.lineNumber + ", " + currentParsePoint.characterNumber + ", '" + this.escapeCode(currentParsePoint.currentLine) + "',\n"); return this.outputBuffer.appendToOutputBuffer(indent + " 'Error evaluating expression - ' + e))\n"); }; CoffeeCodeGenerator.prototype.initOutput = function() { var _ref1; if ((_ref1 = this.options) != null ? _ref1.tolerateFaults : void 0) { this.outputBuffer.appendToOutputBuffer('handleError = haml.HamlRuntime._logError\n'); } else { this.outputBuffer.appendToOutputBuffer('handleError = haml.HamlRuntime._raiseError\n'); } return this.outputBuffer.appendToOutputBuffer('html = []\n'); }; CoffeeCodeGenerator.prototype.closeAndReturnOutput = function() { this.outputBuffer.flush(); return this.outputBuffer.output() + 'return html.join("")\n'; }; CoffeeCodeGenerator.prototype.appendCodeLine = function(line, eol) { this.outputBuffer.flush(); this.outputBuffer.appendToOutputBuffer(this.calcCodeIndent()); this.outputBuffer.appendToOutputBuffer((_.str || _).trim(line)); this.outputBuffer.appendToOutputBuffer(eol); return this.prevCodeIndent = this.indent; }; CoffeeCodeGenerator.prototype.lineMatchesStartFunctionBlock = function(line) { return line.match(/\) [\-=]>\s*$/); }; CoffeeCodeGenerator.prototype.lineMatchesStartBlock = function(line) { return true; }; CoffeeCodeGenerator.prototype.closeOffCodeBlock = function(tokeniser) { return this.outputBuffer.flush(); }; CoffeeCodeGenerator.prototype.closeOffFunctionBlock = function(tokeniser) { return this.outputBuffer.flush(); }; CoffeeCodeGenerator.prototype.generateCodeForDynamicAttributes = function(id, classes, attributeList, attributeHash, objectRef, currentParsePoint) { var indent; this.outputBuffer.flush(); indent = this.calcCodeIndent(); if (attributeHash.length > 0) { attributeHash = this.replaceReservedWordsInHash(attributeHash); this.outputBuffer.appendToOutputBuffer(indent + "hashFunction = () -> s = CoffeeScript.compile('" + attributeHash.replace(/'/g, "\\'").replace(/\n/g, '\\n') + "', bare: true); eval 'hashObject = ' + s\n"); } else { this.outputBuffer.appendToOutputBuffer(indent + "hashFunction = null\n"); } if (objectRef.length > 0) { this.outputBuffer.appendToOutputBuffer(indent + "objRefFn = () -> s = CoffeeScript.compile('" + objectRef.replace(/'/g, "\\'") + "', bare: true); eval 'objRef = ' + s\n"); } else { this.outputBuffer.appendToOutputBuffer(indent + "objRefFn = null\n"); } return this.outputBuffer.appendToOutputBuffer(indent + "html.push(haml.HamlRuntime.generateElementAttributes(this, '" + id + "', ['" + classes.join("','") + "'], objRefFn ? null, " + JSON.stringify(attributeList) + ", hashFunction ? null, " + currentParsePoint.lineNumber + ", " + currentParsePoint.characterNumber + ", '" + this.escapeCode(currentParsePoint.currentLine) + "', handleError))\n"); }; CoffeeCodeGenerator.prototype.replaceReservedWordsInHash = function(hash) { var reservedWord, resultHash, _i, _len, _ref1; resultHash = hash; _ref1 = ['class', 'for']; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { reservedWord = _ref1[_i]; resultHash = resultHash.replace(reservedWord + ':', "'" + reservedWord + "':"); } return resultHash; }; /* Escapes the string for insertion into the generated code. Embedded code blocks in strings must not be escaped */ CoffeeCodeGenerator.prototype.escapeCode = function(str) { var index, outString, precheedingChar, precheedingChar2, result; outString = ''; index = 0; result = this.embeddedCodeBlockMatcher.exec(str); while (result) { if (result.index > 0) { precheedingChar = str.charAt(result.index - 1); } if (result.index > 1) { precheedingChar2 = str.charAt(result.index - 2); } if (precheedingChar === '\\' && precheedingChar2 !== '\\') { if (result.index !== 0) { outString += this._escapeText(str.substring(index, result.index - 1)); } outString += this._escapeText('\\' + result[0]); } else { outString += this._escapeText(str.substring(index, result.index)); outString += result[0]; } index = this.embeddedCodeBlockMatcher.lastIndex; result = this.embeddedCodeBlockMatcher.exec(str); } if (index < str.length) { outString += this._escapeText(str.substring(index)); } return outString; }; CoffeeCodeGenerator.prototype._escapeText = function(text) { return text.replace(/\\/g, '\\\\').replace(/'/g, '\\\'').replace(/"/g, '\\\"').replace(/\n/g, '\\n').replace(/(^|[^\\]{2})\\\\#{/g, '$1\\#{'); }; /* Generates the javascript function by compiling the given code with coffeescript compiler */ CoffeeCodeGenerator.prototype.generateJsFunction = function(functionBody) { var e, fn; try { fn = CoffeeScript.compile(functionBody, { bare: true }); return new Function(fn); } catch (_error) { e = _error; throw "Incorrect embedded code has resulted in an invalid Haml function - " + e + "\nGenerated Function:\n" + fn; } }; CoffeeCodeGenerator.prototype.generateFlush = function(bufferStr) { return this.calcCodeIndent() + "html.push('" + this.escapeCode(bufferStr) + "')\n"; }; CoffeeCodeGenerator.prototype.setIndent = function(indent) { return this.indent = indent; }; CoffeeCodeGenerator.prototype.mark = function() { return this.prevIndent = this.indent; }; CoffeeCodeGenerator.prototype.calcCodeIndent = function() { var codeIndent, i, _i, _ref1, _ref2, _ref3; codeIndent = 0; for (i = _i = 0, _ref1 = this.indent; 0 <= _ref1 ? _i <= _ref1 : _i >= _ref1; i = 0 <= _ref1 ? ++_i : --_i) { if (((_ref2 = this.elementStack[i]) != null ? _ref2.block : void 0) || ((_ref3 = this.elementStack[i]) != null ? _ref3.fnBlock : void 0)) { codeIndent += 1; } } return HamlRuntime.indentText(codeIndent); }; /* Append the text contents to the buffer (interpolating embedded code not required for coffeescript) */ CoffeeCodeGenerator.prototype.appendTextContents = function(text, shouldInterpolate, currentParsePoint, options) { var prefix, suffix; if (shouldInterpolate && text.match(/#{[^}]*}/)) { this.outputBuffer.flush(); prefix = suffix = ''; if (options != null ? options.escapeHTML : void 0) { prefix = 'haml.HamlRuntime.escapeHTML('; suffix = ')'; } else if (options != null ? options.perserveWhitespace : void 0) { prefix = 'haml.HamlRuntime.perserveWhitespace('; suffix = ')'; } return this.outputBuffer.appendToOutputBuffer(this.calcCodeIndent() + 'html.push(' + prefix + '"' + this.escapeCode(text) + '"' + suffix + ')\n'); } else { if (options != null ? options.escapeHTML : void 0) { text = haml.HamlRuntime.escapeHTML(text); } if (options != null ? options.perserveWhitespace : void 0) { text = haml.HamlRuntime.perserveWhitespace(text); } return this.outputBuffer.append(text); } }; return CoffeeCodeGenerator; })(CodeGenerator); /* HAML filters are functions that take 3 parameters contents: The contents block for the filter an array of lines of text generator: The current generator for the compiled function indent: The current indent level currentParsePoint: line and character counters for the current parse point in the input buffer */ filters = { /* Plain filter, just renders the text in the block */ plain: function(contents, generator, indent, currentParsePoint) { var line, _i, _len; for (_i = 0, _len = contents.length; _i < _len; _i++) { line = contents[_i]; generator.appendTextContents(haml.HamlRuntime.indentText(indent - 1) + line + '\n', true, currentParsePoint); } return true; }, /* Wraps the filter block in a javascript tag */ javascript: function(contents, generator, indent, currentParsePoint) { var line, _i, _len; generator.outputBuffer.append(haml.HamlRuntime.indentText(indent) + "\n"); }, /* Wraps the filter block in a style tag */ css: function(contents, generator, indent, currentParsePoint) { var line, _i, _len; generator.outputBuffer.append(haml.HamlRuntime.indentText(indent) + "\n"); }, /* Wraps the filter block in a CDATA tag */ cdata: function(contents, generator, indent, currentParsePoint) { var line, _i, _len; generator.outputBuffer.append(haml.HamlRuntime.indentText(indent) + "\n"); }, /* Preserve filter, preserved blocks of text aren't indented, and newlines are replaced with the HTML escape code for newlines */ preserve: function(contents, generator, indent, currentParsePoint) { var line; generator.appendTextContents(haml.HamlRuntime.indentText(indent), false, currentParsePoint); return generator.appendTextContents(((function() { var _i, _len, _results; _results = []; for (_i = 0, _len = contents.length; _i < _len; _i++) { line = contents[_i]; _results.push(haml.HamlRuntime.trim(line, 2)); } return _results; })()).join(' ') + '\n', true, currentParsePoint); }, /* Escape filter, renders the text in the block with html escaped */ escaped: function(contents, generator, indent, currentParsePoint) { var line, _i, _len; for (_i = 0, _len = contents.length; _i < _len; _i++) { line = contents[_i]; generator.appendTextContents(haml.HamlRuntime.indentText(indent - 1) + line + '\n', true, currentParsePoint, { escapeHTML: true }); } return true; } }; /* Main haml compiler implemtation */ haml = { /* Compiles the haml provided in the parameters to a Javascipt function Parameter: String: Looks for a haml template in dom with this ID Option Hash: The following options determines how haml sources and compiles the template source - This contains the template in string form sourceId - This contains the element ID in the dom which contains the haml source sourceUrl - This contains the URL where the template can be fetched from outputFormat - This determines what is returned, and has the following values: string - The javascript source code function - A javascript function (default) generator - Which code generator to use javascript (default) coffeescript productionjavascript tolerateErrors - switch the compiler into fault tolerant mode (defaults to false) Returns a javascript function */ compileHaml: function(options) { var codeGenerator, result, tokinser; if (typeof options === 'string') { return this._compileHamlTemplate(options, new haml.JsCodeGenerator()); } else { codeGenerator = (function() { switch (options.generator) { case 'coffeescript': return new haml.CoffeeCodeGenerator(options); case 'productionjavascript': return new haml.ProductionJsCodeGenerator(options); default: return new haml.JsCodeGenerator(options); } })(); if (options.source != null) { tokinser = new haml.Tokeniser({ template: options.source }); } else if (options.sourceId != null) { tokinser = new haml.Tokeniser({ templateId: options.sourceId }); } else if (options.sourceUrl != null) { tokinser = new haml.Tokeniser({ templateUrl: options.sourceUrl }); } else { throw "No template source specified for compileHaml. You need to provide a source, sourceId or sourceUrl option"; } result = this._compileHamlToJs(tokinser, codeGenerator, options); if (options.outputFormat !== 'string') { return codeGenerator.generateJsFunction(result); } else { return "function (context) {\n" + result + "}\n"; } } }, /* Compiles the haml in the script block with ID templateId using the coffeescript generator Returns a javascript function */ compileCoffeeHaml: function(templateId) { return this._compileHamlTemplate(templateId, new haml.CoffeeCodeGenerator()); }, /* Compiles the haml in the passed in string Returns a javascript function */ compileStringToJs: function(string) { var codeGenerator, result; codeGenerator = new haml.JsCodeGenerator(); result = this._compileHamlToJs(new haml.Tokeniser({ template: string }), codeGenerator); return codeGenerator.generateJsFunction(result); }, /* Compiles the haml in the passed in string using the coffeescript generator Returns a javascript function */ compileCoffeeHamlFromString: function(string) { var codeGenerator, result; codeGenerator = new haml.CoffeeCodeGenerator(); result = this._compileHamlToJs(new haml.Tokeniser({ template: string }), codeGenerator); return codeGenerator.generateJsFunction(result); }, /* Compiles the haml in the passed in string Returns the javascript function source This is mainly used for precompiling the haml templates so they can be packaged. */ compileHamlToJsString: function(string) { var result; result = 'function (context) {\n'; result += this._compileHamlToJs(new haml.Tokeniser({ template: string }), new haml.JsCodeGenerator()); return result += '}\n'; }, _compileHamlTemplate: function(templateId, codeGenerator) { var fn, result; haml.cache || (haml.cache = {}); if (haml.cache[templateId]) { return haml.cache[templateId]; } result = this._compileHamlToJs(new haml.Tokeniser({ templateId: templateId }), codeGenerator); fn = codeGenerator.generateJsFunction(result); haml.cache[templateId] = fn; return fn; }, _compileHamlToJs: function(tokeniser, generator, options) { var e, indent; if (options == null) { options = {}; } generator.elementStack = []; generator.initOutput(); tokeniser.getNextToken(); while (!tokeniser.token.eof) { if (!tokeniser.token.eol) { try { indent = this._whitespace(tokeniser); generator.setIndent(indent); if (tokeniser.token.eol) { generator.outputBuffer.append(HamlRuntime.indentText(indent) + tokeniser.token.matched); tokeniser.getNextToken(); } else if (tokeniser.token.doctype) { this._doctype(tokeniser, indent, generator); } else if (tokeniser.token.exclamation) { this._ignoredLine(tokeniser, indent, generator.elementStack, generator); } else if (tokeniser.token.equal || tokeniser.token.escapeHtml || tokeniser.token.unescapeHtml || tokeniser.token.tilde) { this._embeddedJs(tokeniser, indent, generator.elementStack, { innerWhitespace: true }, generator); } else if (tokeniser.token.minus) { this._jsLine(tokeniser, indent, generator.elementStack, generator); } else if (tokeniser.token.comment || tokeniser.token.slash) { this._commentLine(tokeniser, indent, generator.elementStack, generator); } else if (tokeniser.token.amp) { this._escapedLine(tokeniser, indent, generator.elementStack, generator); } else if (tokeniser.token.filter) { this._filter(tokeniser, indent, generator, options); } else { this._templateLine(tokeniser, generator.elementStack, indent, generator, options); } } catch (_error) { e = _error; this._handleError(options, { skipTo: true }, tokeniser, e); } } else { generator.outputBuffer.append(tokeniser.token.matched); tokeniser.getNextToken(); } } this._closeElements(0, generator.elementStack, tokeniser, generator); return generator.closeAndReturnOutput(); }, _doctype: function(tokeniser, indent, generator) { var contents, params; if (tokeniser.token.doctype) { generator.outputBuffer.append(HamlRuntime.indentText(indent)); tokeniser.getNextToken(); if (tokeniser.token.ws) { tokeniser.getNextToken(); } contents = tokeniser.skipToEOLorEOF(); if (contents && contents.length > 0) { params = contents.split(/\s+/); switch (params[0]) { case 'XML': if (params.length > 1) { generator.outputBuffer.append(""); } else { generator.outputBuffer.append(""); } break; case 'Strict': generator.outputBuffer.append(''); break; case 'Frameset': generator.outputBuffer.append(''); break; case '5': generator.outputBuffer.append(''); break; case '1.1': generator.outputBuffer.append(''); break; case 'Basic': generator.outputBuffer.append(''); break; case 'Mobile': generator.outputBuffer.append(''); break; case 'RDFa': generator.outputBuffer.append(''); } } else { generator.outputBuffer.append(''); } generator.outputBuffer.append(this._newline(tokeniser)); return tokeniser.getNextToken(); } }, _filter: function(tokeniser, indent, generator, options) { var filter, filterBlock, i, line; if (tokeniser.token.filter) { filter = tokeniser.token.tokenString; if (!haml.filters[filter]) { this._handleError(options, { skipTo: indent }, tokeniser, tokeniser.parseError("Filter '" + filter + "' not registered. Filter functions need to be added to 'haml.filters'.")); return; } tokeniser.skipToEOLorEOF(); tokeniser.getNextToken(); i = haml._whitespace(tokeniser); filterBlock = []; while (!tokeniser.token.eof && i > indent) { tokeniser.pushBackToken(); line = tokeniser.skipToEOLorEOF(); filterBlock.push(HamlRuntime.trim(line, 2 * indent)); tokeniser.getNextToken(); i = haml._whitespace(tokeniser); } haml.filters[filter](filterBlock, generator, indent, tokeniser.currentParsePoint()); return tokeniser.pushBackToken(); } }, _commentLine: function(tokeniser, indent, elementStack, generator) { var contents, i; if (tokeniser.token.comment) { tokeniser.skipToEOLorEOF(); tokeniser.getNextToken(); i = this._whitespace(tokeniser); while (!tokeniser.token.eof && i > indent) { tokeniser.skipToEOLorEOF(); tokeniser.getNextToken(); i = this._whitespace(tokeniser); } if (i > 0) { return tokeniser.pushBackToken(); } } else if (tokeniser.token.slash) { haml._closeElements(indent, elementStack, tokeniser, generator); generator.outputBuffer.append(HamlRuntime.indentText(indent)); generator.outputBuffer.append("' + elementStack[indent].eol); } else if (elementStack[indent].htmlConditionalComment) { generator.outputBuffer.append(HamlRuntime.indentText(indent) + '' + elementStack[indent].eol); } else if (elementStack[indent].block) { generator.closeOffCodeBlock(tokeniser); } else if (elementStack[indent].fnBlock) { generator.closeOffFunctionBlock(tokeniser); } else { innerWhitespace = !elementStack[indent].tagOptions || elementStack[indent].tagOptions.innerWhitespace; if (innerWhitespace) { generator.outputBuffer.append(HamlRuntime.indentText(indent)); } else { generator.outputBuffer.trimWhitespace(); } generator.outputBuffer.append(''); outerWhitespace = !elementStack[indent].tagOptions || elementStack[indent].tagOptions.outerWhitespace; if (haml._parentInnerWhitespace(elementStack, indent) && outerWhitespace) { generator.outputBuffer.append('\n'); } } elementStack[indent] = null; return generator.mark(); } }, _closeElements: function(indent, elementStack, tokeniser, generator) { var i, _results; i = elementStack.length - 1; _results = []; while (i >= indent) { _results.push(this._closeElement(i--, elementStack, tokeniser, generator)); } return _results; }, _openElement: function(currentParsePoint, indent, identifier, id, classes, objectRef, attributeList, attributeHash, elementStack, tagOptions, generator) { var element, parentInnerWhitespace, tagOuterWhitespace; element = identifier.length === 0 ? "div" : identifier; parentInnerWhitespace = this._parentInnerWhitespace(elementStack, indent); tagOuterWhitespace = !tagOptions || tagOptions.outerWhitespace; if (!tagOuterWhitespace) { generator.outputBuffer.trimWhitespace(); } if (indent > 0 && parentInnerWhitespace && tagOuterWhitespace) { generator.outputBuffer.append(HamlRuntime.indentText(indent)); } generator.outputBuffer.append('<' + element); if (attributeHash.length > 0 || objectRef.length > 0) { generator.generateCodeForDynamicAttributes(id, classes, attributeList, attributeHash, objectRef, currentParsePoint); } else { generator.outputBuffer.append(HamlRuntime.generateElementAttributes(null, id, classes, null, attributeList, null, currentParsePoint.lineNumber, currentParsePoint.characterNumber, currentParsePoint.currentLine)); } if (tagOptions.selfClosingTag) { generator.outputBuffer.append("/>"); if (tagOptions.outerWhitespace) { return generator.outputBuffer.append("\n"); } } else { generator.outputBuffer.append(">"); elementStack[indent] = { tag: element, tagOptions: tagOptions }; if (tagOptions.innerWhitespace) { return generator.outputBuffer.append("\n"); } } }, _isSelfClosingTag: function(tag) { return tag === 'meta' || tag === 'img' || tag === 'link' || tag === 'script' || tag === 'br' || tag === 'hr'; }, _tagHasContents: function(indent, tokeniser) { var nextToken; if (!tokeniser.isEolOrEof()) { return true; } else { nextToken = tokeniser.lookAhead(1); return nextToken.ws && nextToken.tokenString.length / 2 > indent; } }, _parentInnerWhitespace: function(elementStack, indent) { return indent === 0 || (!elementStack[indent - 1] || !elementStack[indent - 1].tagOptions || elementStack[indent - 1].tagOptions.innerWhitespace); }, _lineHasElement: function(identifier, id, classes) { return identifier.length > 0 || id.length > 0 || classes.length > 0; }, hasValue: function(value) { return (value != null) && value !== false; }, attrValue: function(attr, value) { if (attr === 'selected' || attr === 'checked' || attr === 'disabled') { return attr; } else { return value; } }, _whitespace: function(tokeniser) { var indent; indent = 0; if (tokeniser.token.ws) { indent = tokeniser.calculateIndent(tokeniser.token.tokenString); tokeniser.getNextToken(); } return indent; }, _element: function(tokeniser) { var identifier; identifier = ''; if (tokeniser.token.element) { identifier = tokeniser.token.tokenString; tokeniser.getNextToken(); } return identifier; }, _eolOrEof: function(tokeniser) { if (tokeniser.token.eol || tokeniser.token.continueLine) { return tokeniser.getNextToken(); } else if (!tokeniser.token.eof) { throw tokeniser.parseError("Expected EOL or EOF"); } }, _idSelector: function(tokeniser) { var id; id = ''; if (tokeniser.token.idSelector) { id = tokeniser.token.tokenString; tokeniser.getNextToken(); } return id; }, _classSelector: function(tokeniser) { var classes; classes = []; while (tokeniser.token.classSelector) { classes.push(tokeniser.token.tokenString); tokeniser.getNextToken(); } return classes; }, _newline: function(tokeniser) { if (tokeniser.token.eol) { return tokeniser.token.matched; } else if (tokeniser.token.continueLine) { return tokeniser.token.matched.substring(1); } else { return "\n"; } }, _handleError: function(options, action, tokeniser, error) { if (options != null ? options.tolerateFaults : void 0) { console.log(error); if (action != null ? action.skipTo : void 0) { return this._skipToNextLineWithIndent(tokeniser, action.skipTo); } } else { throw error; } }, _skipToNextLineWithIndent: function(tokeniser, indent) { var lineIndent; tokeniser.skipToEOLorEOF(); tokeniser.getNextToken(); lineIndent = this._whitespace(tokeniser); while (lineIndent > indent) { tokeniser.skipToEOLorEOF(); tokeniser.getNextToken(); lineIndent = this._whitespace(tokeniser); } return tokeniser.pushBackToken(); } }; haml.Tokeniser = Tokeniser; haml.Buffer = Buffer; haml.JsCodeGenerator = JsCodeGenerator; haml.ProductionJsCodeGenerator = ProductionJsCodeGenerator; haml.CoffeeCodeGenerator = CoffeeCodeGenerator; haml.HamlRuntime = HamlRuntime; haml.filters = filters; if ((typeof module !== "undefined" && module !== null ? module.exports : void 0) != null) { module.exports = haml; } else { root.haml = haml; } }).call(this); /* //@ sourceMappingURL=haml.map */ ; ;TI"required_assets_digest;TI"%79b63b6e86f87bce8c9c200bba98078a;FI" _version;TI"%01dc9d4cb5b0ece13ed47cc1cabfeb41;F