Comparing version 1.0.1 to 1.0.2
@@ -5,7 +5,13 @@ # Change Log | ||
## To Be Released | ||
## 1.0.2 - 2015-07-23 | ||
### Fixed | ||
- [Combobox] Filtered options are now updated when the ComboBox receives new props. [#141](https://github.com/nikgraf/belle/issues/141) | ||
## 1.0.1 - 2015-07-20 | ||
### Fixed | ||
- Avoid exception when no Options children are supplied to ComboBox | ||
- [ComboBox] Avoid exception when no Options children are supplied to ComboBox. [#136](https://github.com/nikgraf/belle/issues/136) | ||
## 1.0.0 - 2015-07-15 | ||
### Released the first version of Belle |
@@ -133,3 +133,3 @@ 'use strict'; | ||
inputValue: inputValue, | ||
filteredOptions: this.filterOptions(inputValue), | ||
filteredOptions: this.filterOptions(inputValue, properties.children, properties.maxOptions), | ||
wrapperProps: sanitizeWrapperProps(properties.wrapperProps), | ||
@@ -201,3 +201,14 @@ inputProps: sanitizeInputProps(properties), | ||
value: function componentWillReceiveProps(properties) { | ||
var inputValue = undefined; | ||
if ((0, _utilsHelpers.has)(properties, 'valueLink')) { | ||
inputValue = properties.valueLink.value; | ||
} else if ((0, _utilsHelpers.has)(properties, 'value')) { | ||
inputValue = properties.value; | ||
} else { | ||
inputValue = this.state.inputValue; | ||
} | ||
var newState = { | ||
inputValue: inputValue, | ||
filteredOptions: this.filterOptions(inputValue, properties.children, properties.maxOptions), | ||
wrapperProps: sanitizeWrapperProps(properties.wrapperProps), | ||
@@ -209,10 +220,2 @@ inputProps: sanitizeInputProps(properties), | ||
if ((0, _utilsHelpers.has)(properties, 'valueLink')) { | ||
newState.inputValue = properties.valueLink.value; | ||
newState.filteredOption = this.filterOptions(properties.valueLink.value); | ||
} else if ((0, _utilsHelpers.has)(properties, 'value')) { | ||
newState.inputValue = properties.value; | ||
newState.filteredOption = this.filterOptions(properties.value); | ||
} | ||
this.setState(newState); | ||
@@ -487,3 +490,3 @@ (0, _utilsInjectStyle.removeAllStyles)([this._styleId, this._caretStyleId]); | ||
focusedOptionIndex: undefined, | ||
filteredOptions: this.filterOptions(value) | ||
filteredOptions: this.filterOptions(value, this.props.children, this.props.maxOptions) | ||
}); | ||
@@ -532,3 +535,3 @@ } | ||
} else { | ||
var filteredOptions = this.filterOptions(value); | ||
var filteredOptions = this.filterOptions(value, this.props.children, this.props.maxOptions); | ||
this.setState({ | ||
@@ -552,3 +555,3 @@ inputValue: value, | ||
*/ | ||
value: function filterOptions(inputValue) { | ||
value: function filterOptions(inputValue, options, max) { | ||
var _this = this; | ||
@@ -558,14 +561,14 @@ | ||
var filteredOptions = []; | ||
if (this.props.children.length > 0) { | ||
if (options.length > 0) { | ||
if (inputValue) { | ||
filteredOptions = (0, _utilsHelpers.filter)(this.props.children, function (entry) { | ||
filteredOptions = (0, _utilsHelpers.filter)(options, function (entry) { | ||
return _this.props.filterFunc(inputValue, entry.props.value); | ||
}); | ||
} else { | ||
filteredOptions = (0, _utilsHelpers.map)(this.props.children, function (entry) { | ||
filteredOptions = (0, _utilsHelpers.map)(options, function (entry) { | ||
return entry; | ||
}); | ||
} | ||
if (this.props.maxOptions) { | ||
filteredOptions = filteredOptions.splice(0, this.props.maxOptions); | ||
if (max) { | ||
filteredOptions = filteredOptions.splice(0, max); | ||
} | ||
@@ -572,0 +575,0 @@ } |
@@ -0,1592 +1,342 @@ | ||
// The following helper functions are based on Underscore.js | ||
/** | ||
* Returns true if the object contain the given key. | ||
* | ||
* @param {object} obj - object to be inspected | ||
* @param {string} key - name of the property | ||
*/ | ||
'use strict'; | ||
(function () { | ||
Object.defineProperty(exports, '__esModule', { | ||
value: true | ||
}); | ||
exports.has = has; | ||
exports.omit = omit; | ||
exports.filter = filter; | ||
exports.map = map; | ||
exports.find = find; | ||
exports.isEmpty = isEmpty; | ||
exports.findIndex = findIndex; | ||
exports.first = first; | ||
exports.last = last; | ||
exports.size = size; | ||
exports.some = some; | ||
exports.union = union; | ||
exports.uniqueId = uniqueId; | ||
exports.extend = extend; | ||
exports.flatten = flatten; | ||
// Baseline setup | ||
// -------------- | ||
function has(obj, key) { | ||
return obj !== undefined && obj !== null && Object.prototype.hasOwnProperty.call(obj, key); | ||
} | ||
// Establish the root object, `window` (`self`) in the browser, `global` | ||
// on the server, or `this` in some virtual machines. We use `self` | ||
// instead of `window` for `WebWorker` support. | ||
var root = typeof self === 'object' && self.self === self && self || typeof global === 'object' && global.global === global && global || this; | ||
/** | ||
* Return a copy of the object, filtered to omit the blacklisted keys (or array of keys). | ||
* | ||
* @param {object} obj - object the returned object is based on | ||
* @param {string|string[]} fields - the key or list of keys of the property to omit | ||
*/ | ||
// Save the previous value of the `_` variable. | ||
var previousUnderscore = root._; | ||
// Save bytes in the minified (but not gzipped) version: | ||
var ArrayProto = Array.prototype, | ||
ObjProto = Object.prototype; | ||
// Create quick reference variables for speed access to core prototypes. | ||
var push = ArrayProto.push, | ||
slice = ArrayProto.slice, | ||
toString = ObjProto.toString, | ||
hasOwnProperty = ObjProto.hasOwnProperty; | ||
// All **ECMAScript 5** native function implementations that we hope to use | ||
// are declared here. | ||
var nativeIsArray = Array.isArray, | ||
nativeKeys = Object.keys, | ||
nativeCreate = Object.create; | ||
// Naked function reference for surrogate-prototype-swapping. | ||
var Ctor = function Ctor() {}; | ||
// Create a safe reference to the Underscore object for use below. | ||
var _ = function _(obj) { | ||
if (obj instanceof _) return obj; | ||
if (!(this instanceof _)) return new _(obj); | ||
this._wrapped = obj; | ||
}; | ||
// Export the Underscore object for **Node.js**, with | ||
// backwards-compatibility for their old module API. If we're in | ||
// the browser, add `_` as a global object. | ||
if (typeof exports !== 'undefined') { | ||
if (typeof module !== 'undefined' && module.exports) { | ||
exports = module.exports = _; | ||
function omit(obj, fields) { | ||
if (obj) { | ||
var result = {}; | ||
for (var key in obj) { | ||
if (obj.hasOwnProperty(key) && (!fields || fields.indexOf(key) < 0)) { | ||
result[key] = obj[key]; | ||
} | ||
} | ||
exports._ = _; | ||
} /* else { | ||
root._ = _; | ||
}*/ | ||
// Internal function that returns an efficient (for current engines) version | ||
// of the passed-in callback, to be repeatedly applied in other Underscore | ||
// functions. | ||
var optimizeCb = function optimizeCb(func, context, argCount) { | ||
if (context === void 0) return func; | ||
switch (argCount == null ? 3 : argCount) { | ||
case 1: | ||
return function (value) { | ||
return func.call(context, value); | ||
}; | ||
// The 2-parameter case has been omitted only because no current consumers | ||
// made use of it. | ||
case 3: | ||
return function (value, index, collection) { | ||
return func.call(context, value, index, collection); | ||
}; | ||
case 4: | ||
return function (accumulator, value, index, collection) { | ||
return func.call(context, accumulator, value, index, collection); | ||
}; | ||
} | ||
return function () { | ||
return func.apply(context, arguments); | ||
}; | ||
}; | ||
// A mostly-internal function to generate callbacks that can be applied | ||
// to each element in a collection, returning the desired result — either | ||
// identity, an arbitrary callback, a property matcher, or a property accessor. | ||
var cb = function cb(value, context, argCount) { | ||
if (value == null) return _.identity; | ||
if (_.isFunction(value)) return optimizeCb(value, context, argCount); | ||
if (_.isObject(value)) return _.matcher(value); | ||
return _.property(value); | ||
}; | ||
_.iteratee = function (value, context) { | ||
return cb(value, context, Infinity); | ||
}; | ||
// Similar to ES6's rest param (http://ariya.ofilabs.com/2013/03/es6-and-rest-parameter.html) | ||
// This accumulates the arguments passed into an array, after a given index. | ||
var restArgs = function restArgs(func, startIndex) { | ||
startIndex = startIndex == null ? func.length - 1 : +startIndex; | ||
return function () { | ||
var length = Math.max(arguments.length - startIndex, 0); | ||
var rest = Array(length); | ||
for (var index = 0; index < length; index++) { | ||
rest[index] = arguments[index + startIndex]; | ||
} | ||
switch (startIndex) { | ||
case 0: | ||
return func.call(this, rest); | ||
case 1: | ||
return func.call(this, arguments[0], rest); | ||
case 2: | ||
return func.call(this, arguments[0], arguments[1], rest); | ||
} | ||
var args = Array(startIndex + 1); | ||
for (index = 0; index < startIndex; index++) { | ||
args[index] = arguments[index]; | ||
} | ||
args[startIndex] = rest; | ||
return func.apply(this, args); | ||
}; | ||
}; | ||
// An internal function for creating a new object that inherits from another. | ||
var baseCreate = function baseCreate(prototype) { | ||
if (!_.isObject(prototype)) return {}; | ||
if (nativeCreate) return nativeCreate(prototype); | ||
Ctor.prototype = prototype; | ||
var result = new Ctor(); | ||
Ctor.prototype = null; | ||
return result; | ||
}; | ||
} | ||
} | ||
var property = function property(key) { | ||
return function (obj) { | ||
return obj == null ? void 0 : obj[key]; | ||
}; | ||
}; | ||
/** | ||
* Looks through each value in the list, returning an array of all the values | ||
* that pass a truth test (predicate). | ||
* | ||
* @param {array} iterable - the iterable object to be filtered | ||
* @param {function} predicate - function returning true when provided with an entry as argument | ||
* @param {object} [context] - context for the predicate function call | ||
*/ | ||
// Helper for collection methods to determine whether a collection | ||
// should be iterated as an array or as an object | ||
// Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength | ||
// Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 | ||
var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; | ||
var getLength = property('length'); | ||
var isArrayLike = function isArrayLike(collection) { | ||
var length = getLength(collection); | ||
return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; | ||
}; | ||
// Collection Functions | ||
// -------------------- | ||
// The cornerstone, an `each` implementation, aka `forEach`. | ||
// Handles raw objects in addition to array-likes. Treats all | ||
// sparse array-likes as if they were dense. | ||
_.each = _.forEach = function (obj, iteratee, context) { | ||
iteratee = optimizeCb(iteratee, context); | ||
var i, length; | ||
if (isArrayLike(obj)) { | ||
for (i = 0, length = obj.length; i < length; i++) { | ||
iteratee(obj[i], i, obj); | ||
} | ||
} else { | ||
var keys = _.keys(obj); | ||
for (i = 0, length = keys.length; i < length; i++) { | ||
iteratee(obj[keys[i]], keys[i], obj); | ||
} | ||
} | ||
return obj; | ||
}; | ||
// Return the results of applying the iteratee to each element. | ||
_.map = _.collect = function (obj, iteratee, context) { | ||
iteratee = cb(iteratee, context); | ||
var keys = !isArrayLike(obj) && _.keys(obj), | ||
length = (keys || obj).length, | ||
results = Array(length); | ||
for (var index = 0; index < length; index++) { | ||
var currentKey = keys ? keys[index] : index; | ||
results[index] = iteratee(obj[currentKey], currentKey, obj); | ||
} | ||
return results; | ||
}; | ||
// Create a reducing function iterating left or right. | ||
var createReduce = function createReduce(dir) { | ||
// Optimized iterator function as using arguments.length | ||
// in the main function will deoptimize the, see #1991. | ||
var reducer = function reducer(obj, iteratee, memo, initial) { | ||
var keys = !isArrayLike(obj) && _.keys(obj), | ||
length = (keys || obj).length, | ||
index = dir > 0 ? 0 : length - 1; | ||
if (!initial) { | ||
memo = obj[keys ? keys[index] : index]; | ||
index += dir; | ||
} | ||
for (; index >= 0 && index < length; index += dir) { | ||
var currentKey = keys ? keys[index] : index; | ||
memo = iteratee(memo, obj[currentKey], currentKey, obj); | ||
} | ||
return memo; | ||
}; | ||
return function (obj, iteratee, memo, context) { | ||
var initial = arguments.length >= 3; | ||
return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial); | ||
}; | ||
}; | ||
// **Reduce** builds up a single result from a list of values, aka `inject`, | ||
// or `foldl`. | ||
_.reduce = _.foldl = _.inject = createReduce(1); | ||
// The right-associative version of reduce, also known as `foldr`. | ||
_.reduceRight = _.foldr = createReduce(-1); | ||
// Return the first value which passes a truth test. Aliased as `detect`. | ||
_.find = _.detect = function (obj, predicate, context) { | ||
var key; | ||
if (isArrayLike(obj)) { | ||
key = _.findIndex(obj, predicate, context); | ||
} else { | ||
key = _.findKey(obj, predicate, context); | ||
} | ||
if (key !== void 0 && key !== -1) return obj[key]; | ||
}; | ||
// Return all the elements that pass a truth test. | ||
// Aliased as `select`. | ||
_.filter = _.select = function (obj, predicate, context) { | ||
var results = []; | ||
predicate = cb(predicate, context); | ||
_.each(obj, function (value, index, list) { | ||
if (predicate(value, index, list)) results.push(value); | ||
}); | ||
return results; | ||
}; | ||
// Return all the elements for which a truth test fails. | ||
_.reject = function (obj, predicate, context) { | ||
return _.filter(obj, _.negate(cb(predicate)), context); | ||
}; | ||
// Determine whether all of the elements match a truth test. | ||
// Aliased as `all`. | ||
_.every = _.all = function (obj, predicate, context) { | ||
predicate = cb(predicate, context); | ||
var keys = !isArrayLike(obj) && _.keys(obj), | ||
length = (keys || obj).length; | ||
for (var index = 0; index < length; index++) { | ||
var currentKey = keys ? keys[index] : index; | ||
if (!predicate(obj[currentKey], currentKey, obj)) return false; | ||
} | ||
return true; | ||
}; | ||
// Determine if at least one element in the object matches a truth test. | ||
// Aliased as `any`. | ||
_.some = _.any = function (obj, predicate, context) { | ||
predicate = cb(predicate, context); | ||
var keys = !isArrayLike(obj) && _.keys(obj), | ||
length = (keys || obj).length; | ||
for (var index = 0; index < length; index++) { | ||
var currentKey = keys ? keys[index] : index; | ||
if (predicate(obj[currentKey], currentKey, obj)) return true; | ||
} | ||
return false; | ||
}; | ||
// Determine if the array or object contains a given item (using `===`). | ||
// Aliased as `includes` and `include`. | ||
_.contains = _.includes = _.include = function (obj, item, fromIndex, guard) { | ||
if (!isArrayLike(obj)) obj = _.values(obj); | ||
if (typeof fromIndex != 'number' || guard) fromIndex = 0; | ||
return _.indexOf(obj, item, fromIndex) >= 0; | ||
}; | ||
// Invoke a method (with arguments) on every item in a collection. | ||
_.invoke = restArgs(function (obj, method, args) { | ||
var isFunc = _.isFunction(method); | ||
return _.map(obj, function (value) { | ||
var func = isFunc ? method : value[method]; | ||
return func == null ? func : func.apply(value, args); | ||
}); | ||
}); | ||
// Convenience version of a common use case of `map`: fetching a property. | ||
_.pluck = function (obj, key) { | ||
return _.map(obj, _.property(key)); | ||
}; | ||
// Convenience version of a common use case of `filter`: selecting only objects | ||
// containing specific `key:value` pairs. | ||
_.where = function (obj, attrs) { | ||
return _.filter(obj, _.matcher(attrs)); | ||
}; | ||
// Convenience version of a common use case of `find`: getting the first object | ||
// containing specific `key:value` pairs. | ||
_.findWhere = function (obj, attrs) { | ||
return _.find(obj, _.matcher(attrs)); | ||
}; | ||
// Return the maximum element (or element-based computation). | ||
_.max = function (obj, iteratee, context) { | ||
var result = -Infinity, | ||
lastComputed = -Infinity, | ||
value, | ||
computed; | ||
if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) { | ||
obj = isArrayLike(obj) ? obj : _.values(obj); | ||
for (var i = 0, length = obj.length; i < length; i++) { | ||
value = obj[i]; | ||
if (value > result) { | ||
result = value; | ||
function filter(iterable, predicate, context) { | ||
if (iterable) { | ||
var _ret = (function () { | ||
var result = []; | ||
iterable.forEach(function (obj) { | ||
if (predicate && predicate.call(context, obj)) { | ||
result.push(obj); | ||
} | ||
} | ||
} else { | ||
iteratee = cb(iteratee, context); | ||
_.each(obj, function (v, index, list) { | ||
computed = iteratee(v, index, list); | ||
if (computed > lastComputed || computed === -Infinity && result === -Infinity) { | ||
result = v; | ||
lastComputed = computed; | ||
} | ||
}); | ||
} | ||
return result; | ||
}; | ||
// Return the minimum element (or element-based computation). | ||
_.min = function (obj, iteratee, context) { | ||
var result = Infinity, | ||
lastComputed = Infinity, | ||
value, | ||
computed; | ||
if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) { | ||
obj = isArrayLike(obj) ? obj : _.values(obj); | ||
for (var i = 0, length = obj.length; i < length; i++) { | ||
value = obj[i]; | ||
if (value < result) { | ||
result = value; | ||
} | ||
} | ||
} else { | ||
iteratee = cb(iteratee, context); | ||
_.each(obj, function (v, index, list) { | ||
computed = iteratee(v, index, list); | ||
if (computed < lastComputed || computed === Infinity && result === Infinity) { | ||
result = v; | ||
lastComputed = computed; | ||
} | ||
}); | ||
} | ||
return result; | ||
}; | ||
// Shuffle a collection. | ||
_.shuffle = function (obj) { | ||
return _.sample(obj, Infinity); | ||
}; | ||
// Sample **n** random values from a collection using the modern version of the | ||
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). | ||
// If **n** is not specified, returns a single random element. | ||
// The internal `guard` argument allows it to work with `map`. | ||
_.sample = function (obj, n, guard) { | ||
if (n == null || guard) { | ||
if (!isArrayLike(obj)) obj = _.values(obj); | ||
return obj[_.random(obj.length - 1)]; | ||
} | ||
var sample = isArrayLike(obj) ? _.clone(obj) : _.values(obj); | ||
var length = getLength(sample); | ||
n = Math.max(Math.min(n, length), 0); | ||
var last = length - 1; | ||
for (var index = 0; index < n; index++) { | ||
var rand = _.random(index, last); | ||
var temp = sample[index]; | ||
sample[index] = sample[rand]; | ||
sample[rand] = temp; | ||
} | ||
return sample.slice(0, n); | ||
}; | ||
// Sort the object's values by a criterion produced by an iteratee. | ||
_.sortBy = function (obj, iteratee, context) { | ||
iteratee = cb(iteratee, context); | ||
return _.pluck(_.map(obj, function (value, index, list) { | ||
return { | ||
value: value, | ||
index: index, | ||
criteria: iteratee(value, index, list) | ||
v: result | ||
}; | ||
}).sort(function (left, right) { | ||
var a = left.criteria; | ||
var b = right.criteria; | ||
if (a !== b) { | ||
if (a > b || a === void 0) return 1; | ||
if (a < b || b === void 0) return -1; | ||
} | ||
return left.index - right.index; | ||
}), 'value'); | ||
}; | ||
})(); | ||
// An internal function used for aggregate "group by" operations. | ||
var group = function group(behavior, partition) { | ||
return function (obj, iteratee, context) { | ||
var result = partition ? [[], []] : {}; | ||
iteratee = cb(iteratee, context); | ||
_.each(obj, function (value, index) { | ||
var key = iteratee(value, index, obj); | ||
behavior(result, value, key); | ||
}); | ||
return result; | ||
}; | ||
}; | ||
if (typeof _ret === 'object') return _ret.v; | ||
} | ||
} | ||
// Groups the object's values by a criterion. Pass either a string attribute | ||
// to group by, or a function that returns the criterion. | ||
_.groupBy = group(function (result, value, key) { | ||
if (_.has(result, key)) result[key].push(value);else result[key] = [value]; | ||
}); | ||
/** | ||
* Returns true if the provided object is an array. | ||
* | ||
* @param {object} obj - object to be inspected | ||
*/ | ||
function isArrayLike(obj) { | ||
var length = obj.length; | ||
return typeof length === 'number' && length >= 0; | ||
} | ||
// Indexes the object's values by a criterion, similar to `groupBy`, but for | ||
// when you know that your index values will be unique. | ||
_.indexBy = group(function (result, value, key) { | ||
result[key] = value; | ||
}); | ||
/** | ||
* Returns all the names of the object's properties. | ||
* | ||
* @param {object} obj - object to be used | ||
*/ | ||
function keys(obj) { | ||
var objKeys = []; | ||
for (var key in obj) { | ||
if (has(obj, key)) objKeys.push(key); | ||
}return objKeys; | ||
} | ||
// Counts instances of an object that group by a certain criterion. Pass | ||
// either a string attribute to count by, or a function that returns the | ||
// criterion. | ||
_.countBy = group(function (result, value, key) { | ||
if (_.has(result, key)) result[key]++;else result[key] = 1; | ||
}); | ||
/** | ||
* Returns a new array of values by mapping each value in list through a transformation function (predicate). If object is a not an array, predicate's arguments will be (value, key, list). | ||
* | ||
* @param {object|array} obj - object to be based upon | ||
* @param {function} predicate - function returning the a new version of the entry | ||
* @param {object} [context] - context for the predicate function call | ||
*/ | ||
// Safely create a real, live array from anything iterable. | ||
_.toArray = function (obj) { | ||
if (!obj) return []; | ||
if (_.isArray(obj)) return slice.call(obj); | ||
if (isArrayLike(obj)) return _.map(obj, _.identity); | ||
return _.values(obj); | ||
}; | ||
// Return the number of elements in an object. | ||
_.size = function (obj) { | ||
if (obj == null) return 0; | ||
return isArrayLike(obj) ? obj.length : _.keys(obj).length; | ||
}; | ||
// Split a collection into two arrays: one whose elements all satisfy the given | ||
// predicate, and one whose elements all do not satisfy the predicate. | ||
_.partition = group(function (result, value, pass) { | ||
result[pass ? 0 : 1].push(value); | ||
}, true); | ||
// Array Functions | ||
// --------------- | ||
// Get the first element of an array. Passing **n** will return the first N | ||
// values in the array. Aliased as `head` and `take`. The **guard** check | ||
// allows it to work with `_.map`. | ||
_.first = _.head = _.take = function (array, n, guard) { | ||
if (array == null) return void 0; | ||
if (n == null || guard) return array[0]; | ||
return _.initial(array, array.length - n); | ||
}; | ||
// Returns everything but the last entry of the array. Especially useful on | ||
// the arguments object. Passing **n** will return all the values in | ||
// the array, excluding the last N. | ||
_.initial = function (array, n, guard) { | ||
return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); | ||
}; | ||
// Get the last element of an array. Passing **n** will return the last N | ||
// values in the array. | ||
_.last = function (array, n, guard) { | ||
if (array == null) return void 0; | ||
if (n == null || guard) return array[array.length - 1]; | ||
return _.rest(array, Math.max(0, array.length - n)); | ||
}; | ||
// Returns everything but the first entry of the array. Aliased as `tail` and `drop`. | ||
// Especially useful on the arguments object. Passing an **n** will return | ||
// the rest N values in the array. | ||
_.rest = _.tail = _.drop = function (array, n, guard) { | ||
return slice.call(array, n == null || guard ? 1 : n); | ||
}; | ||
// Trim out all falsy values from an array. | ||
_.compact = function (array) { | ||
return _.filter(array, _.identity); | ||
}; | ||
// Internal implementation of a recursive `flatten` function. | ||
var flatten = function flatten(input, shallow, strict, output) { | ||
output = output || []; | ||
var idx = output.length; | ||
for (var i = 0, length = getLength(input); i < length; i++) { | ||
var value = input[i]; | ||
if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { | ||
//flatten current level of array or arguments object | ||
if (shallow) { | ||
var j = 0, | ||
len = value.length; | ||
while (j < len) output[idx++] = value[j++]; | ||
} else { | ||
flatten(value, shallow, strict, output); | ||
idx = output.length; | ||
} | ||
} else if (!strict) { | ||
output[idx++] = value; | ||
} | ||
} | ||
return output; | ||
}; | ||
// Flatten out an array, either recursively (by default), or just one level. | ||
_.flatten = function (array, shallow) { | ||
return flatten(array, shallow, false); | ||
}; | ||
// Return a version of the array that does not contain the specified value(s). | ||
_.without = restArgs(function (array, otherArrays) { | ||
return _.difference(array, otherArrays); | ||
}); | ||
// Produce a duplicate-free version of the array. If the array has already | ||
// been sorted, you have the option of using a faster algorithm. | ||
// Aliased as `unique`. | ||
_.uniq = _.unique = function (array, isSorted, iteratee, context) { | ||
if (!_.isBoolean(isSorted)) { | ||
context = iteratee; | ||
iteratee = isSorted; | ||
isSorted = false; | ||
} | ||
if (iteratee != null) iteratee = cb(iteratee, context); | ||
function map(obj, predicate, context) { | ||
if (obj) { | ||
var result = []; | ||
var seen = []; | ||
for (var i = 0, length = getLength(array); i < length; i++) { | ||
var value = array[i], | ||
computed = iteratee ? iteratee(value, i, array) : value; | ||
if (isSorted) { | ||
if (!i || seen !== computed) result.push(value); | ||
seen = computed; | ||
} else if (iteratee) { | ||
if (!_.contains(seen, computed)) { | ||
seen.push(computed); | ||
result.push(value); | ||
} | ||
} else if (!_.contains(result, value)) { | ||
result.push(value); | ||
var objKeys = !isArrayLike(obj) && keys(obj); | ||
var _length = (objKeys || obj).length; | ||
for (var index = 0; index < _length; index++) { | ||
var currentKey = objKeys ? objKeys[index] : index; | ||
if (predicate) { | ||
result[index] = predicate.call(context, obj[currentKey], currentKey); | ||
} | ||
} | ||
return result; | ||
}; | ||
} | ||
} | ||
// Produce an array that contains the union: each distinct element from all of | ||
// the passed-in arrays. | ||
_.union = restArgs(function (arrays) { | ||
return _.uniq(flatten(arrays, true, true)); | ||
}); | ||
/** | ||
* Returns the first value that passes a truth test (predicate), or undefined if | ||
* no value passes the test. Only works for iterable objects e.g. arrays. | ||
* | ||
* @param {array} iterable - the iterable object to be searched | ||
* @param {function} predicate - function returning true in case of a positive match | ||
* @param {object} [context] - context for the predicate function call | ||
*/ | ||
// Produce an array that contains every item shared between all the | ||
// passed-in arrays. | ||
_.intersection = function (array) { | ||
var result = []; | ||
var argsLength = arguments.length; | ||
for (var i = 0, length = getLength(array); i < length; i++) { | ||
var item = array[i]; | ||
if (_.contains(result, item)) continue; | ||
var j; | ||
for (j = 1; j < argsLength; j++) { | ||
if (!_.contains(arguments[j], item)) break; | ||
function find(iterable, predicate, context) { | ||
if (iterable) { | ||
var result = undefined; | ||
for (var index = 0; index < iterable.length; index++) { | ||
if (predicate && predicate.call(context, iterable[index])) { | ||
result = iterable[index]; | ||
break; | ||
} | ||
if (j === argsLength) result.push(item); | ||
} | ||
return result; | ||
}; | ||
} | ||
} | ||
// Take the difference between one array and a number of other arrays. | ||
// Only the elements present in just the first array will remain. | ||
_.difference = restArgs(function (array, rest) { | ||
rest = flatten(rest, true, true); | ||
return _.filter(array, function (value) { | ||
return !_.contains(rest, value); | ||
}); | ||
}); | ||
/** | ||
* Returns true if object contains no values (no enumerable own-properties). | ||
* | ||
* @param {array} iterable - an iterable object | ||
*/ | ||
// Complement of _.zip. Unzip accepts an array of arrays and groups | ||
// each array's elements on shared indices | ||
_.unzip = function (array) { | ||
var length = array && _.max(array, getLength).length || 0; | ||
var result = Array(length); | ||
function isEmpty(iterable) { | ||
return !iterable || iterable.length === 0; | ||
} | ||
for (var index = 0; index < length; index++) { | ||
result[index] = _.pluck(array, index); | ||
} | ||
return result; | ||
}; | ||
/** | ||
* Returns the index of the first value that passes a truth test (predicate), or undefined if | ||
* no value passes the test. Only works for iterable objects e.g. arrays. | ||
* | ||
* @param {array} iterable - the iterable object to be searched | ||
* @param {function} predicate - function returning true in case of a positive match | ||
* @param {object} [context] - context for the predicate function call | ||
*/ | ||
// Zip together multiple lists into a single array -- elements that share | ||
// an index go together. | ||
_.zip = restArgs(_.unzip); | ||
// Converts lists into objects. Pass either a single array of `[key, value]` | ||
// pairs, or two parallel arrays of the same length -- one of keys, and one of | ||
// the corresponding values. | ||
_.object = function (list, values) { | ||
var result = {}; | ||
for (var i = 0, length = getLength(list); i < length; i++) { | ||
if (values) { | ||
result[list[i]] = values[i]; | ||
} else { | ||
result[list[i][0]] = list[i][1]; | ||
function findIndex(iterable, predicate, context) { | ||
if (iterable) { | ||
var result = undefined; | ||
for (var index = 0; index < iterable.length; index++) { | ||
if (predicate && predicate.call(context, iterable[index])) { | ||
result = index; | ||
break; | ||
} | ||
} | ||
return result; | ||
}; | ||
} | ||
} | ||
// Generator function to create the findIndex and findLastIndex functions | ||
var createPredicateIndexFinder = function createPredicateIndexFinder(dir) { | ||
return function (array, predicate, context) { | ||
predicate = cb(predicate, context); | ||
var length = getLength(array); | ||
var index = dir > 0 ? 0 : length - 1; | ||
for (; index >= 0 && index < length; index += dir) { | ||
if (predicate(array[index], index, array)) return index; | ||
} | ||
return -1; | ||
}; | ||
}; | ||
/** | ||
* Returns the first element of an iterable object. | ||
* | ||
* @param {array} iterable - must be an iterable object | ||
*/ | ||
// Returns the first index on an array-like that passes a predicate test | ||
_.findIndex = createPredicateIndexFinder(1); | ||
_.findLastIndex = createPredicateIndexFinder(-1); | ||
function first(iterable) { | ||
if (iterable && iterable.length > 0) { | ||
return iterable[0]; | ||
} | ||
} | ||
// Use a comparator function to figure out the smallest index at which | ||
// an object should be inserted so as to maintain order. Uses binary search. | ||
_.sortedIndex = function (array, obj, iteratee, context) { | ||
iteratee = cb(iteratee, context, 1); | ||
var value = iteratee(obj); | ||
var low = 0, | ||
high = getLength(array); | ||
while (low < high) { | ||
var mid = Math.floor((low + high) / 2); | ||
if (iteratee(array[mid]) < value) low = mid + 1;else high = mid; | ||
} | ||
return low; | ||
}; | ||
/** | ||
* Returns the last element of an iterable object. | ||
* | ||
* @param {array} iterable - must be an iterable object | ||
*/ | ||
// Generator function to create the indexOf and lastIndexOf functions | ||
var createIndexFinder = function createIndexFinder(dir, predicateFind, sortedIndex) { | ||
return function (array, item, idx) { | ||
var i = 0, | ||
length = getLength(array); | ||
if (typeof idx == 'number') { | ||
if (dir > 0) { | ||
i = idx >= 0 ? idx : Math.max(idx + length, i); | ||
} else { | ||
length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; | ||
} | ||
} else if (sortedIndex && idx && length) { | ||
idx = sortedIndex(array, item); | ||
return array[idx] === item ? idx : -1; | ||
} | ||
if (item !== item) { | ||
idx = predicateFind(slice.call(array, i, length), _.isNaN); | ||
return idx >= 0 ? idx + i : -1; | ||
} | ||
for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { | ||
if (array[idx] === item) return idx; | ||
} | ||
return -1; | ||
}; | ||
}; | ||
function last(iterable) { | ||
if (iterable && iterable.length > 0) { | ||
return iterable[iterable.length - 1]; | ||
} | ||
} | ||
// Return the position of the first occurrence of an item in an array, | ||
// or -1 if the item is not included in the array. | ||
// If the array is large and already in sort order, pass `true` | ||
// for **isSorted** to use binary search. | ||
_.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex); | ||
_.lastIndexOf = createIndexFinder(-1, _.findLastIndex); | ||
/** | ||
* Return the number of values in the list. | ||
* | ||
* @param {array} iterable - must be an iterable object | ||
*/ | ||
// Generate an integer Array containing an arithmetic progression. A port of | ||
// the native Python `range()` function. See | ||
// [the Python documentation](http://docs.python.org/library/functions.html#range). | ||
_.range = function (start, stop, step) { | ||
if (stop == null) { | ||
stop = start || 0; | ||
start = 0; | ||
} | ||
step = step || 1; | ||
function size(iterable) { | ||
if (iterable) { | ||
return iterable.length; | ||
} | ||
return 0; | ||
} | ||
var length = Math.max(Math.ceil((stop - start) / step), 0); | ||
var range = Array(length); | ||
/** | ||
* Returns true if any of the values in the list pass the predicate truth test. | ||
* | ||
* @param {array} iterable - iterable object to be searched | ||
* @param {function} predicate - function returning true in case of a positive match | ||
* @param {object} [context] - context for the predicate function call | ||
*/ | ||
for (var idx = 0; idx < length; idx++, start += step) { | ||
range[idx] = start; | ||
} | ||
return range; | ||
}; | ||
// Function (ahem) Functions | ||
// ------------------ | ||
// Determines whether to execute a function as a constructor | ||
// or a normal function with the provided arguments | ||
var executeBound = function executeBound(sourceFunc, boundFunc, context, callingContext, args) { | ||
if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); | ||
var self = baseCreate(sourceFunc.prototype); | ||
var result = sourceFunc.apply(self, args); | ||
if (_.isObject(result)) return result; | ||
return self; | ||
}; | ||
// Create a function bound to a given object (assigning `this`, and arguments, | ||
// optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if | ||
// available. | ||
_.bind = restArgs(function (func, context, args) { | ||
if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); | ||
var bound = restArgs(function (callArgs) { | ||
return executeBound(func, bound, context, this, args.concat(callArgs)); | ||
}); | ||
return bound; | ||
}); | ||
// Partially apply a function by creating a version that has had some of its | ||
// arguments pre-filled, without changing its dynamic `this` context. _ acts | ||
// as a placeholder by default, allowing any combination of arguments to be | ||
// pre-filled. Set `_.partial.placeholder` for a custom placeholder argument. | ||
_.partial = restArgs(function (func, boundArgs) { | ||
var placeholder = _.partial.placeholder; | ||
var bound = function bound() { | ||
var position = 0, | ||
length = boundArgs.length; | ||
var args = Array(length); | ||
for (var i = 0; i < length; i++) { | ||
args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i]; | ||
function some(iterable, predicate, context) { | ||
if (iterable) { | ||
var result = undefined; | ||
for (var index = 0; index < iterable.length; index++) { | ||
if (predicate && predicate.call(context, iterable[index])) { | ||
result = true; | ||
break; | ||
} | ||
while (position < arguments.length) args.push(arguments[position++]); | ||
return executeBound(func, bound, this, this, args); | ||
}; | ||
return bound; | ||
}); | ||
_.partial.placeholder = _; | ||
// Bind a number of an object's methods to that object. Remaining arguments | ||
// are the method names to be bound. Useful for ensuring that all callbacks | ||
// defined on an object belong to it. | ||
_.bindAll = restArgs(function (obj, keys) { | ||
keys = flatten(keys, false, false); | ||
var index = keys.length; | ||
if (index < 1) throw new Error('bindAll must be passed function names'); | ||
while (index--) { | ||
var key = keys[index]; | ||
obj[key] = _.bind(obj[key], obj); | ||
} | ||
}); | ||
return result; | ||
} | ||
} | ||
// Memoize an expensive function by storing its results. | ||
_.memoize = function (func, hasher) { | ||
var memoize = function memoize(key) { | ||
var cache = memoize.cache; | ||
var address = '' + (hasher ? hasher.apply(this, arguments) : key); | ||
if (!_.has(cache, address)) cache[address] = func.apply(this, arguments); | ||
return cache[address]; | ||
}; | ||
memoize.cache = {}; | ||
return memoize; | ||
}; | ||
/** | ||
* Returns the union of the passed-in arrays: the list of unique items, in order, that are present in one or more of the arrays. | ||
* | ||
* @param {...array} arrs - at least two iterable objects must be provide | ||
*/ | ||
// Delays a function for the given number of milliseconds, and then calls | ||
// it with the arguments supplied. | ||
_.delay = restArgs(function (func, wait, args) { | ||
return setTimeout(function () { | ||
return func.apply(null, args); | ||
}, wait); | ||
}); | ||
function union() { | ||
for (var _len = arguments.length, arrs = Array(_len), _key = 0; _key < _len; _key++) { | ||
arrs[_key] = arguments[_key]; | ||
} | ||
// Defers a function, scheduling it to run after the current call stack has | ||
// cleared. | ||
_.defer = _.partial(_.delay, _, 1); | ||
// Returns a function, that, when invoked, will only be triggered at most once | ||
// during a given window of time. Normally, the throttled function will run | ||
// as much as it can, without ever going more than once per `wait` duration; | ||
// but if you'd like to disable the execution on the leading edge, pass | ||
// `{leading: false}`. To disable execution on the trailing edge, ditto. | ||
_.throttle = function (func, wait, options) { | ||
var context, args, result; | ||
var timeout = null; | ||
var previous = 0; | ||
if (!options) options = {}; | ||
var later = function later() { | ||
previous = options.leading === false ? 0 : _.now(); | ||
timeout = null; | ||
result = func.apply(context, args); | ||
if (!timeout) context = args = null; | ||
}; | ||
return function () { | ||
var now = _.now(); | ||
if (!previous && options.leading === false) previous = now; | ||
var remaining = wait - (now - previous); | ||
context = this; | ||
args = arguments; | ||
if (remaining <= 0 || remaining > wait) { | ||
if (timeout) { | ||
clearTimeout(timeout); | ||
timeout = null; | ||
if (arrs) { | ||
var _ret2 = (function () { | ||
var result = []; | ||
arrs.forEach(function (arr) { | ||
if (arr) { | ||
arr.forEach(function (obj) { | ||
if (result.indexOf(obj) < 0) { | ||
result.push(obj); | ||
} | ||
}); | ||
} | ||
previous = now; | ||
result = func.apply(context, args); | ||
if (!timeout) context = args = null; | ||
} else if (!timeout && options.trailing !== false) { | ||
timeout = setTimeout(later, remaining); | ||
} | ||
return result; | ||
}; | ||
}; | ||
}); | ||
return { | ||
v: result | ||
}; | ||
})(); | ||
// Returns a function, that, as long as it continues to be invoked, will not | ||
// be triggered. The function will be called after it stops being called for | ||
// N milliseconds. If `immediate` is passed, trigger the function on the | ||
// leading edge, instead of the trailing. | ||
_.debounce = function (func, wait, immediate) { | ||
var timeout, args, context, timestamp, result; | ||
if (typeof _ret2 === 'object') return _ret2.v; | ||
} | ||
} | ||
var later = function later() { | ||
var last = _.now() - timestamp; | ||
var idCounter = 0; | ||
if (last < wait && last >= 0) { | ||
timeout = setTimeout(later, wait - last); | ||
} else { | ||
timeout = null; | ||
if (!immediate) { | ||
result = func.apply(context, args); | ||
if (!timeout) context = args = null; | ||
} | ||
} | ||
}; | ||
/** | ||
* Generate a globally-unique id. | ||
* | ||
* @param {string} [prefix] - if prefix is passed, the id will be appended to it. | ||
*/ | ||
return function () { | ||
context = this; | ||
args = arguments; | ||
timestamp = _.now(); | ||
var callNow = immediate && !timeout; | ||
if (!timeout) timeout = setTimeout(later, wait); | ||
if (callNow) { | ||
result = func.apply(context, args); | ||
context = args = null; | ||
} | ||
function uniqueId(prefix) { | ||
var id = ++idCounter + ''; | ||
return prefix ? prefix + id : id; | ||
} | ||
return result; | ||
}; | ||
}; | ||
/** | ||
* Copy all of the properties in the source objects over to the destination object, and return the destination object. It's in-order, so the last source will override properties of the same name in previous arguments. | ||
* | ||
* @param {object} obj1 - object to be extended | ||
* @param {...object} objs - at least one but optionally more objects an be provided | ||
*/ | ||
// Returns the first function passed as an argument to the second, | ||
// allowing you to adjust arguments, run code before and after, and | ||
// conditionally execute the original function. | ||
_.wrap = function (func, wrapper) { | ||
return _.partial(wrapper, func); | ||
}; | ||
function extend(obj1) { | ||
for (var _len2 = arguments.length, objs = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { | ||
objs[_key2 - 1] = arguments[_key2]; | ||
} | ||
// Returns a negated version of the passed-in predicate. | ||
_.negate = function (predicate) { | ||
return function () { | ||
return !predicate.apply(this, arguments); | ||
}; | ||
}; | ||
// Returns a function that is the composition of a list of functions, each | ||
// consuming the return value of the function that follows. | ||
_.compose = function () { | ||
var args = arguments; | ||
var start = args.length - 1; | ||
return function () { | ||
var i = start; | ||
var result = args[start].apply(this, arguments); | ||
while (i--) result = args[i].call(this, result); | ||
return result; | ||
}; | ||
}; | ||
// Returns a function that will only be executed on and after the Nth call. | ||
_.after = function (times, func) { | ||
return function () { | ||
if (--times < 1) { | ||
return func.apply(this, arguments); | ||
} | ||
}; | ||
}; | ||
// Returns a function that will only be executed up to (but not including) the Nth call. | ||
_.before = function (times, func) { | ||
var memo; | ||
return function () { | ||
if (--times > 0) { | ||
memo = func.apply(this, arguments); | ||
} | ||
if (times <= 1) func = null; | ||
return memo; | ||
}; | ||
}; | ||
// Returns a function that will be executed at most one time, no matter how | ||
// often you call it. Useful for lazy initialization. | ||
_.once = _.partial(_.before, 2); | ||
_.restArgs = restArgs; | ||
// Object Functions | ||
// ---------------- | ||
// Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. | ||
var hasEnumBug = !({ toString: null }).propertyIsEnumerable('toString'); | ||
var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; | ||
var collectNonEnumProps = function collectNonEnumProps(obj, keys) { | ||
var nonEnumIdx = nonEnumerableProps.length; | ||
var constructor = obj.constructor; | ||
var proto = _.isFunction(constructor) && constructor.prototype || ObjProto; | ||
// Constructor is a special case. | ||
var prop = 'constructor'; | ||
if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); | ||
while (nonEnumIdx--) { | ||
prop = nonEnumerableProps[nonEnumIdx]; | ||
if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { | ||
keys.push(prop); | ||
} | ||
} | ||
}; | ||
// Retrieve the names of an object's own properties. | ||
// Delegates to **ECMAScript 5**'s native `Object.keys` | ||
_.keys = function (obj) { | ||
if (!_.isObject(obj)) return []; | ||
if (nativeKeys) return nativeKeys(obj); | ||
var keys = []; | ||
for (var key in obj) if (_.has(obj, key)) keys.push(key); | ||
// Ahem, IE < 9. | ||
if (hasEnumBug) collectNonEnumProps(obj, keys); | ||
return keys; | ||
}; | ||
// Retrieve all the property names of an object. | ||
_.allKeys = function (obj) { | ||
if (!_.isObject(obj)) return []; | ||
var keys = []; | ||
for (var key in obj) keys.push(key); | ||
// Ahem, IE < 9. | ||
if (hasEnumBug) collectNonEnumProps(obj, keys); | ||
return keys; | ||
}; | ||
// Retrieve the values of an object's properties. | ||
_.values = function (obj) { | ||
var keys = _.keys(obj); | ||
var length = keys.length; | ||
var values = Array(length); | ||
for (var i = 0; i < length; i++) { | ||
values[i] = obj[keys[i]]; | ||
} | ||
return values; | ||
}; | ||
// Returns the results of applying the iteratee to each element of the object | ||
// In contrast to _.map it returns an object | ||
_.mapObject = function (obj, iteratee, context) { | ||
iteratee = cb(iteratee, context); | ||
var keys = _.keys(obj), | ||
length = keys.length, | ||
results = {}; | ||
for (var index = 0; index < length; index++) { | ||
var currentKey = keys[index]; | ||
results[currentKey] = iteratee(obj[currentKey], currentKey, obj); | ||
} | ||
return results; | ||
}; | ||
// Convert an object into a list of `[key, value]` pairs. | ||
_.pairs = function (obj) { | ||
var keys = _.keys(obj); | ||
var length = keys.length; | ||
var pairs = Array(length); | ||
for (var i = 0; i < length; i++) { | ||
pairs[i] = [keys[i], obj[keys[i]]]; | ||
} | ||
return pairs; | ||
}; | ||
// Invert the keys and values of an object. The values must be serializable. | ||
_.invert = function (obj) { | ||
var result = {}; | ||
var keys = _.keys(obj); | ||
for (var i = 0, length = keys.length; i < length; i++) { | ||
result[obj[keys[i]]] = keys[i]; | ||
} | ||
return result; | ||
}; | ||
// Return a sorted list of the function names available on the object. | ||
// Aliased as `methods` | ||
_.functions = _.methods = function (obj) { | ||
var names = []; | ||
for (var key in obj) { | ||
if (_.isFunction(obj[key])) names.push(key); | ||
} | ||
return names.sort(); | ||
}; | ||
// An internal function for creating assigner functions. | ||
var createAssigner = function createAssigner(keysFunc, undefinedOnly) { | ||
return function (obj) { | ||
var length = arguments.length; | ||
if (length < 2 || obj == null) return obj; | ||
for (var index = 1; index < length; index++) { | ||
var source = arguments[index], | ||
keys = keysFunc(source), | ||
l = keys.length; | ||
for (var i = 0; i < l; i++) { | ||
var key = keys[i]; | ||
if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key]; | ||
if (obj1 && objs) { | ||
objs.forEach(function (obj) { | ||
if (obj) { | ||
for (var key in obj) { | ||
if (obj.hasOwnProperty(key)) { | ||
obj1[key] = obj[key]; | ||
} | ||
} | ||
} | ||
return obj; | ||
}; | ||
}; | ||
// Extend a given object with all the properties in passed-in object(s). | ||
_.extend = createAssigner(_.allKeys); | ||
// Assigns a given object with all the own properties in the passed-in object(s) | ||
// (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) | ||
_.extendOwn = _.assign = createAssigner(_.keys); | ||
// Returns the first key on an object that passes a predicate test | ||
_.findKey = function (obj, predicate, context) { | ||
predicate = cb(predicate, context); | ||
var keys = _.keys(obj), | ||
key; | ||
for (var i = 0, length = keys.length; i < length; i++) { | ||
key = keys[i]; | ||
if (predicate(obj[key], key, obj)) return key; | ||
} | ||
}; | ||
// Internal pick helper function to determine if `obj` has key `key`. | ||
var keyInObj = function keyInObj(value, key, obj) { | ||
return key in obj; | ||
}; | ||
// Return a copy of the object only containing the whitelisted properties. | ||
_.pick = restArgs(function (obj, keys) { | ||
var result = {}, | ||
iteratee = keys[0]; | ||
if (obj == null) return result; | ||
if (_.isFunction(iteratee)) { | ||
if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]); | ||
keys = _.allKeys(obj); | ||
} else { | ||
iteratee = keyInObj; | ||
keys = flatten(keys, false, false); | ||
obj = Object(obj); | ||
} | ||
for (var i = 0, length = keys.length; i < length; i++) { | ||
var key = keys[i]; | ||
var value = obj[key]; | ||
if (iteratee(value, key, obj)) result[key] = value; | ||
} | ||
return result; | ||
}); | ||
// Return a copy of the object without the blacklisted properties. | ||
_.omit = restArgs(function (obj, keys) { | ||
var iteratee = keys[0], | ||
context; | ||
if (_.isFunction(iteratee)) { | ||
iteratee = _.negate(iteratee); | ||
if (keys.length > 1) context = keys[1]; | ||
} else { | ||
keys = _.map(flatten(keys, false, false), String); | ||
iteratee = function (value, key) { | ||
return !_.contains(keys, key); | ||
}; | ||
} | ||
return _.pick(obj, iteratee, context); | ||
}); | ||
// Fill in a given object with default properties. | ||
_.defaults = createAssigner(_.allKeys, true); | ||
// Creates an object that inherits from the given prototype object. | ||
// If additional properties are provided then they will be added to the | ||
// created object. | ||
_.create = function (prototype, props) { | ||
var result = baseCreate(prototype); | ||
if (props) _.extendOwn(result, props); | ||
return result; | ||
}; | ||
// Create a (shallow-cloned) duplicate of an object. | ||
_.clone = function (obj) { | ||
if (!_.isObject(obj)) return obj; | ||
return _.isArray(obj) ? obj.slice() : _.extend({}, obj); | ||
}; | ||
// Invokes interceptor with the obj, and then returns obj. | ||
// The primary purpose of this method is to "tap into" a method chain, in | ||
// order to perform operations on intermediate results within the chain. | ||
_.tap = function (obj, interceptor) { | ||
interceptor(obj); | ||
return obj; | ||
}; | ||
// Returns whether an object has a given set of `key:value` pairs. | ||
_.isMatch = function (object, attrs) { | ||
var keys = _.keys(attrs), | ||
length = keys.length; | ||
if (object == null) return !length; | ||
var obj = Object(object); | ||
for (var i = 0; i < length; i++) { | ||
var key = keys[i]; | ||
if (attrs[key] !== obj[key] || !(key in obj)) return false; | ||
} | ||
return true; | ||
}; | ||
// Internal recursive comparison function for `isEqual`. | ||
var eq, deepEq; | ||
eq = function (a, b, aStack, bStack) { | ||
// Identical objects are equal. `0 === -0`, but they aren't identical. | ||
// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). | ||
if (a === b) return a !== 0 || 1 / a === 1 / b; | ||
// A strict comparison is necessary because `null == undefined`. | ||
if (a == null || b == null) return a === b; | ||
// `NaN`s are equivalent, but non-reflexive. | ||
if (a !== a) return b !== b; | ||
// Exhaust primitive checks | ||
var type = typeof a; | ||
if (type !== 'function' && type !== 'object' && typeof b !== 'object') return false; | ||
return deepEq(a, b, aStack, bStack); | ||
}; | ||
// Internal recursive comparison function for `isEqual`. | ||
deepEq = function (a, b, aStack, bStack) { | ||
// Unwrap any wrapped objects. | ||
if (a instanceof _) a = a._wrapped; | ||
if (b instanceof _) b = b._wrapped; | ||
// Compare `[[Class]]` names. | ||
var className = toString.call(a); | ||
if (className !== toString.call(b)) return false; | ||
switch (className) { | ||
// Strings, numbers, regular expressions, dates, and booleans are compared by value. | ||
case '[object RegExp]': | ||
// RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') | ||
case '[object String]': | ||
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is | ||
// equivalent to `new String("5")`. | ||
return '' + a === '' + b; | ||
case '[object Number]': | ||
// `NaN`s are equivalent, but non-reflexive. | ||
// Object(NaN) is equivalent to NaN | ||
if (+a !== +a) return +b !== +b; | ||
// An `egal` comparison is performed for other numeric values. | ||
return +a === 0 ? 1 / +a === 1 / b : +a === +b; | ||
case '[object Date]': | ||
case '[object Boolean]': | ||
// Coerce dates and booleans to numeric primitive values. Dates are compared by their | ||
// millisecond representations. Note that invalid dates with millisecond representations | ||
// of `NaN` are not equivalent. | ||
return +a === +b; | ||
} | ||
var areArrays = className === '[object Array]'; | ||
if (!areArrays) { | ||
if (typeof a != 'object' || typeof b != 'object') return false; | ||
// Objects with different constructors are not equivalent, but `Object`s or `Array`s | ||
// from different frames are. | ||
var aCtor = a.constructor, | ||
bCtor = b.constructor; | ||
if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && _.isFunction(bCtor) && bCtor instanceof bCtor) && ('constructor' in a && 'constructor' in b)) { | ||
return false; | ||
} | ||
} | ||
// Assume equality for cyclic structures. The algorithm for detecting cyclic | ||
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. | ||
// Initializing stack of traversed objects. | ||
// It's done here since we only need them for objects and arrays comparison. | ||
aStack = aStack || []; | ||
bStack = bStack || []; | ||
var length = aStack.length; | ||
while (length--) { | ||
// Linear search. Performance is inversely proportional to the number of | ||
// unique nested structures. | ||
if (aStack[length] === a) return bStack[length] === b; | ||
} | ||
// Add the first object to the stack of traversed objects. | ||
aStack.push(a); | ||
bStack.push(b); | ||
// Recursively compare objects and arrays. | ||
if (areArrays) { | ||
// Compare array lengths to determine if a deep comparison is necessary. | ||
length = a.length; | ||
if (length !== b.length) return false; | ||
// Deep compare the contents, ignoring non-numeric properties. | ||
while (length--) { | ||
if (!eq(a[length], b[length], aStack, bStack)) return false; | ||
} | ||
} else { | ||
// Deep compare objects. | ||
var keys = _.keys(a), | ||
key; | ||
length = keys.length; | ||
// Ensure that both objects contain the same number of properties before comparing deep equality. | ||
if (_.keys(b).length !== length) return false; | ||
while (length--) { | ||
// Deep compare each member | ||
key = keys[length]; | ||
if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; | ||
} | ||
} | ||
// Remove the first object from the stack of traversed objects. | ||
aStack.pop(); | ||
bStack.pop(); | ||
return true; | ||
}; | ||
// Perform a deep comparison to check if two objects are equal. | ||
_.isEqual = function (a, b) { | ||
return eq(a, b); | ||
}; | ||
// Is a given array, string, or object empty? | ||
// An "empty" object has no enumerable own-properties. | ||
_.isEmpty = function (obj) { | ||
if (obj == null) return true; | ||
if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; | ||
return _.keys(obj).length === 0; | ||
}; | ||
// Is a given value a DOM element? | ||
_.isElement = function (obj) { | ||
return !!(obj && obj.nodeType === 1); | ||
}; | ||
// Is a given value an array? | ||
// Delegates to ECMA5's native Array.isArray | ||
_.isArray = nativeIsArray || function (obj) { | ||
return toString.call(obj) === '[object Array]'; | ||
}; | ||
// Is a given variable an object? | ||
_.isObject = function (obj) { | ||
var type = typeof obj; | ||
return type === 'function' || type === 'object' && !!obj; | ||
}; | ||
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError. | ||
_.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function (name) { | ||
_['is' + name] = function (obj) { | ||
return toString.call(obj) === '[object ' + name + ']'; | ||
}; | ||
}); | ||
// Define a fallback version of the method in browsers (ahem, IE < 9), where | ||
// there isn't any inspectable "Arguments" type. | ||
if (!_.isArguments(arguments)) { | ||
_.isArguments = function (obj) { | ||
return _.has(obj, 'callee'); | ||
}; | ||
}); | ||
} | ||
return obj1; | ||
} | ||
// Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8, | ||
// IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236). | ||
var nodelist = root.document && root.document.childNodes; | ||
if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelist != 'function') { | ||
_.isFunction = function (obj) { | ||
return typeof obj == 'function' || false; | ||
}; | ||
} | ||
// Is a given object a finite number? | ||
_.isFinite = function (obj) { | ||
return isFinite(obj) && !isNaN(parseFloat(obj)); | ||
}; | ||
// Is the given value `NaN`? (NaN is the only number which does not equal itself). | ||
_.isNaN = function (obj) { | ||
return _.isNumber(obj) && obj !== +obj; | ||
}; | ||
// Is a given value a boolean? | ||
_.isBoolean = function (obj) { | ||
return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; | ||
}; | ||
// Is a given value equal to null? | ||
_.isNull = function (obj) { | ||
return obj === null; | ||
}; | ||
// Is a given variable undefined? | ||
_.isUndefined = function (obj) { | ||
return obj === void 0; | ||
}; | ||
// Shortcut function for checking if an object has a given property directly | ||
// on itself (in other words, not on a prototype). | ||
_.has = function (obj, key) { | ||
return obj != null && hasOwnProperty.call(obj, key); | ||
}; | ||
// Utility Functions | ||
// ----------------- | ||
// Run Underscore.js in *noConflict* mode, returning the `_` variable to its | ||
// previous owner. Returns a reference to the Underscore object. | ||
_.noConflict = function () { | ||
root._ = previousUnderscore; | ||
return this; | ||
}; | ||
// Keep the identity function around for default iteratees. | ||
_.identity = function (value) { | ||
return value; | ||
}; | ||
// Predicate-generating functions. Often useful outside of Underscore. | ||
_.constant = function (value) { | ||
return function () { | ||
return value; | ||
}; | ||
}; | ||
_.noop = function () {}; | ||
_.property = property; | ||
// Generates a function for a given object that returns a given property. | ||
_.propertyOf = function (obj) { | ||
return obj == null ? function () {} : function (key) { | ||
return obj[key]; | ||
}; | ||
}; | ||
// Returns a predicate for checking whether an object has a given set of | ||
// `key:value` pairs. | ||
_.matcher = _.matches = function (attrs) { | ||
attrs = _.extendOwn({}, attrs); | ||
return function (obj) { | ||
return _.isMatch(obj, attrs); | ||
}; | ||
}; | ||
// Run a function **n** times. | ||
_.times = function (n, iteratee, context) { | ||
var accum = Array(Math.max(0, n)); | ||
iteratee = optimizeCb(iteratee, context, 1); | ||
for (var i = 0; i < n; i++) accum[i] = iteratee(i); | ||
return accum; | ||
}; | ||
// Return a random integer between min and max (inclusive). | ||
_.random = function (min, max) { | ||
if (max == null) { | ||
max = min; | ||
min = 0; | ||
} | ||
return min + Math.floor(Math.random() * (max - min + 1)); | ||
}; | ||
// A (possibly faster) way to get the current timestamp as an integer. | ||
_.now = Date.now || function () { | ||
return new Date().getTime(); | ||
}; | ||
// List of HTML entities for escaping. | ||
var escapeMap = { | ||
'&': '&', | ||
'<': '<', | ||
'>': '>', | ||
'"': '"', | ||
'\'': ''', | ||
'`': '`' | ||
}; | ||
var unescapeMap = _.invert(escapeMap); | ||
// Functions for escaping and unescaping strings to/from HTML interpolation. | ||
var createEscaper = function createEscaper(map) { | ||
var escaper = function escaper(match) { | ||
return map[match]; | ||
}; | ||
// Regexes for identifying a key that needs to be escaped | ||
var source = '(?:' + _.keys(map).join('|') + ')'; | ||
var testRegexp = RegExp(source); | ||
var replaceRegexp = RegExp(source, 'g'); | ||
return function (string) { | ||
string = string == null ? '' : '' + string; | ||
return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; | ||
}; | ||
}; | ||
_.escape = createEscaper(escapeMap); | ||
_.unescape = createEscaper(unescapeMap); | ||
// If the value of the named `property` is a function then invoke it with the | ||
// `object` as context; otherwise, return it. | ||
_.result = function (object, prop, fallback) { | ||
var value = object == null ? void 0 : object[prop]; | ||
if (value === void 0) { | ||
value = fallback; | ||
} | ||
return _.isFunction(value) ? value.call(object) : value; | ||
}; | ||
// Generate a unique integer id (unique within the entire client session). | ||
// Useful for temporary DOM ids. | ||
var idCounter = 0; | ||
_.uniqueId = function (prefix) { | ||
var id = ++idCounter + ''; | ||
return prefix ? prefix + id : id; | ||
}; | ||
// By default, Underscore uses ERB-style template delimiters, change the | ||
// following template settings to use alternative delimiters. | ||
_.templateSettings = { | ||
evaluate: /<%([\s\S]+?)%>/g, | ||
interpolate: /<%=([\s\S]+?)%>/g, | ||
escape: /<%-([\s\S]+?)%>/g | ||
}; | ||
// When customizing `templateSettings`, if you don't want to define an | ||
// interpolation, evaluation or escaping regex, we need one that is | ||
// 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', | ||
'\u2028': 'u2028', | ||
'\u2029': 'u2029' | ||
}; | ||
var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g; | ||
var escapeChar = function escapeChar(match) { | ||
return '\\' + escapes[match]; | ||
}; | ||
// JavaScript micro-templating, similar to John Resig's implementation. | ||
// Underscore templating handles arbitrary delimiters, preserves whitespace, | ||
// and correctly escapes quotes within interpolated code. | ||
// NB: `oldSettings` only exists for backwards compatibility. | ||
_.template = function (text, settings, oldSettings) { | ||
if (!settings && oldSettings) settings = oldSettings; | ||
settings = _.defaults({}, settings, _.templateSettings); | ||
// Combine delimiters into one regular expression via alternation. | ||
var matcher = RegExp([(settings.escape || noMatch).source, (settings.interpolate || noMatch).source, (settings.evaluate || noMatch).source].join('|') + '|$', 'g'); | ||
// Compile the template source, escaping string literals appropriately. | ||
var index = 0; | ||
var source = '__p+=\''; | ||
text.replace(matcher, function (match, escape, interpolate, evaluate, offset) { | ||
source += text.slice(index, offset).replace(escapeRegExp, escapeChar); | ||
index = offset + match.length; | ||
if (escape) { | ||
source += '\'+\n((__t=(' + escape + '))==null?\'\':_.escape(__t))+\n\''; | ||
} else if (interpolate) { | ||
source += '\'+\n((__t=(' + interpolate + '))==null?\'\':__t)+\n\''; | ||
} else if (evaluate) { | ||
source += '\';\n' + evaluate + '\n__p+=\''; | ||
/** | ||
* Recursive function for flattening an iterable. | ||
* | ||
* @param {object} output - base object to be updated | ||
* @param {object} element - input object to be merged into the output | ||
*/ | ||
function flattenInternal(output, element) { | ||
if (element) { | ||
element.forEach(function (obj) { | ||
if (Array.isArray(obj)) { | ||
flattenInternal(output, obj); | ||
} else { | ||
output.push(obj); | ||
} | ||
// Adobe VMs need the match returned to produce the correct offset. | ||
return match; | ||
}); | ||
source += '\';\n'; | ||
} | ||
} | ||
// If a variable is not specified, place data values in local scope. | ||
if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; | ||
/** | ||
* Flattens a nested array (the nesting can be to any depth). | ||
* | ||
* @param {...array} arrays - at least one array must be provided | ||
*/ | ||
source = 'var __t,__p=\'\',__j=Array.prototype.join,' + 'print=function(){__p+=__j.call(arguments,\'\');};\n' + source + 'return __p;\n'; | ||
function flatten() { | ||
for (var _len3 = arguments.length, arrays = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { | ||
arrays[_key3] = arguments[_key3]; | ||
} | ||
var render; | ||
try { | ||
render = new Function(settings.variable || 'obj', '_', source); | ||
} catch (e) { | ||
e.source = source; | ||
throw e; | ||
} | ||
var template = function template(data) { | ||
return render.call(this, data, _); | ||
}; | ||
// Provide the compiled source as a convenience for precompilation. | ||
var argument = settings.variable || 'obj'; | ||
template.source = 'function(' + argument + '){\n' + source + '}'; | ||
return template; | ||
}; | ||
// Add a "chain" function. Start chaining a wrapped Underscore object. | ||
_.chain = function (obj) { | ||
var instance = _(obj); | ||
instance._chain = true; | ||
return instance; | ||
}; | ||
// OOP | ||
// --------------- | ||
// If Underscore is called as a function, it returns a wrapped object that | ||
// can be used OO-style. This wrapper holds altered versions of all the | ||
// underscore functions. Wrapped objects may be chained. | ||
// Helper function to continue chaining intermediate results. | ||
var chainResult = function chainResult(instance, obj) { | ||
return instance._chain ? _(obj).chain() : obj; | ||
}; | ||
// Add your own custom functions to the Underscore object. | ||
_.mixin = function (obj) { | ||
_.each(_.functions(obj), function (name) { | ||
var func = _[name] = obj[name]; | ||
_.prototype[name] = function () { | ||
var args = [this._wrapped]; | ||
push.apply(args, arguments); | ||
return chainResult(this, func.apply(_, args)); | ||
}; | ||
}); | ||
}; | ||
// Add all of the Underscore functions to the wrapper object. | ||
_.mixin(_); | ||
// Add all mutator Array functions to the wrapper. | ||
_.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function (name) { | ||
var method = ArrayProto[name]; | ||
_.prototype[name] = function () { | ||
var obj = this._wrapped; | ||
method.apply(obj, arguments); | ||
if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; | ||
return chainResult(this, obj); | ||
}; | ||
}); | ||
// Add all accessor Array functions to the wrapper. | ||
_.each(['concat', 'join', 'slice'], function (name) { | ||
var method = ArrayProto[name]; | ||
_.prototype[name] = function () { | ||
return chainResult(this, method.apply(this._wrapped, arguments)); | ||
}; | ||
}); | ||
// Extracts the result from a wrapped and chained object. | ||
_.prototype.value = function () { | ||
return this._wrapped; | ||
}; | ||
// Provide unwrapping proxy for some methods used in engine operations | ||
// such as arithmetic and JSON stringification. | ||
_.prototype.valueOf = _.prototype.toJSON = _.prototype.value; | ||
_.prototype.toString = function () { | ||
return '' + this._wrapped; | ||
}; | ||
// AMD registration happens at the end for compatibility with AMD loaders | ||
// that may not enforce next-turn semantics on modules. Even though general | ||
// practice for AMD registration is to be anonymous, underscore registers | ||
// as a named module because, like jQuery, it is a base library that is | ||
// popular enough to be bundled in a third party lib, but not be part of | ||
// an AMD load request. Those cases could generate an error when an | ||
// anonymous define() is called outside of a loader request. | ||
if (typeof define === 'function' && define.amd) { | ||
define('underscore', [], function () { | ||
return _; | ||
}); | ||
if (arrays) { | ||
var result = []; | ||
flattenInternal(result, arrays); | ||
return result; | ||
} | ||
})(); | ||
} |
@@ -98,3 +98,3 @@ 'use strict'; | ||
injectStyleTag(); | ||
(0, _utilsHelpers.each)(styles, function (style) { | ||
styles.forEach(function (style) { | ||
updateStore(style.id, style.style, style.pseudoClass, style.disabled); | ||
@@ -119,3 +119,3 @@ }); | ||
function removeAllStyles(styleIds) { | ||
(0, _utilsHelpers.each)(styleIds, function (styleId) { | ||
styleIds.forEach(function (styleId) { | ||
delete styleStorage[styleId]; | ||
@@ -122,0 +122,0 @@ }); |
{ | ||
"name": "belle", | ||
"version": "1.0.1", | ||
"version": "1.0.2", | ||
"description": "Configurable React Components with great UX", | ||
@@ -33,3 +33,3 @@ "author": { | ||
"postinstall": "rm -rf node_modules/react/", | ||
"test": "cd tests && npm install && ln -snf ../lib lib && cd .. && jest tests/" | ||
"test": "babel --out-dir='lib' --optional='es7.classProperties' src && cd tests && npm install && ln -snf ../lib lib && cd .. && jest tests/" | ||
}, | ||
@@ -36,0 +36,0 @@ "devDependencies": { |
@@ -7,3 +7,3 @@ # Belle | ||
![belle-overview](https://cloud.githubusercontent.com/assets/223045/8707250/f77634f8-2b34-11e5-92d1-f0b0fe44ade9.png) | ||
[<img src="https://cloud.githubusercontent.com/assets/223045/8707250/f77634f8-2b34-11e5-92d1-f0b0fe44ade9.png" width="50%">](http://nikgraf.github.io/belle/) | ||
@@ -157,2 +157,4 @@ ## Getting Started | ||
In addition you can ask the community by [posting your question to StackOverflow with the **belle** tag.](http://stackoverflow.com/questions/ask?tags=belle). | ||
## Future Plans | ||
@@ -164,6 +166,4 @@ | ||
The implementation of the TextInput component was heavily inspired by implementations of [Andrey Popp](https://github.com/andreypopp) & [Eugene](https://github.com/eugene1g). | ||
Thanks to [Andrey Popp](https://github.com/andreypopp) & [Eugene](https://github.com/eugene1g) for their inspiring work on [React TextArea Autosize](https://github.com/andreypopp/react-textarea-autosize) which kind of ignited the idea of Belle. | ||
Thanks to [https://github.com/andreypopp](Andrey Popp) & [https://github.com/eugene1g](Eugene) for their inspiring work on [https://github.com/andreypopp/react-textarea-autosize](React TextArea Autosize) which kind of ignited the idea of Belle. | ||
Thanks to Christian Steiner from [http://www.cropd.at/](cropd.at) for creating the logo and helping out with the design. | ||
@@ -170,0 +170,0 @@ |
AI-detected potential security risk
Supply chain riskAI has determined that this package may contain potential security issues or vulnerabilities.
Found 1 instance in 1 package
0
892590
21926