Add support in _.isEmpty and _.size for jQuery/MooTools DOM query collections.

Former-commit-id: dc834256d09d7a3f2797ba65690961aad00717bf
This commit is contained in:
John-David Dalton
2012-08-12 21:40:46 -07:00
parent 2aa2ea9675
commit 361c91e610
3 changed files with 40 additions and 12 deletions

View File

@@ -43,6 +43,7 @@
'ArrayProto',
'bind',
'callee',
'className',
'compareAscending',
'destValue',
'forIn',
@@ -57,6 +58,7 @@
'isPlainObject',
'methodName',
'noaccum',
'objectClass',
'objectTypes',
'pass',
'properties',

View File

@@ -663,8 +663,8 @@
var factory = Function(
'arrayLikeClasses, ArrayProto, bind, compareAscending, concat, forIn, ' +
'funcClass, hasOwnProperty, identity, indexOf, isArguments, isArray, ' +
'isPlainObject, iteratorBind, objectTypes, nativeKeys, propertyIsEnumerable, ' +
'slice, stringClass, toString',
'isPlainObject, iteratorBind, objectClass, objectTypes, nativeKeys, ' +
'propertyIsEnumerable, slice, stringClass, toString',
'var callee = function(' + args + ') {\n' + iteratorTemplate(data) + '\n};\n' +
'return callee'
);
@@ -672,8 +672,8 @@
return factory(
arrayLikeClasses, ArrayProto, bind, compareAscending, concat, forIn,
funcClass, hasOwnProperty, identity, indexOf, isArguments, isArray,
isPlainObject, iteratorBind, objectTypes, nativeKeys, propertyIsEnumerable,
slice, stringClass, toString
isPlainObject, iteratorBind, objectClass, objectTypes, nativeKeys,
propertyIsEnumerable, slice, stringClass, toString
);
}
@@ -1259,9 +1259,12 @@
'args': 'value',
'init': 'true',
'top':
'if (arrayLikeClasses[toString.call(value)]' +
(noArgsClass ? ' || isArguments(value)' : '') +
') return !value.length',
'var className = toString.call(value), length = value.length;\n' +
'if (arrayLikeClasses[className]' +
(noArgsClass ? ' || isArguments(value)' : '') + ' ||\n' +
' (className == objectClass && length > -1 && length === length >>> 0 &&\n' +
' toString.call(value.splice) == funcClass)' +
') return !length',
'inLoop': {
'object': 'return false'
}
@@ -1726,9 +1729,19 @@
if (!value) {
return 0;
}
return arrayLikeClasses[toString.call(value)] || (noArgsClass && isArguments(value))
? value.length
: keys(value).length;
var className = toString.call(value),
length = value.length;
// return `value.length` for `arguments` objects, arrays, strings, and DOM
// query collections of libraries like jQuery and MooTools
// http://code.google.com/p/fbug/source/browse/branches/firebug1.9/content/firebug/chrome/reps.js?r=12614#653
// http://trac.webkit.org/browser/trunk/Source/WebCore/inspector/InjectedScriptSource.js?rev=125186#L609
if (arrayLikeClasses[className] || (noArgsClass && isArguments(value)) ||
(className == objectClass && length > -1 && length === length >>> 0 &&
toString.call(value.splice) == funcClass)) {
return length;
}
return keys(value).length;
}
/**
@@ -1961,8 +1974,7 @@
' isFunc = typeof methodName == \'function\'',
'inLoop': {
'array':
'result[index] = (isFunc ? methodName : value[methodName])' +
'.apply(value, args)',
'result[index] = (isFunc ? methodName : value[methodName]).apply(value, args)',
'object':
'result' + (isKeysFast ? '[ownIndex] = ' : '.push') +
'((isFunc ? methodName : value[methodName]).apply(value, args))'

View File

@@ -713,6 +713,13 @@
equal(_.isEmpty({ 'length': 0 }), false);
});
test('should work with array-like collections', function() {
function Foo(elements) { Array.prototype.push.apply(this, elements); }
Foo.prototype = { 'splice': Array.prototype.splice };
equal(_.isEmpty(new Foo([])), true);
});
test('should work with `arguments` objects (test in IE < 9)', function() {
equal(_.isEmpty(args), false);
});
@@ -1084,6 +1091,13 @@
equal(_.size({ 'length': 3 }), 1);
});
test('should work with array-like collections', function() {
function Foo(elements) { Array.prototype.push.apply(this, elements); }
Foo.prototype = { 'splice': Array.prototype.splice };
equal(_.size(new Foo([1, 2, 3])), 3);
});
test('should work with `arguments` objects (test in IE < 9)', function() {
equal(_.size(args), 3);
});