| // @param {all} subject |
| // if nodelist, returns an array which generated from the nodelist |
| // if Array, returns the array itself |
| // otherwise, returns an array contains the subject |
| // @param {Array=} host |
| module.exports = function (subject, host) { |
| // false -> [false] |
| // null -> [] |
| // undefined -> makeArray() -> [] |
| if (subject === undefined || subject === null) { |
| return host || [] |
| } |
| |
| // if is already an array |
| if (isArray(subject)) { |
| return host |
| ? host.concat(subject) |
| : subject |
| } |
| |
| host || (host = []) |
| if (isArrayLikeObject(subject)) { |
| // IE fails on collections and <select>.options (refers to <select>) |
| // use subject clone instead of Array.prototype.slice |
| clonePureArray(subject, host) |
| |
| } else { |
| host.push(subject) |
| } |
| |
| return host |
| } |
| |
| var toString = Object.prototype.toString |
| function isArray (subject) { |
| return toString.call(subject) === '[object Array]' |
| } |
| |
| // altered from jQuery |
| function isArrayLikeObject (subject) { |
| var length = subject.length |
| |
| if ( |
| typeof subject === 'function' |
| || Object(subject) !== subject |
| || typeof length !== 'number' |
| // `window` already has a property `length` |
| || 'setInterval' in subject |
| ) { |
| return false |
| } |
| |
| return length === 0 |
| || length > 0 && (length - 1) in subject |
| } |
| |
| /** |
| * clone an object as a pure subject, and ignore non-number properties |
| * @param {Array} subject |
| * @param {Array|Object} host required, receiver which the subject be cloned to |
| */ |
| function clonePureArray (subject, host) { |
| var i = subject.length |
| var start = host.length |
| |
| while (i --) { |
| host[start + i] = subject[i] |
| } |
| |
| return host |
| } |