Просмотр исходного кода

refactor parseTemplate(). address #411

pull/527/head
Saravanan Ganesh 10 лет назад
Родитель
Сommit
ff727be1a2
1 измененных файлов: 80 добавлений и 60 удалений
  1. +80
    -60
      mustache.js

+ 80
- 60
mustache.js Просмотреть файл

@@ -77,6 +77,8 @@
var equalsRe = /\s*=/;
var curlyRe = /\s*\}/;
var tagRe = /#|\^|\/|>|\{|&|=|!/;
var openingTagRe, closingTagRe, closingCurlyRe;
var sections, tokens, spaces, hasTag, noneSpace;

/**
* Breaks up the given `template` string into a tree of tokens. If the `tags`
@@ -104,38 +106,11 @@
if (!template)
return [];

var sections = []; // Stack to hold section tokens
var tokens = []; // Buffer to hold the tokens
var spaces = []; // Indices of whitespace tokens on the current line
var hasTag = false; // Is there a {{tag}} on the current line?
var nonSpace = false; // Is there a non-space char on the current line?

// Strips all whitespace tokens array for the current line
// if there was a {{#tag}} on it and otherwise only space.
function stripSpace () {
if (hasTag && !nonSpace) {
while (spaces.length)
delete tokens[spaces.pop()];
} else {
spaces = [];
}

hasTag = false;
nonSpace = false;
}

var openingTagRe, closingTagRe, closingCurlyRe;
function compileTags (tagsToCompile) {
if (typeof tagsToCompile === 'string')
tagsToCompile = tagsToCompile.split(spaceRe, 2);

if (!isArray(tagsToCompile) || tagsToCompile.length !== 2)
throw new Error('Invalid tags: ' + tagsToCompile);

openingTagRe = new RegExp(escapeRegExp(tagsToCompile[0]) + '\\s*');
closingTagRe = new RegExp('\\s*' + escapeRegExp(tagsToCompile[1]));
closingCurlyRe = new RegExp('\\s*' + escapeRegExp('}' + tagsToCompile[1]));
}
sections = []; // Stack to hold section tokens
tokens = []; // Buffer to hold the tokens
spaces = []; // Indices of whitespace tokens on the current line
hasTag = false; // Is there a {{tag}} on the current line?
nonSpace = false; // Is there a non-space char on the current line?

compileTags(tags || mustache.tags);

@@ -149,22 +124,8 @@
value = scanner.scanUntil(openingTagRe);

if (value) {
for (var i = 0, valueLength = value.length; i < valueLength; ++i) {
chr = value.charAt(i);

if (isWhitespace(chr)) {
spaces.push(tokens.length);
} else {
nonSpace = true;
}

tokens.push([ 'text', chr, start, start + 1 ]);
start += 1;

// Check for whitespace on the current line.
if (chr === '\n')
stripSpace();
}
parseTemplateBetweenTags(value, start);
start = start + value.length;
}

// Match the opening tag.
@@ -178,18 +139,8 @@
scanner.scan(whiteRe);

// Get the tag value.
if (type === '=') {
value = scanner.scanUntil(equalsRe);
scanner.scan(equalsRe);
scanner.scanUntil(closingTagRe);
} else if (type === '{') {
value = scanner.scanUntil(closingCurlyRe);
scanner.scan(curlyRe);
scanner.scanUntil(closingTagRe);
type = '&';
} else {
value = scanner.scanUntil(closingTagRe);
}
value = getTagValue(scanner, type);
type = type == '{' ? '&' : type;

// Match the closing tag.
if (!scanner.scan(closingTagRe))
@@ -226,6 +177,75 @@
return nestTokens(squashTokens(tokens));
}

/**
* Parses text between tags
*/
function parseTemplateBetweenTags (template, start) {
var chr;
for (var i = 0, valueLength = template.length; i < valueLength; ++i) {
chr = template.charAt(i);

if (isWhitespace(chr)) {
spaces.push(tokens.length);
} else {
nonSpace = true;
}

tokens.push([ 'text', chr, start, start + 1 ]);
start += 1;

// Check for whitespace on the current line.
if (chr === '\n') {
// Strips all whitespace tokens array for the current line
// if there was a {{#tag}} on it and otherwise only space.
if (hasTag && !nonSpace) {
while (spaces.length)
delete tokens[spaces.pop()];
} else {
spaces = [];
}

hasTag = false;
nonSpace = false;
}
}
}

/**
* Gets value of the tag give it's type
*/
function getTagValue (scanner, type) {
var value = null;
if (type === '=') {
value = scanner.scanUntil(equalsRe);
scanner.scan(equalsRe);
scanner.scanUntil(closingTagRe);
} else if (type === '{') {
value = scanner.scanUntil(closingCurlyRe);
scanner.scan(curlyRe);
scanner.scanUntil(closingTagRe);
} else {
value = scanner.scanUntil(closingTagRe);
}
return value;
}

/**
* Extracts regular expressions for opening tag, closing tag
* and closing curly tag from tags
*/
function compileTags (tagsToCompile) {
if (typeof tagsToCompile === 'string')
tagsToCompile = tagsToCompile.split(spaceRe, 2);

if (!isArray(tagsToCompile) || tagsToCompile.length !== 2)
throw new Error('Invalid tags: ' + tagsToCompile);

openingTagRe = new RegExp(escapeRegExp(tagsToCompile[0]) + '\\s*');
closingTagRe = new RegExp('\\s*' + escapeRegExp(tagsToCompile[1]));
closingCurlyRe = new RegExp('\\s*' + escapeRegExp('}' + tagsToCompile[1]));
}

/**
* Combines the values of consecutive text tokens in the given `tokens` array
* to a single token.


Загрузка…
Отмена
Сохранить