diff options
| author | Jacob Thornton <[email protected]> | 2012-01-31 13:18:34 -0800 |
|---|---|---|
| committer | Jacob Thornton <[email protected]> | 2012-01-31 13:18:34 -0800 |
| commit | 0bfbe5058d61ae93d82b09f1dff7eb30dc22426e (patch) | |
| tree | 6ccf3dd9c36ff4b1f6cde5edbce21cdf0de78497 /docs/build/node_modules/hogan.js/lib/compiler.js | |
| parent | 43cbc9440425b7c97c943690eefd14520de708e1 (diff) | |
| parent | 4bd1ba4e0dc44d1d16161306576548f378ab1f8a (diff) | |
| download | bootstrap-0bfbe5058d61ae93d82b09f1dff7eb30dc22426e.tar.xz bootstrap-0bfbe5058d61ae93d82b09f1dff7eb30dc22426e.zip | |
Merge branch '2.0-wip'
Conflicts:
.gitignore
LICENSE
Makefile
bootstrap.css
bootstrap.min.css
docs/assets/js/application.js
docs/assets/js/google-code-prettify/prettify.css
docs/index.html
docs/javascript.html
examples/container-app.html
examples/fluid.html
examples/hero.html
js/bootstrap-alerts.js
js/bootstrap-dropdown.js
js/bootstrap-modal.js
js/bootstrap-popover.js
js/bootstrap-scrollspy.js
js/bootstrap-tabs.js
js/bootstrap-twipsy.js
js/tests/index.html
js/tests/unit/bootstrap-modal.js
js/tests/unit/bootstrap-popover.js
js/tests/unit/bootstrap-tabs.js
lib/forms.less
lib/mixins.less
lib/patterns.less
lib/scaffolding.less
lib/tables.less
Diffstat (limited to 'docs/build/node_modules/hogan.js/lib/compiler.js')
| -rw-r--r-- | docs/build/node_modules/hogan.js/lib/compiler.js | 348 |
1 files changed, 348 insertions, 0 deletions
diff --git a/docs/build/node_modules/hogan.js/lib/compiler.js b/docs/build/node_modules/hogan.js/lib/compiler.js new file mode 100644 index 000000000..2cd65f6fd --- /dev/null +++ b/docs/build/node_modules/hogan.js/lib/compiler.js @@ -0,0 +1,348 @@ +/* + * Copyright 2011 Twitter, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +(function (Hogan) { + // Setup regex assignments + // remove whitespace according to Mustache spec + var rIsWhitespace = /\S/, + rQuot = /\"/g, + rNewline = /\n/g, + rCr = /\r/g, + rSlash = /\\/g, + tagTypes = { + '#': 1, '^': 2, '/': 3, '!': 4, '>': 5, + '<': 6, '=': 7, '_v': 8, '{': 9, '&': 10 + }; + + Hogan.scan = function scan(text, delimiters) { + var len = text.length, + IN_TEXT = 0, + IN_TAG_TYPE = 1, + IN_TAG = 2, + state = IN_TEXT, + tagType = null, + tag = null, + buf = '', + tokens = [], + seenTag = false, + i = 0, + lineStart = 0, + otag = '{{', + ctag = '}}'; + + function addBuf() { + if (buf.length > 0) { + tokens.push(new String(buf)); + buf = ''; + } + } + + function lineIsWhitespace() { + var isAllWhitespace = true; + for (var j = lineStart; j < tokens.length; j++) { + isAllWhitespace = + (tokens[j].tag && tagTypes[tokens[j].tag] < tagTypes['_v']) || + (!tokens[j].tag && tokens[j].match(rIsWhitespace) === null); + if (!isAllWhitespace) { + return false; + } + } + + return isAllWhitespace; + } + + function filterLine(haveSeenTag, noNewLine) { + addBuf(); + + if (haveSeenTag && lineIsWhitespace()) { + for (var j = lineStart, next; j < tokens.length; j++) { + if (!tokens[j].tag) { + if ((next = tokens[j+1]) && next.tag == '>') { + // set indent to token value + next.indent = tokens[j].toString() + } + tokens.splice(j, 1); + } + } + } else if (!noNewLine) { + tokens.push({tag:'\n'}); + } + + seenTag = false; + lineStart = tokens.length; + } + + function changeDelimiters(text, index) { + var close = '=' + ctag, + closeIndex = text.indexOf(close, index), + delimiters = trim( + text.substring(text.indexOf('=', index) + 1, closeIndex) + ).split(' '); + + otag = delimiters[0]; + ctag = delimiters[1]; + + return closeIndex + close.length - 1; + } + + if (delimiters) { + delimiters = delimiters.split(' '); + otag = delimiters[0]; + ctag = delimiters[1]; + } + + for (i = 0; i < len; i++) { + if (state == IN_TEXT) { + if (tagChange(otag, text, i)) { + --i; + addBuf(); + state = IN_TAG_TYPE; + } else { + if (text.charAt(i) == '\n') { + filterLine(seenTag); + } else { + buf += text.charAt(i); + } + } + } else if (state == IN_TAG_TYPE) { + i += otag.length - 1; + tag = tagTypes[text.charAt(i + 1)]; + tagType = tag ? text.charAt(i + 1) : '_v'; + if (tagType == '=') { + i = changeDelimiters(text, i); + state = IN_TEXT; + } else { + if (tag) { + i++; + } + state = IN_TAG; + } + seenTag = i; + } else { + if (tagChange(ctag, text, i)) { + tokens.push({tag: tagType, n: trim(buf), otag: otag, ctag: ctag, + i: (tagType == '/') ? seenTag - ctag.length : i + otag.length}); + buf = ''; + i += ctag.length - 1; + state = IN_TEXT; + if (tagType == '{') { + if (ctag == '}}') { + i++; + } else { + cleanTripleStache(tokens[tokens.length - 1]); + } + } + } else { + buf += text.charAt(i); + } + } + } + + filterLine(seenTag, true); + + return tokens; + } + + function cleanTripleStache(token) { + if (token.n.substr(token.n.length - 1) === '}') { + token.n = token.n.substring(0, token.n.length - 1); + } + } + + function trim(s) { + if (s.trim) { + return s.trim(); + } + + return s.replace(/^\s*|\s*$/g, ''); + } + + function tagChange(tag, text, index) { + if (text.charAt(index) != tag.charAt(0)) { + return false; + } + + for (var i = 1, l = tag.length; i < l; i++) { + if (text.charAt(index + i) != tag.charAt(i)) { + return false; + } + } + + return true; + } + + function buildTree(tokens, kind, stack, customTags) { + var instructions = [], + opener = null, + token = null; + + while (tokens.length > 0) { + token = tokens.shift(); + if (token.tag == '#' || token.tag == '^' || isOpener(token, customTags)) { + stack.push(token); + token.nodes = buildTree(tokens, token.tag, stack, customTags); + instructions.push(token); + } else if (token.tag == '/') { + if (stack.length === 0) { + throw new Error('Closing tag without opener: /' + token.n); + } + opener = stack.pop(); + if (token.n != opener.n && !isCloser(token.n, opener.n, customTags)) { + throw new Error('Nesting error: ' + opener.n + ' vs. ' + token.n); + } + opener.end = token.i; + return instructions; + } else { + instructions.push(token); + } + } + + if (stack.length > 0) { + throw new Error('missing closing tag: ' + stack.pop().n); + } + + return instructions; + } + + function isOpener(token, tags) { + for (var i = 0, l = tags.length; i < l; i++) { + if (tags[i].o == token.n) { + token.tag = '#'; + return true; + } + } + } + + function isCloser(close, open, tags) { + for (var i = 0, l = tags.length; i < l; i++) { + if (tags[i].c == close && tags[i].o == open) { + return true; + } + } + } + + function writeCode(tree) { + return 'i = i || "";var b = i + "";var _ = this;' + walk(tree) + 'return b;'; + } + + Hogan.generate = function (code, text, options) { + if (options.asString) { + return 'function(c,p,i){' + code + ';}'; + } + + return new Hogan.Template(new Function('c', 'p', 'i', code), text, Hogan); + } + + function esc(s) { + return s.replace(rSlash, '\\\\') + .replace(rQuot, '\\\"') + .replace(rNewline, '\\n') + .replace(rCr, '\\r'); + } + + function chooseMethod(s) { + return (~s.indexOf('.')) ? 'd' : 'f'; + } + + function walk(tree) { + var code = ''; + for (var i = 0, l = tree.length; i < l; i++) { + var tag = tree[i].tag; + if (tag == '#') { + code += section(tree[i].nodes, tree[i].n, chooseMethod(tree[i].n), + tree[i].i, tree[i].end, tree[i].otag + " " + tree[i].ctag); + } else if (tag == '^') { + code += invertedSection(tree[i].nodes, tree[i].n, + chooseMethod(tree[i].n)); + } else if (tag == '<' || tag == '>') { + code += partial(tree[i]); + } else if (tag == '{' || tag == '&') { + code += tripleStache(tree[i].n, chooseMethod(tree[i].n)); + } else if (tag == '\n') { + code += text('"\\n"' + (tree.length-1 == i ? '' : ' + i')); + } else if (tag == '_v') { + code += variable(tree[i].n, chooseMethod(tree[i].n)); + } else if (tag === undefined) { + code += text('"' + esc(tree[i]) + '"'); + } + } + return code; + } + + function section(nodes, id, method, start, end, tags) { + return 'if(_.s(_.' + method + '("' + esc(id) + '",c,p,1),' + + 'c,p,0,' + start + ',' + end + ', "' + tags + '")){' + + 'b += _.rs(c,p,' + + 'function(c,p){ var b = "";' + + walk(nodes) + + 'return b;});c.pop();}' + + 'else{b += _.b; _.b = ""};'; + } + + function invertedSection(nodes, id, method) { + return 'if (!_.s(_.' + method + '("' + esc(id) + '",c,p,1),c,p,1,0,0,"")){' + + walk(nodes) + + '};'; + } + + function partial(tok) { + return 'b += _.rp("' + esc(tok.n) + '",c,p,"' + (tok.indent || '') + '");'; + } + + function tripleStache(id, method) { + return 'b += (_.' + method + '("' + esc(id) + '",c,p,0));'; + } + + function variable(id, method) { + return 'b += (_.v(_.' + method + '("' + esc(id) + '",c,p,0)));'; + } + + function text(id) { + return 'b += ' + id + ';'; + } + + Hogan.parse = function(tokens, options) { + options = options || {}; + return buildTree(tokens, '', [], options.sectionTags || []); + }, + + Hogan.cache = {}; + + Hogan.compile = function(text, options) { + // options + // + // asString: false (default) + // + // sectionTags: [{o: '_foo', c: 'foo'}] + // An array of object with o and c fields that indicate names for custom + // section tags. The example above allows parsing of {{_foo}}{{/foo}}. + // + // delimiters: A string that overrides the default delimiters. + // Example: "<% %>" + // + options = options || {}; + + var key = text + '||' + !!options.asString; + + var t = this.cache[key]; + + if (t) { + return t; + } + + t = this.generate(writeCode(this.parse(this.scan(text, options.delimiters), options)), text, options); + return this.cache[key] = t; + }; +})(typeof exports !== 'undefined' ? exports : Hogan); |
