| // @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 | |
| } |