mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-13 20:37:48 +00:00
resolving merge
This commit is contained in:
27
index.html
27
index.html
@@ -245,6 +245,7 @@
|
||||
<li>- <a href="#mixin">mixin</a></li>
|
||||
<li>- <a href="#uniqueId">uniqueId</a></li>
|
||||
<li>- <a href="#escape">escape</a></li>
|
||||
<li>- <a href="#result">result</a></li>
|
||||
<li>- <a href="#template">template</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -1309,12 +1310,24 @@ _.uniqueId('contact_');
|
||||
_.escape('Curly, Larry & Moe');
|
||||
=> "Curly, Larry &amp; Moe"</pre>
|
||||
|
||||
<p id="result">
|
||||
<b class="header">result</b><code>_.result(object, property)</code>
|
||||
<br />
|
||||
If the value of the named property is a function then invoke it; otherwise, return it.
|
||||
</p>
|
||||
<pre>
|
||||
var object = {cheese: 'crumpets', stuff: function(){ return 'nonsense'; }};
|
||||
_.result(object, 'cheese');
|
||||
=> "crumpets"
|
||||
_.result(object, 'stuff');
|
||||
=> "nonsense"</pre>
|
||||
|
||||
<p id="template">
|
||||
<b class="header">template</b><code>_.template(templateString, [context])</code>
|
||||
<br />
|
||||
Compiles JavaScript templates into functions that can be evaluated
|
||||
for rendering. Useful for rendering complicated bits of HTML from JSON
|
||||
data sources. Template functions can both interpolate variables, using<br />
|
||||
data sources. Template functions can both interpolate variables, using
|
||||
<tt><%= … %></tt>, as well as execute arbitrary JavaScript code, with
|
||||
<tt><% … %></tt>. If you wish to interpolate a value, and have
|
||||
it be HTML-escaped, use <tt><%- … %></tt> When you evaluate a template function, pass in a
|
||||
@@ -1368,6 +1381,18 @@ var template = _.template("Hello {{ name }}!");
|
||||
template({name : "Mustache"});
|
||||
=> "Hello Mustache!"</pre>
|
||||
|
||||
<p>
|
||||
Precompiling your templates can be a big help when debugging errors you can't
|
||||
reproduce. This is because precompiled templates can provide line numbers and
|
||||
a stack trace, something that is not possible when compiling templates on the client.
|
||||
<b>template</b> provides the <b>source</b> property on the compiled template
|
||||
function for easy precompilation.
|
||||
</p>
|
||||
|
||||
<pre><script>
|
||||
JST.project = <%= _.template(jstText).source %>;
|
||||
</script></pre>
|
||||
|
||||
|
||||
<h2 id="chaining">Chaining</h2>
|
||||
|
||||
|
||||
@@ -275,6 +275,7 @@ $(document).ready(function() {
|
||||
|
||||
test('collections: size', function() {
|
||||
equal(_.size({one : 1, two : 2, three : 3}), 3, 'can compute the size of an object');
|
||||
equal(_.size([1, 2, 3]), 3, 'can compute the size of an array');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -101,8 +101,8 @@ $(document).ready(function() {
|
||||
setTimeout(throttledIncr, 190);
|
||||
setTimeout(throttledIncr, 220);
|
||||
setTimeout(throttledIncr, 240);
|
||||
_.delay(function(){ ok(counter == 1, "incr was called immediately"); }, 30);
|
||||
_.delay(function(){ ok(counter == 4, "incr was throttled"); start(); }, 400);
|
||||
_.delay(function(){ equal(counter, 1, "incr was called immediately"); }, 30);
|
||||
_.delay(function(){ equal(counter, 4, "incr was throttled"); start(); }, 400);
|
||||
});
|
||||
|
||||
asyncTest("functions: throttle arguments", 2, function() {
|
||||
@@ -122,7 +122,7 @@ $(document).ready(function() {
|
||||
var incr = function(){ counter++; };
|
||||
var throttledIncr = _.throttle(incr, 100);
|
||||
throttledIncr();
|
||||
_.delay(function(){ ok(counter == 1, "incr was called once"); start(); }, 220);
|
||||
_.delay(function(){ equal(counter, 1, "incr was called once"); start(); }, 220);
|
||||
});
|
||||
|
||||
asyncTest("functions: throttle twice", 1, function() {
|
||||
@@ -130,7 +130,7 @@ $(document).ready(function() {
|
||||
var incr = function(){ counter++; };
|
||||
var throttledIncr = _.throttle(incr, 100);
|
||||
throttledIncr(); throttledIncr();
|
||||
_.delay(function(){ ok(counter == 2, "incr was called twice"); start(); }, 220);
|
||||
_.delay(function(){ equal(counter, 2, "incr was called twice"); start(); }, 220);
|
||||
});
|
||||
|
||||
asyncTest("functions: debounce", 1, function() {
|
||||
@@ -143,7 +143,7 @@ $(document).ready(function() {
|
||||
setTimeout(debouncedIncr, 90);
|
||||
setTimeout(debouncedIncr, 120);
|
||||
setTimeout(debouncedIncr, 150);
|
||||
_.delay(function(){ ok(counter == 1, "incr was debounced"); start(); }, 220);
|
||||
_.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 220);
|
||||
});
|
||||
|
||||
asyncTest("functions: debounce asap", 2, function() {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
<body>
|
||||
<div class="underscore-test">
|
||||
<h1 id="qunit-header">Underscore Test Suite</h1>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
@@ -34,6 +35,7 @@
|
||||
|
||||
<script type="text/html" id="template">
|
||||
<%
|
||||
// a comment
|
||||
if (data) { data += 12345; }; %>
|
||||
<li><%= data %></li>
|
||||
</script>
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
$(document).ready(function() {
|
||||
|
||||
module("Utility");
|
||||
var templateSettings = _.templateSettings;
|
||||
|
||||
module("Utility", {
|
||||
|
||||
teardown: function() {
|
||||
_.templateSettings = templateSettings;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
test("utility: noConflict", function() {
|
||||
var underscore = _.noConflict();
|
||||
@@ -152,4 +160,18 @@ $(document).ready(function() {
|
||||
equal(templateWithNull({planet : "world"}), "a null undefined world", "can handle missing escape and evaluate settings");
|
||||
});
|
||||
|
||||
test('_.template handles \\u2028 & \\u2029', function() {
|
||||
var tmpl = _.template('<p>\u2028<%= "\\u2028\\u2029" %>\u2029</p>');
|
||||
strictEqual(tmpl(), '<p>\u2028\u2028\u2029\u2029</p>');
|
||||
});
|
||||
|
||||
test('result calls functions and returns primitives', function() {
|
||||
var obj = {w: '', x: 'x', y: function(){ return this.x; }};
|
||||
strictEqual(_.result(obj, 'w'), '');
|
||||
strictEqual(_.result(obj, 'x'), 'x');
|
||||
strictEqual(_.result(obj, 'y'), 'x');
|
||||
strictEqual(_.result(obj, 'z'), undefined);
|
||||
strictEqual(_.result(null, 'x'), null);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -309,7 +309,7 @@
|
||||
|
||||
// Return the number of elements in an object.
|
||||
_.size = function(obj) {
|
||||
return _.toArray(obj).length;
|
||||
return _.isArray(obj) ? obj.length : _.keys(obj).length;
|
||||
};
|
||||
|
||||
// Array Functions
|
||||
@@ -873,6 +873,14 @@
|
||||
return (''+string).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g,'/');
|
||||
};
|
||||
|
||||
// If the value of the named property is a function then invoke it;
|
||||
// otherwise, return it.
|
||||
_.result = function(object, property) {
|
||||
if (object == null) return null;
|
||||
var value = object[property];
|
||||
return _.isFunction(value) ? value.call(object) : value;
|
||||
};
|
||||
|
||||
// Add your own custom functions to the Underscore object, ensuring that
|
||||
// they're correctly added to the OOP wrapper as well.
|
||||
_.mixin = function(obj) {
|
||||
@@ -902,39 +910,58 @@
|
||||
// guaranteed not to match.
|
||||
var noMatch = /.^/;
|
||||
|
||||
// Certain characters need to be escaped so that they can be put into a
|
||||
// string literal.
|
||||
var escapes = {
|
||||
'\\': '\\',
|
||||
"'": "'",
|
||||
'r': '\r',
|
||||
'n': '\n',
|
||||
't': '\t',
|
||||
'u2028': '\u2028',
|
||||
'u2029': '\u2029'
|
||||
};
|
||||
|
||||
for (var p in escapes) escapes[escapes[p]] = p;
|
||||
var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
|
||||
var unescaper = /\\(\\|'|r|n|t|u2028|u2029)/g;
|
||||
|
||||
// Within an interpolation, evaluation, or escaping, remove HTML escaping
|
||||
// that had been previously added.
|
||||
var unescape = function(code) {
|
||||
return code.replace(/\\\\/g, '\\').replace(/\\'/g, "'");
|
||||
return code.replace(unescaper, function(match, escape) {
|
||||
return escapes[escape];
|
||||
});
|
||||
};
|
||||
|
||||
// JavaScript micro-templating, similar to John Resig's implementation.
|
||||
// Underscore templating handles arbitrary delimiters, preserves whitespace,
|
||||
// and correctly escapes quotes within interpolated code.
|
||||
_.template = function(str, data) {
|
||||
var c = _.templateSettings;
|
||||
var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
|
||||
var settings = _.templateSettings;
|
||||
var source = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
|
||||
'with(obj||{}){__p.push(\'' +
|
||||
str.replace(/\\/g, '\\\\')
|
||||
.replace(/'/g, "\\'")
|
||||
.replace(c.escape || noMatch, function(match, code) {
|
||||
return "',_.escape(" + unescape(code) + "),'";
|
||||
})
|
||||
.replace(c.interpolate || noMatch, function(match, code) {
|
||||
return "'," + unescape(code) + ",'";
|
||||
})
|
||||
.replace(c.evaluate || noMatch, function(match, code) {
|
||||
return "');" + unescape(code).replace(/[\r\n\t]/g, ' ') + ";__p.push('";
|
||||
})
|
||||
.replace(/\r/g, '\\r')
|
||||
.replace(/\n/g, '\\n')
|
||||
.replace(/\t/g, '\\t')
|
||||
+ "');}return __p.join('');";
|
||||
var func = new Function('obj', '_', tmpl);
|
||||
if (data) return func(data, _);
|
||||
return function(data) {
|
||||
return func.call(this, data, _);
|
||||
str
|
||||
.replace(escaper, function(match) {
|
||||
return '\\' + escapes[match];
|
||||
})
|
||||
.replace(settings.escape || noMatch, function(match, code) {
|
||||
return "',\n_.escape(" + unescape(code) + "),\n'";
|
||||
})
|
||||
.replace(settings.interpolate || noMatch, function(match, code) {
|
||||
return "',\n" + unescape(code) + ",\n'";
|
||||
})
|
||||
.replace(settings.evaluate || noMatch, function(match, code) {
|
||||
return "');\n" + unescape(code) + "\n;__p.push('";
|
||||
})
|
||||
+ "');\n}\nreturn __p.join('');";
|
||||
var render = new Function('obj', '_', source);
|
||||
if (data) return render(data, _);
|
||||
var template = function(data) {
|
||||
return render.call(this, data, _);
|
||||
};
|
||||
template.source = 'function(obj){\n' + source + '\n}';
|
||||
return template;
|
||||
};
|
||||
|
||||
// Add a "chain" function, which will delegate to the wrapper.
|
||||
|
||||
Reference in New Issue
Block a user