From 773efd0812097a89944c889c595485a5744326f6 Mon Sep 17 00:00:00 2001 From: Lucas Galfaso Date: Mon, 26 Oct 2015 11:58:49 +0100 Subject: [PATCH] fix(isArrayLike): handle jQuery objects of length 0 Closes: #13169 Closes: #13171 --- src/Angular.js | 18 +++++++++--------- test/AngularSpec.js | 5 +++++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/Angular.js b/src/Angular.js index c1d1f8aeb487..637679c3c27c 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -191,11 +191,6 @@ var msie = document.documentMode; -function isNodeList(obj) { - return typeof obj.length == 'number' && - typeof obj.item == 'function'; -} - /** * @private * @param {*} obj @@ -207,15 +202,20 @@ function isArrayLike(obj) { // `null`, `undefined` and `window` are not array-like if (obj == null || isWindow(obj)) return false; - // arrays and strings are array like - if (isArray(obj) || isString(obj)) return true; + // arrays, strings and jQuery/jqLite objects are array like + // * jqLite is either the jQuery or jqLite constructor function + // * we have to check the existance of jqLite first as this method is called + // via the forEach method when constructing the jqLite object in the first place + if (isArray(obj) || isString(obj) || (jqLite && obj instanceof jqLite)) return true; // Support: iOS 8.2 (not reproducible in simulator) // "length" in obj used to prevent JIT error (gh-11508) var length = "length" in Object(obj) && obj.length; - // node lists and objects with suitable length characteristics are array-like - return (isNumber(length) && length >= 0 && (length - 1) in obj) || isNodeList(obj); + // NodeList objects (with `item` method) and + // other objects with suitable length characteristics are array-like + return isNumber(length) && + (length >= 0 && (length - 1) in obj || typeof obj.item == 'function'); } /** diff --git a/test/AngularSpec.js b/test/AngularSpec.js index 35f30500156d..1f482c2903e3 100644 --- a/test/AngularSpec.js +++ b/test/AngularSpec.js @@ -1142,6 +1142,11 @@ describe('angular', function() { forEach(jqObject, function(value, key) { log.push(key + ':' + value.innerHTML); }); expect(log).toEqual(['0:s1', '1:s2']); + + log = []; + jqObject = jqLite(""); + forEach(jqObject.children(), function(value, key) { log.push(key + ':' + value.innerHTML); }); + expect(log).toEqual([]); });