mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-07 10:07:48 +00:00
lodash: Optimize template. [jddalton]
Former-commit-id: 2cd61549491714e6796308ec437fa8dff8fa9a1b
This commit is contained in:
@@ -84,6 +84,7 @@
|
|||||||
'isEqual',
|
'isEqual',
|
||||||
'isFinite',
|
'isFinite',
|
||||||
'setTimeout',
|
'setTimeout',
|
||||||
|
'source',
|
||||||
'templateSettings',
|
'templateSettings',
|
||||||
'toArray',
|
'toArray',
|
||||||
'value',
|
'value',
|
||||||
@@ -112,7 +113,7 @@
|
|||||||
|
|
||||||
// remove whitespace from string literals
|
// remove whitespace from string literals
|
||||||
source = source.replace(/'(?:(?=(\\?))\1.)*?'/g, function(string) {
|
source = source.replace(/'(?:(?=(\\?))\1.)*?'/g, function(string) {
|
||||||
return string.replace(/\[object |else if|function | in |return\s+[\w']|throw |use strict|var |'\\n'|\\n|\s+/g, function(match) {
|
return string.replace(/\[object |else if|function | in |return\s+[\w']|throw |use strict|var |['|]\\n[|']|\\n|\s+/g, function(match) {
|
||||||
return match == false || match == '\\n' ? '' : match;
|
return match == false || match == '\\n' ? '' : match;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
148
lodash.js
148
lodash.js
@@ -8,24 +8,17 @@
|
|||||||
;(function(window, undefined) {
|
;(function(window, undefined) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/** Used to escape and unescape characters in templates */
|
/** Used to escape characters in templates */
|
||||||
var escapes = {
|
var escapes = {
|
||||||
'\\': '\\',
|
'\\': '\\',
|
||||||
"'": "'",
|
"'": "'",
|
||||||
'r': '\r',
|
'\n': 'n',
|
||||||
'n': '\n',
|
'\r': 'r',
|
||||||
't': '\t',
|
'\t': 't',
|
||||||
'u2028': '\u2028',
|
'\u2028': 'u2028',
|
||||||
'u2029': '\u2029'
|
'\u2029': 'u2029'
|
||||||
};
|
};
|
||||||
|
|
||||||
// assign the result as keys and the keys as values
|
|
||||||
(function() {
|
|
||||||
for (var prop in escapes) {
|
|
||||||
escapes[escapes[prop]] = prop;
|
|
||||||
}
|
|
||||||
}());
|
|
||||||
|
|
||||||
/** Detect free variable `exports` */
|
/** Detect free variable `exports` */
|
||||||
var freeExports = typeof exports == 'object' && exports &&
|
var freeExports = typeof exports == 'object' && exports &&
|
||||||
(typeof global == 'object' && global && global == global.global && (window = global), exports);
|
(typeof global == 'object' && global && global == global.global && (window = global), exports);
|
||||||
@@ -36,18 +29,11 @@
|
|||||||
/** Used to restore the original `_` reference in `noConflict` */
|
/** Used to restore the original `_` reference in `noConflict` */
|
||||||
var oldDash = window._;
|
var oldDash = window._;
|
||||||
|
|
||||||
/** Used to replace unescape characters with their escaped counterpart */
|
/** Used to store unique `reUnescaped` regexps */
|
||||||
var reEscaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
|
var reCache = {};
|
||||||
|
|
||||||
/**
|
/** Used to extract a regexp from its `source` property */
|
||||||
* Used for `templateSettings` properties such as `escape`, `evaluate`,
|
var reSource = /^\/([\s\S]+?)\/[gim]+?$/;
|
||||||
* or `interpolate` with explicitly assigned falsey values to ensure no match
|
|
||||||
* is made.
|
|
||||||
*/
|
|
||||||
var reNoMatch = /.^/;
|
|
||||||
|
|
||||||
/** Used to replace escaped characters with their unescaped counterpart */
|
|
||||||
var reUnescaper = /\\(\\|'|r|n|t|u2028|u2029)/g;
|
|
||||||
|
|
||||||
/** Object#toString result shortcuts */
|
/** Object#toString result shortcuts */
|
||||||
var arrayClass = '[object Array]',
|
var arrayClass = '[object Array]',
|
||||||
@@ -65,6 +51,7 @@
|
|||||||
/** Native method shortcuts */
|
/** Native method shortcuts */
|
||||||
var concat = ArrayProto.concat,
|
var concat = ArrayProto.concat,
|
||||||
hasOwnProperty = ObjProto.hasOwnProperty,
|
hasOwnProperty = ObjProto.hasOwnProperty,
|
||||||
|
join = ArrayProto.join,
|
||||||
push = ArrayProto.push,
|
push = ArrayProto.push,
|
||||||
slice = ArrayProto.slice,
|
slice = ArrayProto.slice,
|
||||||
toString = ObjProto.toString;
|
toString = ObjProto.toString;
|
||||||
@@ -225,6 +212,19 @@
|
|||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used by `String#replace` to escape characters for inclusion in compiled
|
||||||
|
* string literals while skipping over template delimiters.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {String} character The the character to escape.
|
||||||
|
* @param {String} [delimiter=''] The delimiter to skip over.
|
||||||
|
* @returns {String} Returns an escaped character or template delimiter.
|
||||||
|
*/
|
||||||
|
function escapeString(character, delimiter) {
|
||||||
|
return delimiter || '\\' + escapes[character];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compiles iteration functions.
|
* Compiles iteration functions.
|
||||||
*
|
*
|
||||||
@@ -324,21 +324,6 @@
|
|||||||
indexOf, Infinity, isArray, isEmpty, Math, slice, stringClass, toString);
|
indexOf, Infinity, isArray, isEmpty, Math, slice, stringClass, toString);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Unescapes characters, previously escaped for inclusion in compiled string
|
|
||||||
* literals, so they may compiled into function bodies.
|
|
||||||
* (Used for template interpolation, evaluation, or escaping)
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {String} string The string to unescape.
|
|
||||||
* @returns {String} Returns the unescaped string.
|
|
||||||
*/
|
|
||||||
function unescape(string) {
|
|
||||||
return string.replace(reUnescaper, function(match, escaped) {
|
|
||||||
return escapes[escaped];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2594,45 +2579,66 @@
|
|||||||
function template(text, data, options) {
|
function template(text, data, options) {
|
||||||
options = defaults(options || {}, lodash.templateSettings);
|
options = defaults(options || {}, lodash.templateSettings);
|
||||||
|
|
||||||
// Compile the template source, taking care to escape characters that
|
var result,
|
||||||
// cannot be included in string literals and then unescape them in code
|
reEscapeDelimiter = options.escape,
|
||||||
// blocks.
|
reEvaluateDelimiter = options.evaluate,
|
||||||
var source = "__p+='" + text
|
reInterpolateDelimiter = options.interpolate,
|
||||||
.replace(reEscaper, function(match) {
|
id = reEscapeDelimiter + reEvaluateDelimiter + reInterpolateDelimiter,
|
||||||
return '\\' + escapes[match];
|
reUnescaped = reCache[id],
|
||||||
})
|
variable = options.variable;
|
||||||
.replace(options.escape || reNoMatch, function(match, code) {
|
|
||||||
return "'+\n((__t=(" + unescape(code) + "))==null?'':_.escape(__t))+\n'";
|
|
||||||
})
|
|
||||||
.replace(options.interpolate || reNoMatch, function(match, code) {
|
|
||||||
return "'+\n((__t=(" + unescape(code) + "))==null?'':__t)+\n'";
|
|
||||||
})
|
|
||||||
.replace(options.evaluate || reNoMatch, function(match, code) {
|
|
||||||
return "';\n" + unescape(code) + ";\n__p+='";
|
|
||||||
}) + "';\n";
|
|
||||||
|
|
||||||
// if a variable is not specified, place data values in local scope
|
// create and cache the `reUnescaped` regexp
|
||||||
if (!options.variable) {
|
if (!reUnescaped) {
|
||||||
source = 'with (object || {}) {\n' + source + '\n}\n';
|
reUnescaped = [];
|
||||||
|
if (reEscapeDelimiter) {
|
||||||
|
reUnescaped.push(reSource.exec(reEscapeDelimiter)[1]);
|
||||||
|
}
|
||||||
|
if (reEvaluateDelimiter) {
|
||||||
|
reUnescaped.push(reSource.exec(reEvaluateDelimiter)[1]);
|
||||||
|
}
|
||||||
|
if (reInterpolateDelimiter) {
|
||||||
|
reUnescaped.push(reSource.exec(reInterpolateDelimiter)[1]);
|
||||||
|
}
|
||||||
|
reUnescaped = reCache[id] = RegExp('\\\\|\'|\\r|\\n|\\t|\\u2028|\\u2029' +
|
||||||
|
(reUnescaped.length ? '|((?:' + reUnescaped.join(')|(?:') + '))' : ''), 'g');
|
||||||
}
|
}
|
||||||
|
|
||||||
source = 'var __t, __j = Array.prototype.join, __p = "";' +
|
// escape characters that cannot be included in string literals
|
||||||
|
text = text.replace(reUnescaped, escapeString);
|
||||||
|
|
||||||
|
if (reEscapeDelimiter) {
|
||||||
|
text = text.replace(reEscapeDelimiter, "'+\n((__t=($1))==null?'':__e(__t))+\n'")
|
||||||
|
}
|
||||||
|
if (reInterpolateDelimiter) {
|
||||||
|
text = text.replace(reInterpolateDelimiter, "'+\n((__t=($1))==null?'':__t)+\n'");
|
||||||
|
}
|
||||||
|
if (reEvaluateDelimiter) {
|
||||||
|
text = text.replace(reEvaluateDelimiter, "';\n$1;\n__p+='");
|
||||||
|
}
|
||||||
|
|
||||||
|
text = "__p='" + text + "';\n";
|
||||||
|
|
||||||
|
// if `options.variable` is not specified, add `data` to the top of the scope chain
|
||||||
|
if (!variable) {
|
||||||
|
text = 'with (object || {}) {\n' + text + '\n}\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
text = 'function(' + (variable || 'object') + '){\n' +
|
||||||
|
'var __p, __t;\n' +
|
||||||
'function print() { __p += __j.call(arguments, "") }\n' +
|
'function print() { __p += __j.call(arguments, "") }\n' +
|
||||||
source + 'return __p';
|
text +
|
||||||
|
'return __p\n}';
|
||||||
|
|
||||||
|
result = Function('_,__e,__j', 'return ' + text)(lodash, escape, join);
|
||||||
|
|
||||||
var render = Function(options.variable || 'object', '_', source);
|
|
||||||
if (data) {
|
if (data) {
|
||||||
return render(data, lodash);
|
return result(data);
|
||||||
}
|
}
|
||||||
|
// provide the compiled function's source via its `toString()` method, in
|
||||||
var template = function(data) {
|
// supported environments, or the `source` property as a convenience for
|
||||||
return render.call(this, data, lodash);
|
// build time precompilation
|
||||||
};
|
result.source = text;
|
||||||
|
return result;
|
||||||
// provide the compiled function source as a convenience for build time precompilation
|
|
||||||
template.source = 'function(' + (options.variable || 'object') + '){\n' + source + '\n}';
|
|
||||||
|
|
||||||
return template;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|||||||
Reference in New Issue
Block a user