mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-11 11:27:50 +00:00
Optimize how with-statements are inserted into compiled templates.
Former-commit-id: aabb0b1f8c6e910532464b7a007767801c00a640
This commit is contained in:
96
lodash.js
96
lodash.js
@@ -37,9 +37,9 @@
|
|||||||
var oldDash = window._;
|
var oldDash = window._;
|
||||||
|
|
||||||
/** Used to match empty strings in compiled templates */
|
/** Used to match empty strings in compiled templates */
|
||||||
var reEmptyStringEvaluate = /\b__p \+= '';/g,
|
var reEmptyStringLeading = /\b__p \+= '';/g,
|
||||||
reEmptyStringInterpolate = /\b__p \+= '' \+/g,
|
reEmptyStringMiddle = /\b(__p \+?=) '' \+/g,
|
||||||
reEmptyStringHybrid = /\b__t\) \+\n'';/g;
|
reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
|
||||||
|
|
||||||
/** Used to insert the data object variable into compiled templates */
|
/** Used to insert the data object variable into compiled templates */
|
||||||
var reInsertVariable = /(?:__e|__t = )\(\s*(?![\s"']|this\.)/g;
|
var reInsertVariable = /(?:__e|__t = )\(\s*(?![\s"']|this\.)/g;
|
||||||
@@ -3202,10 +3202,13 @@
|
|||||||
// https://github.com/olado/doT
|
// https://github.com/olado/doT
|
||||||
options || (options = {});
|
options || (options = {});
|
||||||
|
|
||||||
var isEscaping,
|
var endIndex,
|
||||||
|
isEscaping,
|
||||||
isEvaluating,
|
isEvaluating,
|
||||||
isInterpolating,
|
isInterpolating,
|
||||||
|
startIndex,
|
||||||
result,
|
result,
|
||||||
|
useWith,
|
||||||
defaults = lodash.templateSettings,
|
defaults = lodash.templateSettings,
|
||||||
escapeDelimiter = options.escape,
|
escapeDelimiter = options.escape,
|
||||||
evaluateDelimiter = options.evaluate,
|
evaluateDelimiter = options.evaluate,
|
||||||
@@ -3222,7 +3225,6 @@
|
|||||||
if (interpolateDelimiter == null) {
|
if (interpolateDelimiter == null) {
|
||||||
interpolateDelimiter = defaults.interpolate;
|
interpolateDelimiter = defaults.interpolate;
|
||||||
}
|
}
|
||||||
|
|
||||||
// tokenize delimiters to avoid escaping them
|
// tokenize delimiters to avoid escaping them
|
||||||
if (escapeDelimiter) {
|
if (escapeDelimiter) {
|
||||||
isEscaping = text != (text = text.replace(escapeDelimiter, tokenizeEscape));
|
isEscaping = text != (text = text.replace(escapeDelimiter, tokenizeEscape));
|
||||||
@@ -3231,55 +3233,83 @@
|
|||||||
isInterpolating = text != (text = text.replace(interpolateDelimiter, tokenizeInterpolate));
|
isInterpolating = text != (text = text.replace(interpolateDelimiter, tokenizeInterpolate));
|
||||||
}
|
}
|
||||||
if (evaluateDelimiter) {
|
if (evaluateDelimiter) {
|
||||||
|
startIndex = tokenized.length;
|
||||||
isEvaluating = text != (text = text.replace(evaluateDelimiter, tokenizeEvaluate));
|
isEvaluating = text != (text = text.replace(evaluateDelimiter, tokenizeEvaluate));
|
||||||
|
endIndex = tokenized.length - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if `options.variable` is not specified and the template contains "evaluate"
|
||||||
|
// delimiters, inject a with-statement around all "evaluate" delimiters to
|
||||||
|
// add the data object to the top of the scope chain
|
||||||
|
if (!variable) {
|
||||||
|
variable = defaults.variable || lastVariable || 'obj';
|
||||||
|
useWith = isEvaluating;
|
||||||
|
|
||||||
|
if (useWith) {
|
||||||
|
tokenized[startIndex] =
|
||||||
|
tokenized[startIndex].slice(0, 3) +
|
||||||
|
'__with (' + variable + ') {\n' +
|
||||||
|
tokenized[startIndex].slice(3);
|
||||||
|
|
||||||
|
tokenized[endIndex] =
|
||||||
|
tokenized[endIndex].slice(0, -8) +
|
||||||
|
'}__\n' +
|
||||||
|
tokenized[endIndex].slice(-8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// memoize `reDoubleVariable`
|
||||||
|
if (variable != lastVariable) {
|
||||||
|
lastVariable = variable;
|
||||||
|
reDoubleVariable = RegExp('([(\\s])' + variable + '\\.' + variable + '\\b', 'g');
|
||||||
|
}
|
||||||
|
|
||||||
|
var strInsertVariable = '$&' + variable + '.',
|
||||||
|
strDoubleVariable = '$1__d';
|
||||||
|
|
||||||
// escape characters that cannot be included in string literals and
|
// escape characters that cannot be included in string literals and
|
||||||
// detokenize delimiter code snippets
|
// detokenize delimiter code snippets
|
||||||
text = "__p='" + text
|
text = "__p = '" + text
|
||||||
.replace(reUnescapedString, escapeStringChar)
|
.replace(reUnescapedString, escapeStringChar)
|
||||||
.replace(reToken, detokenize) + "';\n";
|
.replace(reToken, detokenize) + "';\n";
|
||||||
|
|
||||||
// clear stored code snippets
|
// clear stored code snippets
|
||||||
tokenized.length = 0;
|
tokenized.length = 0;
|
||||||
|
|
||||||
// strip concating empty strings
|
// find the start and end indexes of the with-statement
|
||||||
if (isInterpolating) {
|
if (useWith) {
|
||||||
text = text.replace(reEmptyStringInterpolate, '__p \+=');
|
startIndex = text.indexOf('__with');
|
||||||
}
|
endIndex = text.indexOf('}__', startIndex + 12);
|
||||||
if (isEvaluating) {
|
|
||||||
text = text.replace(reEmptyStringEvaluate, '');
|
|
||||||
if (isInterpolating) {
|
|
||||||
text = text.replace(reEmptyStringHybrid, '__t);');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!variable) {
|
// inject data object references outside of the with-statement
|
||||||
variable = defaults.variable;
|
text = (useWith ? text.slice(0, startIndex) : text)
|
||||||
|
.replace(reInsertVariable, strInsertVariable)
|
||||||
|
.replace(reDoubleVariable, strDoubleVariable) +
|
||||||
|
(useWith
|
||||||
|
? text.slice(startIndex + 2, endIndex + 1) +
|
||||||
|
text.slice(endIndex + 3)
|
||||||
|
.replace(reInsertVariable, strInsertVariable)
|
||||||
|
.replace(reDoubleVariable, strDoubleVariable)
|
||||||
|
: ''
|
||||||
|
);
|
||||||
|
|
||||||
// if `options.variable` is not specified or the template contains "evaluate"
|
// cleanup compiled code by stripping empty strings
|
||||||
// delimiters, add the data object to the top of the scope chain
|
text = (isEvaluating ? text.replace(reEmptyStringLeading, '') : text)
|
||||||
if (isEvaluating || !variable) {
|
.replace(reEmptyStringMiddle, '$1')
|
||||||
text = 'with (' + variable + ' || {}) {\n' + text + '\n}\n';
|
.replace(reEmptyStringTrailing, '$1;');
|
||||||
}
|
|
||||||
// else insert data object references to avoid using a with-statement
|
|
||||||
else {
|
|
||||||
if (variable != lastVariable) {
|
|
||||||
lastVariable = variable;
|
|
||||||
reDoubleVariable = RegExp('([(\\s])(' + variable + '\\.' + variable + ')\\b', 'g');
|
|
||||||
}
|
|
||||||
text = text
|
|
||||||
.replace(reInsertVariable, '$&' + variable + '.')
|
|
||||||
.replace(reDoubleVariable, '$1($2 || ' + variable + ')');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// wrap function body
|
||||||
text = 'function(' + variable + ') {\n' +
|
text = 'function(' + variable + ') {\n' +
|
||||||
|
(useWith
|
||||||
|
? variable + ' || (' + variable + ' = {});\n'
|
||||||
|
: ''
|
||||||
|
) +
|
||||||
'var __p' +
|
'var __p' +
|
||||||
(isInterpolating
|
(isInterpolating
|
||||||
? ', __t'
|
? ', __t'
|
||||||
: ''
|
: ''
|
||||||
) +
|
) +
|
||||||
|
', __d = ' + variable + '.' + variable + ' || ' + variable +
|
||||||
(isEscaping
|
(isEscaping
|
||||||
? ', __e = _.escape'
|
? ', __e = _.escape'
|
||||||
: ''
|
: ''
|
||||||
|
|||||||
Reference in New Issue
Block a user