1a2d6209f9
fix styles: make thin-small 15px instead of 14px (was too small)
29183 lines
893 KiB
JavaScript
29183 lines
893 KiB
JavaScript
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
|
// shim for using process in browser
|
|
|
|
var process = module.exports = {};
|
|
var queue = [];
|
|
var draining = false;
|
|
var currentQueue;
|
|
var queueIndex = -1;
|
|
|
|
function cleanUpNextTick() {
|
|
draining = false;
|
|
if (currentQueue.length) {
|
|
queue = currentQueue.concat(queue);
|
|
} else {
|
|
queueIndex = -1;
|
|
}
|
|
if (queue.length) {
|
|
drainQueue();
|
|
}
|
|
}
|
|
|
|
function drainQueue() {
|
|
if (draining) {
|
|
return;
|
|
}
|
|
var timeout = setTimeout(cleanUpNextTick);
|
|
draining = true;
|
|
|
|
var len = queue.length;
|
|
while(len) {
|
|
currentQueue = queue;
|
|
queue = [];
|
|
while (++queueIndex < len) {
|
|
currentQueue[queueIndex].run();
|
|
}
|
|
queueIndex = -1;
|
|
len = queue.length;
|
|
}
|
|
currentQueue = null;
|
|
draining = false;
|
|
clearTimeout(timeout);
|
|
}
|
|
|
|
process.nextTick = function (fun) {
|
|
var args = new Array(arguments.length - 1);
|
|
if (arguments.length > 1) {
|
|
for (var i = 1; i < arguments.length; i++) {
|
|
args[i - 1] = arguments[i];
|
|
}
|
|
}
|
|
queue.push(new Item(fun, args));
|
|
if (queue.length === 1 && !draining) {
|
|
setTimeout(drainQueue, 0);
|
|
}
|
|
};
|
|
|
|
// v8 likes predictible objects
|
|
function Item(fun, array) {
|
|
this.fun = fun;
|
|
this.array = array;
|
|
}
|
|
Item.prototype.run = function () {
|
|
this.fun.apply(null, this.array);
|
|
};
|
|
process.title = 'browser';
|
|
process.browser = true;
|
|
process.env = {};
|
|
process.argv = [];
|
|
process.version = ''; // empty string to avoid regexp issues
|
|
process.versions = {};
|
|
|
|
function noop() {}
|
|
|
|
process.on = noop;
|
|
process.addListener = noop;
|
|
process.once = noop;
|
|
process.off = noop;
|
|
process.removeListener = noop;
|
|
process.removeAllListeners = noop;
|
|
process.emit = noop;
|
|
|
|
process.binding = function (name) {
|
|
throw new Error('process.binding is not supported');
|
|
};
|
|
|
|
// TODO(shtylman)
|
|
process.cwd = function () { return '/' };
|
|
process.chdir = function (dir) {
|
|
throw new Error('process.chdir is not supported');
|
|
};
|
|
process.umask = function() { return 0; };
|
|
|
|
},{}],2:[function(require,module,exports){
|
|
/** Used as the `TypeError` message for "Functions" methods. */
|
|
var FUNC_ERROR_TEXT = 'Expected a function';
|
|
|
|
/* Native method references for those with the same name as other `lodash` methods. */
|
|
var nativeMax = Math.max;
|
|
|
|
/**
|
|
* Creates a function that invokes `func` with the `this` binding of the
|
|
* created function and arguments from `start` and beyond provided as an array.
|
|
*
|
|
* **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Function
|
|
* @param {Function} func The function to apply a rest parameter to.
|
|
* @param {number} [start=func.length-1] The start position of the rest parameter.
|
|
* @returns {Function} Returns the new function.
|
|
* @example
|
|
*
|
|
* var say = _.restParam(function(what, names) {
|
|
* return what + ' ' + _.initial(names).join(', ') +
|
|
* (_.size(names) > 1 ? ', & ' : '') + _.last(names);
|
|
* });
|
|
*
|
|
* say('hello', 'fred', 'barney', 'pebbles');
|
|
* // => 'hello fred, barney, & pebbles'
|
|
*/
|
|
function restParam(func, start) {
|
|
if (typeof func != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);
|
|
return function() {
|
|
var args = arguments,
|
|
index = -1,
|
|
length = nativeMax(args.length - start, 0),
|
|
rest = Array(length);
|
|
|
|
while (++index < length) {
|
|
rest[index] = args[start + index];
|
|
}
|
|
switch (start) {
|
|
case 0: return func.call(this, rest);
|
|
case 1: return func.call(this, args[0], rest);
|
|
case 2: return func.call(this, args[0], args[1], rest);
|
|
}
|
|
var otherArgs = Array(start + 1);
|
|
index = -1;
|
|
while (++index < start) {
|
|
otherArgs[index] = args[index];
|
|
}
|
|
otherArgs[start] = rest;
|
|
return func.apply(this, otherArgs);
|
|
};
|
|
}
|
|
|
|
module.exports = restParam;
|
|
|
|
},{}],3:[function(require,module,exports){
|
|
(function (global){
|
|
var cachePush = require('./cachePush'),
|
|
getNative = require('./getNative');
|
|
|
|
/** Native method references. */
|
|
var Set = getNative(global, 'Set');
|
|
|
|
/* Native method references for those with the same name as other `lodash` methods. */
|
|
var nativeCreate = getNative(Object, 'create');
|
|
|
|
/**
|
|
*
|
|
* Creates a cache object to store unique values.
|
|
*
|
|
* @private
|
|
* @param {Array} [values] The values to cache.
|
|
*/
|
|
function SetCache(values) {
|
|
var length = values ? values.length : 0;
|
|
|
|
this.data = { 'hash': nativeCreate(null), 'set': new Set };
|
|
while (length--) {
|
|
this.push(values[length]);
|
|
}
|
|
}
|
|
|
|
// Add functions to the `Set` cache.
|
|
SetCache.prototype.push = cachePush;
|
|
|
|
module.exports = SetCache;
|
|
|
|
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
},{"./cachePush":15,"./getNative":21}],4:[function(require,module,exports){
|
|
/**
|
|
* A specialized version of `_.map` for arrays without support for callback
|
|
* shorthands and `this` binding.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Array} Returns the new mapped array.
|
|
*/
|
|
function arrayMap(array, iteratee) {
|
|
var index = -1,
|
|
length = array.length,
|
|
result = Array(length);
|
|
|
|
while (++index < length) {
|
|
result[index] = iteratee(array[index], index, array);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
module.exports = arrayMap;
|
|
|
|
},{}],5:[function(require,module,exports){
|
|
/**
|
|
* Appends the elements of `values` to `array`.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to modify.
|
|
* @param {Array} values The values to append.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function arrayPush(array, values) {
|
|
var index = -1,
|
|
length = values.length,
|
|
offset = array.length;
|
|
|
|
while (++index < length) {
|
|
array[offset + index] = values[index];
|
|
}
|
|
return array;
|
|
}
|
|
|
|
module.exports = arrayPush;
|
|
|
|
},{}],6:[function(require,module,exports){
|
|
var baseIndexOf = require('./baseIndexOf'),
|
|
cacheIndexOf = require('./cacheIndexOf'),
|
|
createCache = require('./createCache');
|
|
|
|
/** Used as the size to enable large array optimizations. */
|
|
var LARGE_ARRAY_SIZE = 200;
|
|
|
|
/**
|
|
* The base implementation of `_.difference` which accepts a single array
|
|
* of values to exclude.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {Array} values The values to exclude.
|
|
* @returns {Array} Returns the new array of filtered values.
|
|
*/
|
|
function baseDifference(array, values) {
|
|
var length = array ? array.length : 0,
|
|
result = [];
|
|
|
|
if (!length) {
|
|
return result;
|
|
}
|
|
var index = -1,
|
|
indexOf = baseIndexOf,
|
|
isCommon = true,
|
|
cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(values) : null,
|
|
valuesLength = values.length;
|
|
|
|
if (cache) {
|
|
indexOf = cacheIndexOf;
|
|
isCommon = false;
|
|
values = cache;
|
|
}
|
|
outer:
|
|
while (++index < length) {
|
|
var value = array[index];
|
|
|
|
if (isCommon && value === value) {
|
|
var valuesIndex = valuesLength;
|
|
while (valuesIndex--) {
|
|
if (values[valuesIndex] === value) {
|
|
continue outer;
|
|
}
|
|
}
|
|
result.push(value);
|
|
}
|
|
else if (indexOf(values, value, 0) < 0) {
|
|
result.push(value);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
module.exports = baseDifference;
|
|
|
|
},{"./baseIndexOf":10,"./cacheIndexOf":14,"./createCache":17}],7:[function(require,module,exports){
|
|
var arrayPush = require('./arrayPush'),
|
|
isArguments = require('../lang/isArguments'),
|
|
isArray = require('../lang/isArray'),
|
|
isArrayLike = require('./isArrayLike'),
|
|
isObjectLike = require('./isObjectLike');
|
|
|
|
/**
|
|
* The base implementation of `_.flatten` with added support for restricting
|
|
* flattening and specifying the start index.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to flatten.
|
|
* @param {boolean} [isDeep] Specify a deep flatten.
|
|
* @param {boolean} [isStrict] Restrict flattening to arrays-like objects.
|
|
* @param {Array} [result=[]] The initial result value.
|
|
* @returns {Array} Returns the new flattened array.
|
|
*/
|
|
function baseFlatten(array, isDeep, isStrict, result) {
|
|
result || (result = []);
|
|
|
|
var index = -1,
|
|
length = array.length;
|
|
|
|
while (++index < length) {
|
|
var value = array[index];
|
|
if (isObjectLike(value) && isArrayLike(value) &&
|
|
(isStrict || isArray(value) || isArguments(value))) {
|
|
if (isDeep) {
|
|
// Recursively flatten arrays (susceptible to call stack limits).
|
|
baseFlatten(value, isDeep, isStrict, result);
|
|
} else {
|
|
arrayPush(result, value);
|
|
}
|
|
} else if (!isStrict) {
|
|
result[result.length] = value;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
module.exports = baseFlatten;
|
|
|
|
},{"../lang/isArguments":31,"../lang/isArray":32,"./arrayPush":5,"./isArrayLike":23,"./isObjectLike":27}],8:[function(require,module,exports){
|
|
var createBaseFor = require('./createBaseFor');
|
|
|
|
/**
|
|
* The base implementation of `baseForIn` and `baseForOwn` which iterates
|
|
* over `object` properties returned by `keysFunc` invoking `iteratee` for
|
|
* each property. Iteratee functions may exit iteration early by explicitly
|
|
* returning `false`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @param {Function} keysFunc The function to get the keys of `object`.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
var baseFor = createBaseFor();
|
|
|
|
module.exports = baseFor;
|
|
|
|
},{"./createBaseFor":16}],9:[function(require,module,exports){
|
|
var baseFor = require('./baseFor'),
|
|
keysIn = require('../object/keysIn');
|
|
|
|
/**
|
|
* The base implementation of `_.forIn` without support for callback
|
|
* shorthands and `this` binding.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function baseForIn(object, iteratee) {
|
|
return baseFor(object, iteratee, keysIn);
|
|
}
|
|
|
|
module.exports = baseForIn;
|
|
|
|
},{"../object/keysIn":36,"./baseFor":8}],10:[function(require,module,exports){
|
|
var indexOfNaN = require('./indexOfNaN');
|
|
|
|
/**
|
|
* The base implementation of `_.indexOf` without support for binary searches.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to search.
|
|
* @param {*} value The value to search for.
|
|
* @param {number} fromIndex The index to search from.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
*/
|
|
function baseIndexOf(array, value, fromIndex) {
|
|
if (value !== value) {
|
|
return indexOfNaN(array, fromIndex);
|
|
}
|
|
var index = fromIndex - 1,
|
|
length = array.length;
|
|
|
|
while (++index < length) {
|
|
if (array[index] === value) {
|
|
return index;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
module.exports = baseIndexOf;
|
|
|
|
},{"./indexOfNaN":22}],11:[function(require,module,exports){
|
|
/**
|
|
* The base implementation of `_.property` without support for deep paths.
|
|
*
|
|
* @private
|
|
* @param {string} key The key of the property to get.
|
|
* @returns {Function} Returns the new function.
|
|
*/
|
|
function baseProperty(key) {
|
|
return function(object) {
|
|
return object == null ? undefined : object[key];
|
|
};
|
|
}
|
|
|
|
module.exports = baseProperty;
|
|
|
|
},{}],12:[function(require,module,exports){
|
|
/**
|
|
* Converts `value` to a string if it's not one. An empty string is returned
|
|
* for `null` or `undefined` values.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to process.
|
|
* @returns {string} Returns the string.
|
|
*/
|
|
function baseToString(value) {
|
|
return value == null ? '' : (value + '');
|
|
}
|
|
|
|
module.exports = baseToString;
|
|
|
|
},{}],13:[function(require,module,exports){
|
|
var identity = require('../utility/identity');
|
|
|
|
/**
|
|
* A specialized version of `baseCallback` which only supports `this` binding
|
|
* and specifying the number of arguments to provide to `func`.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to bind.
|
|
* @param {*} thisArg The `this` binding of `func`.
|
|
* @param {number} [argCount] The number of arguments to provide to `func`.
|
|
* @returns {Function} Returns the callback.
|
|
*/
|
|
function bindCallback(func, thisArg, argCount) {
|
|
if (typeof func != 'function') {
|
|
return identity;
|
|
}
|
|
if (thisArg === undefined) {
|
|
return func;
|
|
}
|
|
switch (argCount) {
|
|
case 1: return function(value) {
|
|
return func.call(thisArg, value);
|
|
};
|
|
case 3: return function(value, index, collection) {
|
|
return func.call(thisArg, value, index, collection);
|
|
};
|
|
case 4: return function(accumulator, value, index, collection) {
|
|
return func.call(thisArg, accumulator, value, index, collection);
|
|
};
|
|
case 5: return function(value, other, key, object, source) {
|
|
return func.call(thisArg, value, other, key, object, source);
|
|
};
|
|
}
|
|
return function() {
|
|
return func.apply(thisArg, arguments);
|
|
};
|
|
}
|
|
|
|
module.exports = bindCallback;
|
|
|
|
},{"../utility/identity":41}],14:[function(require,module,exports){
|
|
var isObject = require('../lang/isObject');
|
|
|
|
/**
|
|
* Checks if `value` is in `cache` mimicking the return signature of
|
|
* `_.indexOf` by returning `0` if the value is found, else `-1`.
|
|
*
|
|
* @private
|
|
* @param {Object} cache The cache to search.
|
|
* @param {*} value The value to search for.
|
|
* @returns {number} Returns `0` if `value` is found, else `-1`.
|
|
*/
|
|
function cacheIndexOf(cache, value) {
|
|
var data = cache.data,
|
|
result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value];
|
|
|
|
return result ? 0 : -1;
|
|
}
|
|
|
|
module.exports = cacheIndexOf;
|
|
|
|
},{"../lang/isObject":35}],15:[function(require,module,exports){
|
|
var isObject = require('../lang/isObject');
|
|
|
|
/**
|
|
* Adds `value` to the cache.
|
|
*
|
|
* @private
|
|
* @name push
|
|
* @memberOf SetCache
|
|
* @param {*} value The value to cache.
|
|
*/
|
|
function cachePush(value) {
|
|
var data = this.data;
|
|
if (typeof value == 'string' || isObject(value)) {
|
|
data.set.add(value);
|
|
} else {
|
|
data.hash[value] = true;
|
|
}
|
|
}
|
|
|
|
module.exports = cachePush;
|
|
|
|
},{"../lang/isObject":35}],16:[function(require,module,exports){
|
|
var toObject = require('./toObject');
|
|
|
|
/**
|
|
* Creates a base function for `_.forIn` or `_.forInRight`.
|
|
*
|
|
* @private
|
|
* @param {boolean} [fromRight] Specify iterating from right to left.
|
|
* @returns {Function} Returns the new base function.
|
|
*/
|
|
function createBaseFor(fromRight) {
|
|
return function(object, iteratee, keysFunc) {
|
|
var iterable = toObject(object),
|
|
props = keysFunc(object),
|
|
length = props.length,
|
|
index = fromRight ? length : -1;
|
|
|
|
while ((fromRight ? index-- : ++index < length)) {
|
|
var key = props[index];
|
|
if (iteratee(iterable[key], key, iterable) === false) {
|
|
break;
|
|
}
|
|
}
|
|
return object;
|
|
};
|
|
}
|
|
|
|
module.exports = createBaseFor;
|
|
|
|
},{"./toObject":30}],17:[function(require,module,exports){
|
|
(function (global){
|
|
var SetCache = require('./SetCache'),
|
|
getNative = require('./getNative');
|
|
|
|
/** Native method references. */
|
|
var Set = getNative(global, 'Set');
|
|
|
|
/* Native method references for those with the same name as other `lodash` methods. */
|
|
var nativeCreate = getNative(Object, 'create');
|
|
|
|
/**
|
|
* Creates a `Set` cache object to optimize linear searches of large arrays.
|
|
*
|
|
* @private
|
|
* @param {Array} [values] The values to cache.
|
|
* @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`.
|
|
*/
|
|
function createCache(values) {
|
|
return (nativeCreate && Set) ? new SetCache(values) : null;
|
|
}
|
|
|
|
module.exports = createCache;
|
|
|
|
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
},{"./SetCache":3,"./getNative":21}],18:[function(require,module,exports){
|
|
var deburr = require('../string/deburr'),
|
|
words = require('../string/words');
|
|
|
|
/**
|
|
* Creates a function that produces compound words out of the words in a
|
|
* given string.
|
|
*
|
|
* @private
|
|
* @param {Function} callback The function to combine each word.
|
|
* @returns {Function} Returns the new compounder function.
|
|
*/
|
|
function createCompounder(callback) {
|
|
return function(string) {
|
|
var index = -1,
|
|
array = words(deburr(string)),
|
|
length = array.length,
|
|
result = '';
|
|
|
|
while (++index < length) {
|
|
result = callback(result, array[index], index);
|
|
}
|
|
return result;
|
|
};
|
|
}
|
|
|
|
module.exports = createCompounder;
|
|
|
|
},{"../string/deburr":39,"../string/words":40}],19:[function(require,module,exports){
|
|
/** Used to map latin-1 supplementary letters to basic latin letters. */
|
|
var deburredLetters = {
|
|
'\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
|
|
'\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
|
|
'\xc7': 'C', '\xe7': 'c',
|
|
'\xd0': 'D', '\xf0': 'd',
|
|
'\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
|
|
'\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
|
|
'\xcC': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
|
|
'\xeC': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i',
|
|
'\xd1': 'N', '\xf1': 'n',
|
|
'\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
|
|
'\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
|
|
'\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
|
|
'\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
|
|
'\xdd': 'Y', '\xfd': 'y', '\xff': 'y',
|
|
'\xc6': 'Ae', '\xe6': 'ae',
|
|
'\xde': 'Th', '\xfe': 'th',
|
|
'\xdf': 'ss'
|
|
};
|
|
|
|
/**
|
|
* Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters.
|
|
*
|
|
* @private
|
|
* @param {string} letter The matched letter to deburr.
|
|
* @returns {string} Returns the deburred letter.
|
|
*/
|
|
function deburrLetter(letter) {
|
|
return deburredLetters[letter];
|
|
}
|
|
|
|
module.exports = deburrLetter;
|
|
|
|
},{}],20:[function(require,module,exports){
|
|
var baseProperty = require('./baseProperty');
|
|
|
|
/**
|
|
* Gets the "length" property value of `object`.
|
|
*
|
|
* **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
|
|
* that affects Safari on at least iOS 8.1-8.3 ARM64.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {*} Returns the "length" value.
|
|
*/
|
|
var getLength = baseProperty('length');
|
|
|
|
module.exports = getLength;
|
|
|
|
},{"./baseProperty":11}],21:[function(require,module,exports){
|
|
var isNative = require('../lang/isNative');
|
|
|
|
/**
|
|
* Gets the native function at `key` of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @param {string} key The key of the method to get.
|
|
* @returns {*} Returns the function if it's native, else `undefined`.
|
|
*/
|
|
function getNative(object, key) {
|
|
var value = object == null ? undefined : object[key];
|
|
return isNative(value) ? value : undefined;
|
|
}
|
|
|
|
module.exports = getNative;
|
|
|
|
},{"../lang/isNative":34}],22:[function(require,module,exports){
|
|
/**
|
|
* Gets the index at which the first occurrence of `NaN` is found in `array`.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to search.
|
|
* @param {number} fromIndex The index to search from.
|
|
* @param {boolean} [fromRight] Specify iterating from right to left.
|
|
* @returns {number} Returns the index of the matched `NaN`, else `-1`.
|
|
*/
|
|
function indexOfNaN(array, fromIndex, fromRight) {
|
|
var length = array.length,
|
|
index = fromIndex + (fromRight ? 0 : -1);
|
|
|
|
while ((fromRight ? index-- : ++index < length)) {
|
|
var other = array[index];
|
|
if (other !== other) {
|
|
return index;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
module.exports = indexOfNaN;
|
|
|
|
},{}],23:[function(require,module,exports){
|
|
var getLength = require('./getLength'),
|
|
isLength = require('./isLength');
|
|
|
|
/**
|
|
* Checks if `value` is array-like.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
|
|
*/
|
|
function isArrayLike(value) {
|
|
return value != null && isLength(getLength(value));
|
|
}
|
|
|
|
module.exports = isArrayLike;
|
|
|
|
},{"./getLength":20,"./isLength":26}],24:[function(require,module,exports){
|
|
/** Used to detect unsigned integer values. */
|
|
var reIsUint = /^\d+$/;
|
|
|
|
/**
|
|
* Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
|
|
* of an array-like value.
|
|
*/
|
|
var MAX_SAFE_INTEGER = 9007199254740991;
|
|
|
|
/**
|
|
* Checks if `value` is a valid array-like index.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
|
|
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
|
|
*/
|
|
function isIndex(value, length) {
|
|
value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
|
|
length = length == null ? MAX_SAFE_INTEGER : length;
|
|
return value > -1 && value % 1 == 0 && value < length;
|
|
}
|
|
|
|
module.exports = isIndex;
|
|
|
|
},{}],25:[function(require,module,exports){
|
|
var isArrayLike = require('./isArrayLike'),
|
|
isIndex = require('./isIndex'),
|
|
isObject = require('../lang/isObject');
|
|
|
|
/**
|
|
* Checks if the provided arguments are from an iteratee call.
|
|
*
|
|
* @private
|
|
* @param {*} value The potential iteratee value argument.
|
|
* @param {*} index The potential iteratee index or key argument.
|
|
* @param {*} object The potential iteratee object argument.
|
|
* @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
|
|
*/
|
|
function isIterateeCall(value, index, object) {
|
|
if (!isObject(object)) {
|
|
return false;
|
|
}
|
|
var type = typeof index;
|
|
if (type == 'number'
|
|
? (isArrayLike(object) && isIndex(index, object.length))
|
|
: (type == 'string' && index in object)) {
|
|
var other = object[index];
|
|
return value === value ? (value === other) : (other !== other);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
module.exports = isIterateeCall;
|
|
|
|
},{"../lang/isObject":35,"./isArrayLike":23,"./isIndex":24}],26:[function(require,module,exports){
|
|
/**
|
|
* Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
|
|
* of an array-like value.
|
|
*/
|
|
var MAX_SAFE_INTEGER = 9007199254740991;
|
|
|
|
/**
|
|
* Checks if `value` is a valid array-like length.
|
|
*
|
|
* **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
|
|
*/
|
|
function isLength(value) {
|
|
return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
|
|
}
|
|
|
|
module.exports = isLength;
|
|
|
|
},{}],27:[function(require,module,exports){
|
|
/**
|
|
* Checks if `value` is object-like.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
|
*/
|
|
function isObjectLike(value) {
|
|
return !!value && typeof value == 'object';
|
|
}
|
|
|
|
module.exports = isObjectLike;
|
|
|
|
},{}],28:[function(require,module,exports){
|
|
var toObject = require('./toObject');
|
|
|
|
/**
|
|
* A specialized version of `_.pick` which picks `object` properties specified
|
|
* by `props`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The source object.
|
|
* @param {string[]} props The property names to pick.
|
|
* @returns {Object} Returns the new object.
|
|
*/
|
|
function pickByArray(object, props) {
|
|
object = toObject(object);
|
|
|
|
var index = -1,
|
|
length = props.length,
|
|
result = {};
|
|
|
|
while (++index < length) {
|
|
var key = props[index];
|
|
if (key in object) {
|
|
result[key] = object[key];
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
module.exports = pickByArray;
|
|
|
|
},{"./toObject":30}],29:[function(require,module,exports){
|
|
var baseForIn = require('./baseForIn');
|
|
|
|
/**
|
|
* A specialized version of `_.pick` which picks `object` properties `predicate`
|
|
* returns truthy for.
|
|
*
|
|
* @private
|
|
* @param {Object} object The source object.
|
|
* @param {Function} predicate The function invoked per iteration.
|
|
* @returns {Object} Returns the new object.
|
|
*/
|
|
function pickByCallback(object, predicate) {
|
|
var result = {};
|
|
baseForIn(object, function(value, key, object) {
|
|
if (predicate(value, key, object)) {
|
|
result[key] = value;
|
|
}
|
|
});
|
|
return result;
|
|
}
|
|
|
|
module.exports = pickByCallback;
|
|
|
|
},{"./baseForIn":9}],30:[function(require,module,exports){
|
|
var isObject = require('../lang/isObject');
|
|
|
|
/**
|
|
* Converts `value` to an object if it's not one.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to process.
|
|
* @returns {Object} Returns the object.
|
|
*/
|
|
function toObject(value) {
|
|
return isObject(value) ? value : Object(value);
|
|
}
|
|
|
|
module.exports = toObject;
|
|
|
|
},{"../lang/isObject":35}],31:[function(require,module,exports){
|
|
var isArrayLike = require('../internal/isArrayLike'),
|
|
isObjectLike = require('../internal/isObjectLike');
|
|
|
|
/** Used for native method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/** Used to check objects for own properties. */
|
|
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
|
|
/** Native method references. */
|
|
var propertyIsEnumerable = objectProto.propertyIsEnumerable;
|
|
|
|
/**
|
|
* Checks if `value` is classified as an `arguments` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
|
* @example
|
|
*
|
|
* _.isArguments(function() { return arguments; }());
|
|
* // => true
|
|
*
|
|
* _.isArguments([1, 2, 3]);
|
|
* // => false
|
|
*/
|
|
function isArguments(value) {
|
|
return isObjectLike(value) && isArrayLike(value) &&
|
|
hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');
|
|
}
|
|
|
|
module.exports = isArguments;
|
|
|
|
},{"../internal/isArrayLike":23,"../internal/isObjectLike":27}],32:[function(require,module,exports){
|
|
var getNative = require('../internal/getNative'),
|
|
isLength = require('../internal/isLength'),
|
|
isObjectLike = require('../internal/isObjectLike');
|
|
|
|
/** `Object#toString` result references. */
|
|
var arrayTag = '[object Array]';
|
|
|
|
/** Used for native method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/**
|
|
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
|
|
* of values.
|
|
*/
|
|
var objToString = objectProto.toString;
|
|
|
|
/* Native method references for those with the same name as other `lodash` methods. */
|
|
var nativeIsArray = getNative(Array, 'isArray');
|
|
|
|
/**
|
|
* Checks if `value` is classified as an `Array` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
|
* @example
|
|
*
|
|
* _.isArray([1, 2, 3]);
|
|
* // => true
|
|
*
|
|
* _.isArray(function() { return arguments; }());
|
|
* // => false
|
|
*/
|
|
var isArray = nativeIsArray || function(value) {
|
|
return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
|
|
};
|
|
|
|
module.exports = isArray;
|
|
|
|
},{"../internal/getNative":21,"../internal/isLength":26,"../internal/isObjectLike":27}],33:[function(require,module,exports){
|
|
var isObject = require('./isObject');
|
|
|
|
/** `Object#toString` result references. */
|
|
var funcTag = '[object Function]';
|
|
|
|
/** Used for native method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/**
|
|
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
|
|
* of values.
|
|
*/
|
|
var objToString = objectProto.toString;
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `Function` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
|
* @example
|
|
*
|
|
* _.isFunction(_);
|
|
* // => true
|
|
*
|
|
* _.isFunction(/abc/);
|
|
* // => false
|
|
*/
|
|
function isFunction(value) {
|
|
// The use of `Object#toString` avoids issues with the `typeof` operator
|
|
// in older versions of Chrome and Safari which return 'function' for regexes
|
|
// and Safari 8 which returns 'object' for typed array constructors.
|
|
return isObject(value) && objToString.call(value) == funcTag;
|
|
}
|
|
|
|
module.exports = isFunction;
|
|
|
|
},{"./isObject":35}],34:[function(require,module,exports){
|
|
var isFunction = require('./isFunction'),
|
|
isObjectLike = require('../internal/isObjectLike');
|
|
|
|
/** Used to detect host constructors (Safari > 5). */
|
|
var reIsHostCtor = /^\[object .+?Constructor\]$/;
|
|
|
|
/** Used for native method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/** Used to resolve the decompiled source of functions. */
|
|
var fnToString = Function.prototype.toString;
|
|
|
|
/** Used to check objects for own properties. */
|
|
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
|
|
/** Used to detect if a method is native. */
|
|
var reIsNative = RegExp('^' +
|
|
fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
|
|
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
|
|
);
|
|
|
|
/**
|
|
* Checks if `value` is a native function.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a native function, else `false`.
|
|
* @example
|
|
*
|
|
* _.isNative(Array.prototype.push);
|
|
* // => true
|
|
*
|
|
* _.isNative(_);
|
|
* // => false
|
|
*/
|
|
function isNative(value) {
|
|
if (value == null) {
|
|
return false;
|
|
}
|
|
if (isFunction(value)) {
|
|
return reIsNative.test(fnToString.call(value));
|
|
}
|
|
return isObjectLike(value) && reIsHostCtor.test(value);
|
|
}
|
|
|
|
module.exports = isNative;
|
|
|
|
},{"../internal/isObjectLike":27,"./isFunction":33}],35:[function(require,module,exports){
|
|
/**
|
|
* Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
|
|
* (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
|
* @example
|
|
*
|
|
* _.isObject({});
|
|
* // => true
|
|
*
|
|
* _.isObject([1, 2, 3]);
|
|
* // => true
|
|
*
|
|
* _.isObject(1);
|
|
* // => false
|
|
*/
|
|
function isObject(value) {
|
|
// Avoid a V8 JIT bug in Chrome 19-20.
|
|
// See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
|
|
var type = typeof value;
|
|
return !!value && (type == 'object' || type == 'function');
|
|
}
|
|
|
|
module.exports = isObject;
|
|
|
|
},{}],36:[function(require,module,exports){
|
|
var isArguments = require('../lang/isArguments'),
|
|
isArray = require('../lang/isArray'),
|
|
isIndex = require('../internal/isIndex'),
|
|
isLength = require('../internal/isLength'),
|
|
isObject = require('../lang/isObject');
|
|
|
|
/** Used for native method references. */
|
|
var objectProto = Object.prototype;
|
|
|
|
/** Used to check objects for own properties. */
|
|
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
|
|
/**
|
|
* Creates an array of the own and inherited enumerable property names of `object`.
|
|
*
|
|
* **Note:** Non-object values are coerced to objects.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property names.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.keysIn(new Foo);
|
|
* // => ['a', 'b', 'c'] (iteration order is not guaranteed)
|
|
*/
|
|
function keysIn(object) {
|
|
if (object == null) {
|
|
return [];
|
|
}
|
|
if (!isObject(object)) {
|
|
object = Object(object);
|
|
}
|
|
var length = object.length;
|
|
length = (length && isLength(length) &&
|
|
(isArray(object) || isArguments(object)) && length) || 0;
|
|
|
|
var Ctor = object.constructor,
|
|
index = -1,
|
|
isProto = typeof Ctor == 'function' && Ctor.prototype === object,
|
|
result = Array(length),
|
|
skipIndexes = length > 0;
|
|
|
|
while (++index < length) {
|
|
result[index] = (index + '');
|
|
}
|
|
for (var key in object) {
|
|
if (!(skipIndexes && isIndex(key, length)) &&
|
|
!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
|
|
result.push(key);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
module.exports = keysIn;
|
|
|
|
},{"../internal/isIndex":24,"../internal/isLength":26,"../lang/isArguments":31,"../lang/isArray":32,"../lang/isObject":35}],37:[function(require,module,exports){
|
|
var arrayMap = require('../internal/arrayMap'),
|
|
baseDifference = require('../internal/baseDifference'),
|
|
baseFlatten = require('../internal/baseFlatten'),
|
|
bindCallback = require('../internal/bindCallback'),
|
|
keysIn = require('./keysIn'),
|
|
pickByArray = require('../internal/pickByArray'),
|
|
pickByCallback = require('../internal/pickByCallback'),
|
|
restParam = require('../function/restParam');
|
|
|
|
/**
|
|
* The opposite of `_.pick`; this method creates an object composed of the
|
|
* own and inherited enumerable properties of `object` that are not omitted.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The source object.
|
|
* @param {Function|...(string|string[])} [predicate] The function invoked per
|
|
* iteration or property names to omit, specified as individual property
|
|
* names or arrays of property names.
|
|
* @param {*} [thisArg] The `this` binding of `predicate`.
|
|
* @returns {Object} Returns the new object.
|
|
* @example
|
|
*
|
|
* var object = { 'user': 'fred', 'age': 40 };
|
|
*
|
|
* _.omit(object, 'age');
|
|
* // => { 'user': 'fred' }
|
|
*
|
|
* _.omit(object, _.isNumber);
|
|
* // => { 'user': 'fred' }
|
|
*/
|
|
var omit = restParam(function(object, props) {
|
|
if (object == null) {
|
|
return {};
|
|
}
|
|
if (typeof props[0] != 'function') {
|
|
var props = arrayMap(baseFlatten(props), String);
|
|
return pickByArray(object, baseDifference(keysIn(object), props));
|
|
}
|
|
var predicate = bindCallback(props[0], props[1], 3);
|
|
return pickByCallback(object, function(value, key, object) {
|
|
return !predicate(value, key, object);
|
|
});
|
|
});
|
|
|
|
module.exports = omit;
|
|
|
|
},{"../function/restParam":2,"../internal/arrayMap":4,"../internal/baseDifference":6,"../internal/baseFlatten":7,"../internal/bindCallback":13,"../internal/pickByArray":28,"../internal/pickByCallback":29,"./keysIn":36}],38:[function(require,module,exports){
|
|
var createCompounder = require('../internal/createCompounder');
|
|
|
|
/**
|
|
* Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category String
|
|
* @param {string} [string=''] The string to convert.
|
|
* @returns {string} Returns the camel cased string.
|
|
* @example
|
|
*
|
|
* _.camelCase('Foo Bar');
|
|
* // => 'fooBar'
|
|
*
|
|
* _.camelCase('--foo-bar');
|
|
* // => 'fooBar'
|
|
*
|
|
* _.camelCase('__foo_bar__');
|
|
* // => 'fooBar'
|
|
*/
|
|
var camelCase = createCompounder(function(result, word, index) {
|
|
word = word.toLowerCase();
|
|
return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) : word);
|
|
});
|
|
|
|
module.exports = camelCase;
|
|
|
|
},{"../internal/createCompounder":18}],39:[function(require,module,exports){
|
|
var baseToString = require('../internal/baseToString'),
|
|
deburrLetter = require('../internal/deburrLetter');
|
|
|
|
/** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */
|
|
var reComboMark = /[\u0300-\u036f\ufe20-\ufe23]/g;
|
|
|
|
/** Used to match latin-1 supplementary letters (excluding mathematical operators). */
|
|
var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g;
|
|
|
|
/**
|
|
* Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
|
|
* to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category String
|
|
* @param {string} [string=''] The string to deburr.
|
|
* @returns {string} Returns the deburred string.
|
|
* @example
|
|
*
|
|
* _.deburr('déjà vu');
|
|
* // => 'deja vu'
|
|
*/
|
|
function deburr(string) {
|
|
string = baseToString(string);
|
|
return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, '');
|
|
}
|
|
|
|
module.exports = deburr;
|
|
|
|
},{"../internal/baseToString":12,"../internal/deburrLetter":19}],40:[function(require,module,exports){
|
|
var baseToString = require('../internal/baseToString'),
|
|
isIterateeCall = require('../internal/isIterateeCall');
|
|
|
|
/** Used to match words to create compound words. */
|
|
var reWords = (function() {
|
|
var upper = '[A-Z\\xc0-\\xd6\\xd8-\\xde]',
|
|
lower = '[a-z\\xdf-\\xf6\\xf8-\\xff]+';
|
|
|
|
return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g');
|
|
}());
|
|
|
|
/**
|
|
* Splits `string` into an array of its words.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category String
|
|
* @param {string} [string=''] The string to inspect.
|
|
* @param {RegExp|string} [pattern] The pattern to match words.
|
|
* @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
|
|
* @returns {Array} Returns the words of `string`.
|
|
* @example
|
|
*
|
|
* _.words('fred, barney, & pebbles');
|
|
* // => ['fred', 'barney', 'pebbles']
|
|
*
|
|
* _.words('fred, barney, & pebbles', /[^, ]+/g);
|
|
* // => ['fred', 'barney', '&', 'pebbles']
|
|
*/
|
|
function words(string, pattern, guard) {
|
|
if (guard && isIterateeCall(string, pattern, guard)) {
|
|
pattern = undefined;
|
|
}
|
|
string = baseToString(string);
|
|
return string.match(pattern || reWords) || [];
|
|
}
|
|
|
|
module.exports = words;
|
|
|
|
},{"../internal/baseToString":12,"../internal/isIterateeCall":25}],41:[function(require,module,exports){
|
|
/**
|
|
* This method returns the first argument provided to it.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Utility
|
|
* @param {*} value Any value.
|
|
* @returns {*} Returns `value`.
|
|
* @example
|
|
*
|
|
* var object = { 'user': 'fred' };
|
|
*
|
|
* _.identity(object) === object;
|
|
* // => true
|
|
*/
|
|
function identity(value) {
|
|
return value;
|
|
}
|
|
|
|
module.exports = identity;
|
|
|
|
},{}],42:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
exports.__esModule = true;
|
|
exports['default'] = createAll;
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _createProvider = require('./createProvider');
|
|
|
|
var _createProvider2 = _interopRequireDefault(_createProvider);
|
|
|
|
var _createConnect = require('./createConnect');
|
|
|
|
var _createConnect2 = _interopRequireDefault(_createConnect);
|
|
|
|
function createAll(React) {
|
|
var Provider = _createProvider2['default'](React);
|
|
var connect = _createConnect2['default'](React);
|
|
|
|
return { Provider: Provider, connect: connect };
|
|
}
|
|
|
|
module.exports = exports['default'];
|
|
},{"./createConnect":43,"./createProvider":44}],43:[function(require,module,exports){
|
|
(function (process){
|
|
'use strict';
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
|
|
|
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
|
|
|
exports['default'] = createConnect;
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var _utilsCreateStoreShape = require('../utils/createStoreShape');
|
|
|
|
var _utilsCreateStoreShape2 = _interopRequireDefault(_utilsCreateStoreShape);
|
|
|
|
var _utilsShallowEqual = require('../utils/shallowEqual');
|
|
|
|
var _utilsShallowEqual2 = _interopRequireDefault(_utilsShallowEqual);
|
|
|
|
var _utilsIsPlainObject = require('../utils/isPlainObject');
|
|
|
|
var _utilsIsPlainObject2 = _interopRequireDefault(_utilsIsPlainObject);
|
|
|
|
var _utilsWrapActionCreators = require('../utils/wrapActionCreators');
|
|
|
|
var _utilsWrapActionCreators2 = _interopRequireDefault(_utilsWrapActionCreators);
|
|
|
|
var _invariant = require('invariant');
|
|
|
|
var _invariant2 = _interopRequireDefault(_invariant);
|
|
|
|
var defaultMapStateToProps = function defaultMapStateToProps() {
|
|
return {};
|
|
};
|
|
var defaultMapDispatchToProps = function defaultMapDispatchToProps(dispatch) {
|
|
return { dispatch: dispatch };
|
|
};
|
|
var defaultMergeProps = function defaultMergeProps(stateProps, dispatchProps, parentProps) {
|
|
return _extends({}, parentProps, stateProps, dispatchProps);
|
|
};
|
|
|
|
function getDisplayName(Component) {
|
|
return Component.displayName || Component.name || 'Component';
|
|
}
|
|
|
|
// Helps track hot reloading.
|
|
var nextVersion = 0;
|
|
|
|
function createConnect(React) {
|
|
var Component = React.Component;
|
|
var PropTypes = React.PropTypes;
|
|
|
|
var storeShape = _utilsCreateStoreShape2['default'](PropTypes);
|
|
|
|
return function connect(mapStateToProps, mapDispatchToProps, mergeProps) {
|
|
var shouldSubscribe = Boolean(mapStateToProps);
|
|
var finalMapStateToProps = mapStateToProps || defaultMapStateToProps;
|
|
var finalMapDispatchToProps = _utilsIsPlainObject2['default'](mapDispatchToProps) ? _utilsWrapActionCreators2['default'](mapDispatchToProps) : mapDispatchToProps || defaultMapDispatchToProps;
|
|
var finalMergeProps = mergeProps || defaultMergeProps;
|
|
var shouldUpdateStateProps = finalMapStateToProps.length > 1;
|
|
var shouldUpdateDispatchProps = finalMapDispatchToProps.length > 1;
|
|
|
|
// Helps track hot reloading.
|
|
var version = nextVersion++;
|
|
|
|
function computeStateProps(store, props) {
|
|
var state = store.getState();
|
|
var stateProps = shouldUpdateStateProps ? finalMapStateToProps(state, props) : finalMapStateToProps(state);
|
|
|
|
_invariant2['default'](_utilsIsPlainObject2['default'](stateProps), '`mapStateToProps` must return an object. Instead received %s.', stateProps);
|
|
return stateProps;
|
|
}
|
|
|
|
function computeDispatchProps(store, props) {
|
|
var dispatch = store.dispatch;
|
|
|
|
var dispatchProps = shouldUpdateDispatchProps ? finalMapDispatchToProps(dispatch, props) : finalMapDispatchToProps(dispatch);
|
|
|
|
_invariant2['default'](_utilsIsPlainObject2['default'](dispatchProps), '`mapDispatchToProps` must return an object. Instead received %s.', dispatchProps);
|
|
return dispatchProps;
|
|
}
|
|
|
|
function _computeNextState(stateProps, dispatchProps, parentProps) {
|
|
var mergedProps = finalMergeProps(stateProps, dispatchProps, parentProps);
|
|
_invariant2['default'](_utilsIsPlainObject2['default'](mergedProps), '`mergeProps` must return an object. Instead received %s.', mergedProps);
|
|
return mergedProps;
|
|
}
|
|
|
|
return function wrapWithConnect(WrappedComponent) {
|
|
var Connect = (function (_Component) {
|
|
_inherits(Connect, _Component);
|
|
|
|
Connect.prototype.shouldComponentUpdate = function shouldComponentUpdate(nextProps, nextState) {
|
|
return !_utilsShallowEqual2['default'](this.state.props, nextState.props);
|
|
};
|
|
|
|
_createClass(Connect, null, [{
|
|
key: 'displayName',
|
|
value: 'Connect(' + getDisplayName(WrappedComponent) + ')',
|
|
enumerable: true
|
|
}, {
|
|
key: 'WrappedComponent',
|
|
value: WrappedComponent,
|
|
enumerable: true
|
|
}, {
|
|
key: 'contextTypes',
|
|
value: {
|
|
store: storeShape
|
|
},
|
|
enumerable: true
|
|
}, {
|
|
key: 'propTypes',
|
|
value: {
|
|
store: storeShape
|
|
},
|
|
enumerable: true
|
|
}]);
|
|
|
|
function Connect(props, context) {
|
|
_classCallCheck(this, Connect);
|
|
|
|
_Component.call(this, props, context);
|
|
this.version = version;
|
|
this.store = props.store || context.store;
|
|
|
|
_invariant2['default'](this.store, 'Could not find "store" in either the context or ' + ('props of "' + this.constructor.displayName + '". ') + 'Either wrap the root component in a <Provider>, ' + ('or explicitly pass "store" as a prop to "' + this.constructor.displayName + '".'));
|
|
|
|
this.stateProps = computeStateProps(this.store, props);
|
|
this.dispatchProps = computeDispatchProps(this.store, props);
|
|
this.state = {
|
|
props: this.computeNextState()
|
|
};
|
|
}
|
|
|
|
Connect.prototype.computeNextState = function computeNextState() {
|
|
var props = arguments.length <= 0 || arguments[0] === undefined ? this.props : arguments[0];
|
|
|
|
return _computeNextState(this.stateProps, this.dispatchProps, props);
|
|
};
|
|
|
|
Connect.prototype.updateStateProps = function updateStateProps() {
|
|
var props = arguments.length <= 0 || arguments[0] === undefined ? this.props : arguments[0];
|
|
|
|
var nextStateProps = computeStateProps(this.store, props);
|
|
if (_utilsShallowEqual2['default'](nextStateProps, this.stateProps)) {
|
|
return false;
|
|
}
|
|
|
|
this.stateProps = nextStateProps;
|
|
return true;
|
|
};
|
|
|
|
Connect.prototype.updateDispatchProps = function updateDispatchProps() {
|
|
var props = arguments.length <= 0 || arguments[0] === undefined ? this.props : arguments[0];
|
|
|
|
var nextDispatchProps = computeDispatchProps(this.store, props);
|
|
if (_utilsShallowEqual2['default'](nextDispatchProps, this.dispatchProps)) {
|
|
return false;
|
|
}
|
|
|
|
this.dispatchProps = nextDispatchProps;
|
|
return true;
|
|
};
|
|
|
|
Connect.prototype.updateState = function updateState() {
|
|
var props = arguments.length <= 0 || arguments[0] === undefined ? this.props : arguments[0];
|
|
|
|
var nextState = this.computeNextState(props);
|
|
if (!_utilsShallowEqual2['default'](nextState, this.state.props)) {
|
|
this.setState({
|
|
props: nextState
|
|
});
|
|
}
|
|
};
|
|
|
|
Connect.prototype.isSubscribed = function isSubscribed() {
|
|
return typeof this.unsubscribe === 'function';
|
|
};
|
|
|
|
Connect.prototype.trySubscribe = function trySubscribe() {
|
|
if (shouldSubscribe && !this.unsubscribe) {
|
|
this.unsubscribe = this.store.subscribe(this.handleChange.bind(this));
|
|
this.handleChange();
|
|
}
|
|
};
|
|
|
|
Connect.prototype.tryUnsubscribe = function tryUnsubscribe() {
|
|
if (this.unsubscribe) {
|
|
this.unsubscribe();
|
|
this.unsubscribe = null;
|
|
}
|
|
};
|
|
|
|
Connect.prototype.componentDidMount = function componentDidMount() {
|
|
this.trySubscribe();
|
|
};
|
|
|
|
Connect.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
|
|
if (!_utilsShallowEqual2['default'](nextProps, this.props)) {
|
|
if (shouldUpdateStateProps) {
|
|
this.updateStateProps(nextProps);
|
|
}
|
|
|
|
if (shouldUpdateDispatchProps) {
|
|
this.updateDispatchProps(nextProps);
|
|
}
|
|
|
|
this.updateState(nextProps);
|
|
}
|
|
};
|
|
|
|
Connect.prototype.componentWillUnmount = function componentWillUnmount() {
|
|
this.tryUnsubscribe();
|
|
};
|
|
|
|
Connect.prototype.handleChange = function handleChange() {
|
|
if (this.updateStateProps()) {
|
|
this.updateState();
|
|
}
|
|
};
|
|
|
|
Connect.prototype.getWrappedInstance = function getWrappedInstance() {
|
|
return this.refs.wrappedInstance;
|
|
};
|
|
|
|
Connect.prototype.render = function render() {
|
|
return React.createElement(WrappedComponent, _extends({ ref: 'wrappedInstance'
|
|
}, this.state.props));
|
|
};
|
|
|
|
return Connect;
|
|
})(Component);
|
|
|
|
if (
|
|
// Node-like CommonJS environments (Browserify, Webpack)
|
|
typeof process !== 'undefined' && typeof process.env !== 'undefined' && process.env.NODE_ENV !== 'production' ||
|
|
// React Native
|
|
typeof __DEV__ !== 'undefined' && __DEV__ //eslint-disable-line no-undef
|
|
) {
|
|
Connect.prototype.componentWillUpdate = function componentWillUpdate() {
|
|
if (this.version === version) {
|
|
return;
|
|
}
|
|
|
|
// We are hot reloading!
|
|
this.version = version;
|
|
|
|
// Update the state and bindings.
|
|
this.trySubscribe();
|
|
this.updateStateProps();
|
|
this.updateDispatchProps();
|
|
this.updateState();
|
|
};
|
|
}
|
|
|
|
return Connect;
|
|
};
|
|
};
|
|
}
|
|
|
|
module.exports = exports['default'];
|
|
}).call(this,require('_process'))
|
|
},{"../utils/createStoreShape":46,"../utils/isPlainObject":47,"../utils/shallowEqual":48,"../utils/wrapActionCreators":49,"_process":1,"invariant":50}],44:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
|
|
|
exports['default'] = createProvider;
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var _utilsCreateStoreShape = require('../utils/createStoreShape');
|
|
|
|
var _utilsCreateStoreShape2 = _interopRequireDefault(_utilsCreateStoreShape);
|
|
|
|
function isUsingOwnerContext(React) {
|
|
var version = React.version;
|
|
|
|
if (typeof version !== 'string') {
|
|
return true;
|
|
}
|
|
|
|
var sections = version.split('.');
|
|
var major = parseInt(sections[0], 10);
|
|
var minor = parseInt(sections[1], 10);
|
|
|
|
return major === 0 && minor === 13;
|
|
}
|
|
|
|
function createProvider(React) {
|
|
var Component = React.Component;
|
|
var PropTypes = React.PropTypes;
|
|
var Children = React.Children;
|
|
|
|
var storeShape = _utilsCreateStoreShape2['default'](PropTypes);
|
|
var requireFunctionChild = isUsingOwnerContext(React);
|
|
|
|
var didWarn = false;
|
|
function warnAboutFunction() {
|
|
if (didWarn || requireFunctionChild) {
|
|
return;
|
|
}
|
|
|
|
didWarn = true;
|
|
console.error( // eslint-disable-line no-console
|
|
'With React 0.14 and later versions, you no longer need to ' + 'wrap <Provider> child into a function.');
|
|
}
|
|
function warnAboutElement() {
|
|
if (didWarn || !requireFunctionChild) {
|
|
return;
|
|
}
|
|
|
|
didWarn = true;
|
|
console.error( // eslint-disable-line no-console
|
|
'With React 0.13, you need to ' + 'wrap <Provider> child into a function. ' + 'This restriction will be removed with React 0.14.');
|
|
}
|
|
|
|
return (function (_Component) {
|
|
_inherits(Provider, _Component);
|
|
|
|
Provider.prototype.getChildContext = function getChildContext() {
|
|
return { store: this.state.store };
|
|
};
|
|
|
|
_createClass(Provider, null, [{
|
|
key: 'childContextTypes',
|
|
value: {
|
|
store: storeShape.isRequired
|
|
},
|
|
enumerable: true
|
|
}, {
|
|
key: 'propTypes',
|
|
value: {
|
|
store: storeShape.isRequired,
|
|
children: (requireFunctionChild ? PropTypes.func : PropTypes.element).isRequired
|
|
},
|
|
enumerable: true
|
|
}]);
|
|
|
|
function Provider(props, context) {
|
|
_classCallCheck(this, Provider);
|
|
|
|
_Component.call(this, props, context);
|
|
this.state = { store: props.store };
|
|
}
|
|
|
|
Provider.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
|
|
var store = this.state.store;
|
|
var nextStore = nextProps.store;
|
|
|
|
if (store !== nextStore) {
|
|
var nextReducer = nextStore.getReducer();
|
|
store.replaceReducer(nextReducer);
|
|
}
|
|
};
|
|
|
|
Provider.prototype.render = function render() {
|
|
var children = this.props.children;
|
|
|
|
if (typeof children === 'function') {
|
|
warnAboutFunction();
|
|
children = children();
|
|
} else {
|
|
warnAboutElement();
|
|
}
|
|
|
|
return Children.only(children);
|
|
};
|
|
|
|
return Provider;
|
|
})(Component);
|
|
}
|
|
|
|
module.exports = exports['default'];
|
|
},{"../utils/createStoreShape":46}],45:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
exports.__esModule = true;
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _react = require('react');
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _componentsCreateAll = require('./components/createAll');
|
|
|
|
var _componentsCreateAll2 = _interopRequireDefault(_componentsCreateAll);
|
|
|
|
var _createAll = _componentsCreateAll2['default'](_react2['default']);
|
|
|
|
var Provider = _createAll.Provider;
|
|
var connect = _createAll.connect;
|
|
exports.Provider = Provider;
|
|
exports.connect = connect;
|
|
},{"./components/createAll":42,"react":205}],46:[function(require,module,exports){
|
|
"use strict";
|
|
|
|
exports.__esModule = true;
|
|
exports["default"] = createStoreShape;
|
|
|
|
function createStoreShape(PropTypes) {
|
|
return PropTypes.shape({
|
|
subscribe: PropTypes.func.isRequired,
|
|
dispatch: PropTypes.func.isRequired,
|
|
getState: PropTypes.func.isRequired
|
|
});
|
|
}
|
|
|
|
module.exports = exports["default"];
|
|
},{}],47:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
exports.__esModule = true;
|
|
exports['default'] = isPlainObject;
|
|
var fnToString = function fnToString(fn) {
|
|
return Function.prototype.toString.call(fn);
|
|
};
|
|
|
|
/**
|
|
* @param {any} obj The object to inspect.
|
|
* @returns {boolean} True if the argument appears to be a plain object.
|
|
*/
|
|
|
|
function isPlainObject(obj) {
|
|
if (!obj || typeof obj !== 'object') {
|
|
return false;
|
|
}
|
|
|
|
var proto = typeof obj.constructor === 'function' ? Object.getPrototypeOf(obj) : Object.prototype;
|
|
|
|
if (proto === null) {
|
|
return true;
|
|
}
|
|
|
|
var constructor = proto.constructor;
|
|
|
|
return typeof constructor === 'function' && constructor instanceof constructor && fnToString(constructor) === fnToString(Object);
|
|
}
|
|
|
|
module.exports = exports['default'];
|
|
},{}],48:[function(require,module,exports){
|
|
"use strict";
|
|
|
|
exports.__esModule = true;
|
|
exports["default"] = shallowEqual;
|
|
|
|
function shallowEqual(objA, objB) {
|
|
if (objA === objB) {
|
|
return true;
|
|
}
|
|
|
|
var keysA = Object.keys(objA);
|
|
var keysB = Object.keys(objB);
|
|
|
|
if (keysA.length !== keysB.length) {
|
|
return false;
|
|
}
|
|
|
|
// Test for A's keys different from B.
|
|
var hasOwn = Object.prototype.hasOwnProperty;
|
|
for (var i = 0; i < keysA.length; i++) {
|
|
if (!hasOwn.call(objB, keysA[i]) || objA[keysA[i]] !== objB[keysA[i]]) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
module.exports = exports["default"];
|
|
},{}],49:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
exports.__esModule = true;
|
|
exports['default'] = wrapActionCreators;
|
|
|
|
var _redux = require('redux');
|
|
|
|
function wrapActionCreators(actionCreators) {
|
|
return function (dispatch) {
|
|
return _redux.bindActionCreators(actionCreators, dispatch);
|
|
};
|
|
}
|
|
|
|
module.exports = exports['default'];
|
|
},{"redux":207}],50:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule invariant
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* Use invariant() to assert state which your program assumes to be true.
|
|
*
|
|
* Provide sprintf-style format (only %s is supported) and arguments
|
|
* to provide information about what broke and what you were
|
|
* expecting.
|
|
*
|
|
* The invariant message will be stripped in production, but the invariant
|
|
* will remain to ensure logic does not differ in production.
|
|
*/
|
|
|
|
var invariant = function(condition, format, a, b, c, d, e, f) {
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
if (format === undefined) {
|
|
throw new Error('invariant requires an error message argument');
|
|
}
|
|
}
|
|
|
|
if (!condition) {
|
|
var error;
|
|
if (format === undefined) {
|
|
error = new Error(
|
|
'Minified exception occurred; use the non-minified dev environment ' +
|
|
'for the full error message and additional helpful warnings.'
|
|
);
|
|
} else {
|
|
var args = [a, b, c, d, e, f];
|
|
var argIndex = 0;
|
|
error = new Error(
|
|
'Invariant Violation: ' +
|
|
format.replace(/%s/g, function() { return args[argIndex++]; })
|
|
);
|
|
}
|
|
|
|
error.framesToPop = 1; // we don't care about invariant's own frame
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
module.exports = invariant;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"_process":1}],51:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule AutoFocusMixin
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var focusNode = require("./focusNode");
|
|
|
|
var AutoFocusMixin = {
|
|
componentDidMount: function() {
|
|
if (this.props.autoFocus) {
|
|
focusNode(this.getDOMNode());
|
|
}
|
|
}
|
|
};
|
|
|
|
module.exports = AutoFocusMixin;
|
|
|
|
},{"./focusNode":169}],52:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015 Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule BeforeInputEventPlugin
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var EventConstants = require("./EventConstants");
|
|
var EventPropagators = require("./EventPropagators");
|
|
var ExecutionEnvironment = require("./ExecutionEnvironment");
|
|
var FallbackCompositionState = require("./FallbackCompositionState");
|
|
var SyntheticCompositionEvent = require("./SyntheticCompositionEvent");
|
|
var SyntheticInputEvent = require("./SyntheticInputEvent");
|
|
|
|
var keyOf = require("./keyOf");
|
|
|
|
var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
|
|
var START_KEYCODE = 229;
|
|
|
|
var canUseCompositionEvent = (
|
|
ExecutionEnvironment.canUseDOM &&
|
|
'CompositionEvent' in window
|
|
);
|
|
|
|
var documentMode = null;
|
|
if (ExecutionEnvironment.canUseDOM && 'documentMode' in document) {
|
|
documentMode = document.documentMode;
|
|
}
|
|
|
|
// Webkit offers a very useful `textInput` event that can be used to
|
|
// directly represent `beforeInput`. The IE `textinput` event is not as
|
|
// useful, so we don't use it.
|
|
var canUseTextInputEvent = (
|
|
ExecutionEnvironment.canUseDOM &&
|
|
'TextEvent' in window &&
|
|
!documentMode &&
|
|
!isPresto()
|
|
);
|
|
|
|
// In IE9+, we have access to composition events, but the data supplied
|
|
// by the native compositionend event may be incorrect. Japanese ideographic
|
|
// spaces, for instance (\u3000) are not recorded correctly.
|
|
var useFallbackCompositionData = (
|
|
ExecutionEnvironment.canUseDOM &&
|
|
(
|
|
(!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11)
|
|
)
|
|
);
|
|
|
|
/**
|
|
* Opera <= 12 includes TextEvent in window, but does not fire
|
|
* text input events. Rely on keypress instead.
|
|
*/
|
|
function isPresto() {
|
|
var opera = window.opera;
|
|
return (
|
|
typeof opera === 'object' &&
|
|
typeof opera.version === 'function' &&
|
|
parseInt(opera.version(), 10) <= 12
|
|
);
|
|
}
|
|
|
|
var SPACEBAR_CODE = 32;
|
|
var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);
|
|
|
|
var topLevelTypes = EventConstants.topLevelTypes;
|
|
|
|
// Events and their corresponding property names.
|
|
var eventTypes = {
|
|
beforeInput: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onBeforeInput: null}),
|
|
captured: keyOf({onBeforeInputCapture: null})
|
|
},
|
|
dependencies: [
|
|
topLevelTypes.topCompositionEnd,
|
|
topLevelTypes.topKeyPress,
|
|
topLevelTypes.topTextInput,
|
|
topLevelTypes.topPaste
|
|
]
|
|
},
|
|
compositionEnd: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onCompositionEnd: null}),
|
|
captured: keyOf({onCompositionEndCapture: null})
|
|
},
|
|
dependencies: [
|
|
topLevelTypes.topBlur,
|
|
topLevelTypes.topCompositionEnd,
|
|
topLevelTypes.topKeyDown,
|
|
topLevelTypes.topKeyPress,
|
|
topLevelTypes.topKeyUp,
|
|
topLevelTypes.topMouseDown
|
|
]
|
|
},
|
|
compositionStart: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onCompositionStart: null}),
|
|
captured: keyOf({onCompositionStartCapture: null})
|
|
},
|
|
dependencies: [
|
|
topLevelTypes.topBlur,
|
|
topLevelTypes.topCompositionStart,
|
|
topLevelTypes.topKeyDown,
|
|
topLevelTypes.topKeyPress,
|
|
topLevelTypes.topKeyUp,
|
|
topLevelTypes.topMouseDown
|
|
]
|
|
},
|
|
compositionUpdate: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onCompositionUpdate: null}),
|
|
captured: keyOf({onCompositionUpdateCapture: null})
|
|
},
|
|
dependencies: [
|
|
topLevelTypes.topBlur,
|
|
topLevelTypes.topCompositionUpdate,
|
|
topLevelTypes.topKeyDown,
|
|
topLevelTypes.topKeyPress,
|
|
topLevelTypes.topKeyUp,
|
|
topLevelTypes.topMouseDown
|
|
]
|
|
}
|
|
};
|
|
|
|
// Track whether we've ever handled a keypress on the space key.
|
|
var hasSpaceKeypress = false;
|
|
|
|
/**
|
|
* Return whether a native keypress event is assumed to be a command.
|
|
* This is required because Firefox fires `keypress` events for key commands
|
|
* (cut, copy, select-all, etc.) even though no character is inserted.
|
|
*/
|
|
function isKeypressCommand(nativeEvent) {
|
|
return (
|
|
(nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) &&
|
|
// ctrlKey && altKey is equivalent to AltGr, and is not a command.
|
|
!(nativeEvent.ctrlKey && nativeEvent.altKey)
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
* Translate native top level events into event types.
|
|
*
|
|
* @param {string} topLevelType
|
|
* @return {object}
|
|
*/
|
|
function getCompositionEventType(topLevelType) {
|
|
switch (topLevelType) {
|
|
case topLevelTypes.topCompositionStart:
|
|
return eventTypes.compositionStart;
|
|
case topLevelTypes.topCompositionEnd:
|
|
return eventTypes.compositionEnd;
|
|
case topLevelTypes.topCompositionUpdate:
|
|
return eventTypes.compositionUpdate;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Does our fallback best-guess model think this event signifies that
|
|
* composition has begun?
|
|
*
|
|
* @param {string} topLevelType
|
|
* @param {object} nativeEvent
|
|
* @return {boolean}
|
|
*/
|
|
function isFallbackCompositionStart(topLevelType, nativeEvent) {
|
|
return (
|
|
topLevelType === topLevelTypes.topKeyDown &&
|
|
nativeEvent.keyCode === START_KEYCODE
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Does our fallback mode think that this event is the end of composition?
|
|
*
|
|
* @param {string} topLevelType
|
|
* @param {object} nativeEvent
|
|
* @return {boolean}
|
|
*/
|
|
function isFallbackCompositionEnd(topLevelType, nativeEvent) {
|
|
switch (topLevelType) {
|
|
case topLevelTypes.topKeyUp:
|
|
// Command keys insert or clear IME input.
|
|
return (END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1);
|
|
case topLevelTypes.topKeyDown:
|
|
// Expect IME keyCode on each keydown. If we get any other
|
|
// code we must have exited earlier.
|
|
return (nativeEvent.keyCode !== START_KEYCODE);
|
|
case topLevelTypes.topKeyPress:
|
|
case topLevelTypes.topMouseDown:
|
|
case topLevelTypes.topBlur:
|
|
// Events are not possible without cancelling IME.
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Google Input Tools provides composition data via a CustomEvent,
|
|
* with the `data` property populated in the `detail` object. If this
|
|
* is available on the event object, use it. If not, this is a plain
|
|
* composition event and we have nothing special to extract.
|
|
*
|
|
* @param {object} nativeEvent
|
|
* @return {?string}
|
|
*/
|
|
function getDataFromCustomEvent(nativeEvent) {
|
|
var detail = nativeEvent.detail;
|
|
if (typeof detail === 'object' && 'data' in detail) {
|
|
return detail.data;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Track the current IME composition fallback object, if any.
|
|
var currentComposition = null;
|
|
|
|
/**
|
|
* @param {string} topLevelType Record from `EventConstants`.
|
|
* @param {DOMEventTarget} topLevelTarget The listening component root node.
|
|
* @param {string} topLevelTargetID ID of `topLevelTarget`.
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @return {?object} A SyntheticCompositionEvent.
|
|
*/
|
|
function extractCompositionEvent(
|
|
topLevelType,
|
|
topLevelTarget,
|
|
topLevelTargetID,
|
|
nativeEvent
|
|
) {
|
|
var eventType;
|
|
var fallbackData;
|
|
|
|
if (canUseCompositionEvent) {
|
|
eventType = getCompositionEventType(topLevelType);
|
|
} else if (!currentComposition) {
|
|
if (isFallbackCompositionStart(topLevelType, nativeEvent)) {
|
|
eventType = eventTypes.compositionStart;
|
|
}
|
|
} else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {
|
|
eventType = eventTypes.compositionEnd;
|
|
}
|
|
|
|
if (!eventType) {
|
|
return null;
|
|
}
|
|
|
|
if (useFallbackCompositionData) {
|
|
// The current composition is stored statically and must not be
|
|
// overwritten while composition continues.
|
|
if (!currentComposition && eventType === eventTypes.compositionStart) {
|
|
currentComposition = FallbackCompositionState.getPooled(topLevelTarget);
|
|
} else if (eventType === eventTypes.compositionEnd) {
|
|
if (currentComposition) {
|
|
fallbackData = currentComposition.getData();
|
|
}
|
|
}
|
|
}
|
|
|
|
var event = SyntheticCompositionEvent.getPooled(
|
|
eventType,
|
|
topLevelTargetID,
|
|
nativeEvent
|
|
);
|
|
|
|
if (fallbackData) {
|
|
// Inject data generated from fallback path into the synthetic event.
|
|
// This matches the property of native CompositionEventInterface.
|
|
event.data = fallbackData;
|
|
} else {
|
|
var customData = getDataFromCustomEvent(nativeEvent);
|
|
if (customData !== null) {
|
|
event.data = customData;
|
|
}
|
|
}
|
|
|
|
EventPropagators.accumulateTwoPhaseDispatches(event);
|
|
return event;
|
|
}
|
|
|
|
/**
|
|
* @param {string} topLevelType Record from `EventConstants`.
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @return {?string} The string corresponding to this `beforeInput` event.
|
|
*/
|
|
function getNativeBeforeInputChars(topLevelType, nativeEvent) {
|
|
switch (topLevelType) {
|
|
case topLevelTypes.topCompositionEnd:
|
|
return getDataFromCustomEvent(nativeEvent);
|
|
case topLevelTypes.topKeyPress:
|
|
/**
|
|
* If native `textInput` events are available, our goal is to make
|
|
* use of them. However, there is a special case: the spacebar key.
|
|
* In Webkit, preventing default on a spacebar `textInput` event
|
|
* cancels character insertion, but it *also* causes the browser
|
|
* to fall back to its default spacebar behavior of scrolling the
|
|
* page.
|
|
*
|
|
* Tracking at:
|
|
* https://code.google.com/p/chromium/issues/detail?id=355103
|
|
*
|
|
* To avoid this issue, use the keypress event as if no `textInput`
|
|
* event is available.
|
|
*/
|
|
var which = nativeEvent.which;
|
|
if (which !== SPACEBAR_CODE) {
|
|
return null;
|
|
}
|
|
|
|
hasSpaceKeypress = true;
|
|
return SPACEBAR_CHAR;
|
|
|
|
case topLevelTypes.topTextInput:
|
|
// Record the characters to be added to the DOM.
|
|
var chars = nativeEvent.data;
|
|
|
|
// If it's a spacebar character, assume that we have already handled
|
|
// it at the keypress level and bail immediately. Android Chrome
|
|
// doesn't give us keycodes, so we need to blacklist it.
|
|
if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
|
|
return null;
|
|
}
|
|
|
|
return chars;
|
|
|
|
default:
|
|
// For other native event types, do nothing.
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* For browsers that do not provide the `textInput` event, extract the
|
|
* appropriate string to use for SyntheticInputEvent.
|
|
*
|
|
* @param {string} topLevelType Record from `EventConstants`.
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @return {?string} The fallback string for this `beforeInput` event.
|
|
*/
|
|
function getFallbackBeforeInputChars(topLevelType, nativeEvent) {
|
|
// If we are currently composing (IME) and using a fallback to do so,
|
|
// try to extract the composed characters from the fallback object.
|
|
if (currentComposition) {
|
|
if (
|
|
topLevelType === topLevelTypes.topCompositionEnd ||
|
|
isFallbackCompositionEnd(topLevelType, nativeEvent)
|
|
) {
|
|
var chars = currentComposition.getData();
|
|
FallbackCompositionState.release(currentComposition);
|
|
currentComposition = null;
|
|
return chars;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
switch (topLevelType) {
|
|
case topLevelTypes.topPaste:
|
|
// If a paste event occurs after a keypress, throw out the input
|
|
// chars. Paste events should not lead to BeforeInput events.
|
|
return null;
|
|
case topLevelTypes.topKeyPress:
|
|
/**
|
|
* As of v27, Firefox may fire keypress events even when no character
|
|
* will be inserted. A few possibilities:
|
|
*
|
|
* - `which` is `0`. Arrow keys, Esc key, etc.
|
|
*
|
|
* - `which` is the pressed key code, but no char is available.
|
|
* Ex: 'AltGr + d` in Polish. There is no modified character for
|
|
* this key combination and no character is inserted into the
|
|
* document, but FF fires the keypress for char code `100` anyway.
|
|
* No `input` event will occur.
|
|
*
|
|
* - `which` is the pressed key code, but a command combination is
|
|
* being used. Ex: `Cmd+C`. No character is inserted, and no
|
|
* `input` event will occur.
|
|
*/
|
|
if (nativeEvent.which && !isKeypressCommand(nativeEvent)) {
|
|
return String.fromCharCode(nativeEvent.which);
|
|
}
|
|
return null;
|
|
case topLevelTypes.topCompositionEnd:
|
|
return useFallbackCompositionData ? null : nativeEvent.data;
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Extract a SyntheticInputEvent for `beforeInput`, based on either native
|
|
* `textInput` or fallback behavior.
|
|
*
|
|
* @param {string} topLevelType Record from `EventConstants`.
|
|
* @param {DOMEventTarget} topLevelTarget The listening component root node.
|
|
* @param {string} topLevelTargetID ID of `topLevelTarget`.
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @return {?object} A SyntheticInputEvent.
|
|
*/
|
|
function extractBeforeInputEvent(
|
|
topLevelType,
|
|
topLevelTarget,
|
|
topLevelTargetID,
|
|
nativeEvent
|
|
) {
|
|
var chars;
|
|
|
|
if (canUseTextInputEvent) {
|
|
chars = getNativeBeforeInputChars(topLevelType, nativeEvent);
|
|
} else {
|
|
chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);
|
|
}
|
|
|
|
// If no characters are being inserted, no BeforeInput event should
|
|
// be fired.
|
|
if (!chars) {
|
|
return null;
|
|
}
|
|
|
|
var event = SyntheticInputEvent.getPooled(
|
|
eventTypes.beforeInput,
|
|
topLevelTargetID,
|
|
nativeEvent
|
|
);
|
|
|
|
event.data = chars;
|
|
EventPropagators.accumulateTwoPhaseDispatches(event);
|
|
return event;
|
|
}
|
|
|
|
/**
|
|
* Create an `onBeforeInput` event to match
|
|
* http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
|
|
*
|
|
* This event plugin is based on the native `textInput` event
|
|
* available in Chrome, Safari, Opera, and IE. This event fires after
|
|
* `onKeyPress` and `onCompositionEnd`, but before `onInput`.
|
|
*
|
|
* `beforeInput` is spec'd but not implemented in any browsers, and
|
|
* the `input` event does not provide any useful information about what has
|
|
* actually been added, contrary to the spec. Thus, `textInput` is the best
|
|
* available event to identify the characters that have actually been inserted
|
|
* into the target node.
|
|
*
|
|
* This plugin is also responsible for emitting `composition` events, thus
|
|
* allowing us to share composition fallback code for both `beforeInput` and
|
|
* `composition` event types.
|
|
*/
|
|
var BeforeInputEventPlugin = {
|
|
|
|
eventTypes: eventTypes,
|
|
|
|
/**
|
|
* @param {string} topLevelType Record from `EventConstants`.
|
|
* @param {DOMEventTarget} topLevelTarget The listening component root node.
|
|
* @param {string} topLevelTargetID ID of `topLevelTarget`.
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @return {*} An accumulation of synthetic events.
|
|
* @see {EventPluginHub.extractEvents}
|
|
*/
|
|
extractEvents: function(
|
|
topLevelType,
|
|
topLevelTarget,
|
|
topLevelTargetID,
|
|
nativeEvent
|
|
) {
|
|
return [
|
|
extractCompositionEvent(
|
|
topLevelType,
|
|
topLevelTarget,
|
|
topLevelTargetID,
|
|
nativeEvent
|
|
),
|
|
extractBeforeInputEvent(
|
|
topLevelType,
|
|
topLevelTarget,
|
|
topLevelTargetID,
|
|
nativeEvent
|
|
)
|
|
];
|
|
}
|
|
};
|
|
|
|
module.exports = BeforeInputEventPlugin;
|
|
|
|
},{"./EventConstants":64,"./EventPropagators":69,"./ExecutionEnvironment":70,"./FallbackCompositionState":71,"./SyntheticCompositionEvent":143,"./SyntheticInputEvent":147,"./keyOf":191}],53:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule CSSProperty
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* CSS properties which accept numbers but are not in units of "px".
|
|
*/
|
|
var isUnitlessNumber = {
|
|
boxFlex: true,
|
|
boxFlexGroup: true,
|
|
columnCount: true,
|
|
flex: true,
|
|
flexGrow: true,
|
|
flexPositive: true,
|
|
flexShrink: true,
|
|
flexNegative: true,
|
|
fontWeight: true,
|
|
lineClamp: true,
|
|
lineHeight: true,
|
|
opacity: true,
|
|
order: true,
|
|
orphans: true,
|
|
widows: true,
|
|
zIndex: true,
|
|
zoom: true,
|
|
|
|
// SVG-related properties
|
|
fillOpacity: true,
|
|
strokeDashoffset: true,
|
|
strokeOpacity: true,
|
|
strokeWidth: true
|
|
};
|
|
|
|
/**
|
|
* @param {string} prefix vendor-specific prefix, eg: Webkit
|
|
* @param {string} key style name, eg: transitionDuration
|
|
* @return {string} style name prefixed with `prefix`, properly camelCased, eg:
|
|
* WebkitTransitionDuration
|
|
*/
|
|
function prefixKey(prefix, key) {
|
|
return prefix + key.charAt(0).toUpperCase() + key.substring(1);
|
|
}
|
|
|
|
/**
|
|
* Support style names that may come passed in prefixed by adding permutations
|
|
* of vendor prefixes.
|
|
*/
|
|
var prefixes = ['Webkit', 'ms', 'Moz', 'O'];
|
|
|
|
// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
|
|
// infinite loop, because it iterates over the newly added props too.
|
|
Object.keys(isUnitlessNumber).forEach(function(prop) {
|
|
prefixes.forEach(function(prefix) {
|
|
isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Most style properties can be unset by doing .style[prop] = '' but IE8
|
|
* doesn't like doing that with shorthand properties so for the properties that
|
|
* IE8 breaks on, which are listed here, we instead unset each of the
|
|
* individual properties. See http://bugs.jquery.com/ticket/12385.
|
|
* The 4-value 'clock' properties like margin, padding, border-width seem to
|
|
* behave without any problems. Curiously, list-style works too without any
|
|
* special prodding.
|
|
*/
|
|
var shorthandPropertyExpansions = {
|
|
background: {
|
|
backgroundImage: true,
|
|
backgroundPosition: true,
|
|
backgroundRepeat: true,
|
|
backgroundColor: true
|
|
},
|
|
border: {
|
|
borderWidth: true,
|
|
borderStyle: true,
|
|
borderColor: true
|
|
},
|
|
borderBottom: {
|
|
borderBottomWidth: true,
|
|
borderBottomStyle: true,
|
|
borderBottomColor: true
|
|
},
|
|
borderLeft: {
|
|
borderLeftWidth: true,
|
|
borderLeftStyle: true,
|
|
borderLeftColor: true
|
|
},
|
|
borderRight: {
|
|
borderRightWidth: true,
|
|
borderRightStyle: true,
|
|
borderRightColor: true
|
|
},
|
|
borderTop: {
|
|
borderTopWidth: true,
|
|
borderTopStyle: true,
|
|
borderTopColor: true
|
|
},
|
|
font: {
|
|
fontStyle: true,
|
|
fontVariant: true,
|
|
fontWeight: true,
|
|
fontSize: true,
|
|
lineHeight: true,
|
|
fontFamily: true
|
|
}
|
|
};
|
|
|
|
var CSSProperty = {
|
|
isUnitlessNumber: isUnitlessNumber,
|
|
shorthandPropertyExpansions: shorthandPropertyExpansions
|
|
};
|
|
|
|
module.exports = CSSProperty;
|
|
|
|
},{}],54:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule CSSPropertyOperations
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var CSSProperty = require("./CSSProperty");
|
|
var ExecutionEnvironment = require("./ExecutionEnvironment");
|
|
|
|
var camelizeStyleName = require("./camelizeStyleName");
|
|
var dangerousStyleValue = require("./dangerousStyleValue");
|
|
var hyphenateStyleName = require("./hyphenateStyleName");
|
|
var memoizeStringOnly = require("./memoizeStringOnly");
|
|
var warning = require("./warning");
|
|
|
|
var processStyleName = memoizeStringOnly(function(styleName) {
|
|
return hyphenateStyleName(styleName);
|
|
});
|
|
|
|
var styleFloatAccessor = 'cssFloat';
|
|
if (ExecutionEnvironment.canUseDOM) {
|
|
// IE8 only supports accessing cssFloat (standard) as styleFloat
|
|
if (document.documentElement.style.cssFloat === undefined) {
|
|
styleFloatAccessor = 'styleFloat';
|
|
}
|
|
}
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
// 'msTransform' is correct, but the other prefixes should be capitalized
|
|
var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
|
|
|
|
// style values shouldn't contain a semicolon
|
|
var badStyleValueWithSemicolonPattern = /;\s*$/;
|
|
|
|
var warnedStyleNames = {};
|
|
var warnedStyleValues = {};
|
|
|
|
var warnHyphenatedStyleName = function(name) {
|
|
if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
|
|
return;
|
|
}
|
|
|
|
warnedStyleNames[name] = true;
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
false,
|
|
'Unsupported style property %s. Did you mean %s?',
|
|
name,
|
|
camelizeStyleName(name)
|
|
) : null);
|
|
};
|
|
|
|
var warnBadVendoredStyleName = function(name) {
|
|
if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
|
|
return;
|
|
}
|
|
|
|
warnedStyleNames[name] = true;
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
false,
|
|
'Unsupported vendor-prefixed style property %s. Did you mean %s?',
|
|
name,
|
|
name.charAt(0).toUpperCase() + name.slice(1)
|
|
) : null);
|
|
};
|
|
|
|
var warnStyleValueWithSemicolon = function(name, value) {
|
|
if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
|
|
return;
|
|
}
|
|
|
|
warnedStyleValues[value] = true;
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
false,
|
|
'Style property values shouldn\'t contain a semicolon. ' +
|
|
'Try "%s: %s" instead.',
|
|
name,
|
|
value.replace(badStyleValueWithSemicolonPattern, '')
|
|
) : null);
|
|
};
|
|
|
|
/**
|
|
* @param {string} name
|
|
* @param {*} value
|
|
*/
|
|
var warnValidStyle = function(name, value) {
|
|
if (name.indexOf('-') > -1) {
|
|
warnHyphenatedStyleName(name);
|
|
} else if (badVendoredStyleNamePattern.test(name)) {
|
|
warnBadVendoredStyleName(name);
|
|
} else if (badStyleValueWithSemicolonPattern.test(value)) {
|
|
warnStyleValueWithSemicolon(name, value);
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Operations for dealing with CSS properties.
|
|
*/
|
|
var CSSPropertyOperations = {
|
|
|
|
/**
|
|
* Serializes a mapping of style properties for use as inline styles:
|
|
*
|
|
* > createMarkupForStyles({width: '200px', height: 0})
|
|
* "width:200px;height:0;"
|
|
*
|
|
* Undefined values are ignored so that declarative programming is easier.
|
|
* The result should be HTML-escaped before insertion into the DOM.
|
|
*
|
|
* @param {object} styles
|
|
* @return {?string}
|
|
*/
|
|
createMarkupForStyles: function(styles) {
|
|
var serialized = '';
|
|
for (var styleName in styles) {
|
|
if (!styles.hasOwnProperty(styleName)) {
|
|
continue;
|
|
}
|
|
var styleValue = styles[styleName];
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
warnValidStyle(styleName, styleValue);
|
|
}
|
|
if (styleValue != null) {
|
|
serialized += processStyleName(styleName) + ':';
|
|
serialized += dangerousStyleValue(styleName, styleValue) + ';';
|
|
}
|
|
}
|
|
return serialized || null;
|
|
},
|
|
|
|
/**
|
|
* Sets the value for multiple styles on a node. If a value is specified as
|
|
* '' (empty string), the corresponding style property will be unset.
|
|
*
|
|
* @param {DOMElement} node
|
|
* @param {object} styles
|
|
*/
|
|
setValueForStyles: function(node, styles) {
|
|
var style = node.style;
|
|
for (var styleName in styles) {
|
|
if (!styles.hasOwnProperty(styleName)) {
|
|
continue;
|
|
}
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
warnValidStyle(styleName, styles[styleName]);
|
|
}
|
|
var styleValue = dangerousStyleValue(styleName, styles[styleName]);
|
|
if (styleName === 'float') {
|
|
styleName = styleFloatAccessor;
|
|
}
|
|
if (styleValue) {
|
|
style[styleName] = styleValue;
|
|
} else {
|
|
var expansion = CSSProperty.shorthandPropertyExpansions[styleName];
|
|
if (expansion) {
|
|
// Shorthand property that IE8 won't like unsetting, so unset each
|
|
// component to placate it
|
|
for (var individualStyleName in expansion) {
|
|
style[individualStyleName] = '';
|
|
}
|
|
} else {
|
|
style[styleName] = '';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = CSSPropertyOperations;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./CSSProperty":53,"./ExecutionEnvironment":70,"./camelizeStyleName":158,"./dangerousStyleValue":163,"./hyphenateStyleName":183,"./memoizeStringOnly":193,"./warning":204,"_process":1}],55:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule CallbackQueue
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var PooledClass = require("./PooledClass");
|
|
|
|
var assign = require("./Object.assign");
|
|
var invariant = require("./invariant");
|
|
|
|
/**
|
|
* A specialized pseudo-event module to help keep track of components waiting to
|
|
* be notified when their DOM representations are available for use.
|
|
*
|
|
* This implements `PooledClass`, so you should never need to instantiate this.
|
|
* Instead, use `CallbackQueue.getPooled()`.
|
|
*
|
|
* @class ReactMountReady
|
|
* @implements PooledClass
|
|
* @internal
|
|
*/
|
|
function CallbackQueue() {
|
|
this._callbacks = null;
|
|
this._contexts = null;
|
|
}
|
|
|
|
assign(CallbackQueue.prototype, {
|
|
|
|
/**
|
|
* Enqueues a callback to be invoked when `notifyAll` is invoked.
|
|
*
|
|
* @param {function} callback Invoked when `notifyAll` is invoked.
|
|
* @param {?object} context Context to call `callback` with.
|
|
* @internal
|
|
*/
|
|
enqueue: function(callback, context) {
|
|
this._callbacks = this._callbacks || [];
|
|
this._contexts = this._contexts || [];
|
|
this._callbacks.push(callback);
|
|
this._contexts.push(context);
|
|
},
|
|
|
|
/**
|
|
* Invokes all enqueued callbacks and clears the queue. This is invoked after
|
|
* the DOM representation of a component has been created or updated.
|
|
*
|
|
* @internal
|
|
*/
|
|
notifyAll: function() {
|
|
var callbacks = this._callbacks;
|
|
var contexts = this._contexts;
|
|
if (callbacks) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
callbacks.length === contexts.length,
|
|
'Mismatched list of contexts in callback queue'
|
|
) : invariant(callbacks.length === contexts.length));
|
|
this._callbacks = null;
|
|
this._contexts = null;
|
|
for (var i = 0, l = callbacks.length; i < l; i++) {
|
|
callbacks[i].call(contexts[i]);
|
|
}
|
|
callbacks.length = 0;
|
|
contexts.length = 0;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Resets the internal queue.
|
|
*
|
|
* @internal
|
|
*/
|
|
reset: function() {
|
|
this._callbacks = null;
|
|
this._contexts = null;
|
|
},
|
|
|
|
/**
|
|
* `PooledClass` looks for this.
|
|
*/
|
|
destructor: function() {
|
|
this.reset();
|
|
}
|
|
|
|
});
|
|
|
|
PooledClass.addPoolingTo(CallbackQueue);
|
|
|
|
module.exports = CallbackQueue;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./Object.assign":76,"./PooledClass":77,"./invariant":185,"_process":1}],56:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ChangeEventPlugin
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var EventConstants = require("./EventConstants");
|
|
var EventPluginHub = require("./EventPluginHub");
|
|
var EventPropagators = require("./EventPropagators");
|
|
var ExecutionEnvironment = require("./ExecutionEnvironment");
|
|
var ReactUpdates = require("./ReactUpdates");
|
|
var SyntheticEvent = require("./SyntheticEvent");
|
|
|
|
var isEventSupported = require("./isEventSupported");
|
|
var isTextInputElement = require("./isTextInputElement");
|
|
var keyOf = require("./keyOf");
|
|
|
|
var topLevelTypes = EventConstants.topLevelTypes;
|
|
|
|
var eventTypes = {
|
|
change: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onChange: null}),
|
|
captured: keyOf({onChangeCapture: null})
|
|
},
|
|
dependencies: [
|
|
topLevelTypes.topBlur,
|
|
topLevelTypes.topChange,
|
|
topLevelTypes.topClick,
|
|
topLevelTypes.topFocus,
|
|
topLevelTypes.topInput,
|
|
topLevelTypes.topKeyDown,
|
|
topLevelTypes.topKeyUp,
|
|
topLevelTypes.topSelectionChange
|
|
]
|
|
}
|
|
};
|
|
|
|
/**
|
|
* For IE shims
|
|
*/
|
|
var activeElement = null;
|
|
var activeElementID = null;
|
|
var activeElementValue = null;
|
|
var activeElementValueProp = null;
|
|
|
|
/**
|
|
* SECTION: handle `change` event
|
|
*/
|
|
function shouldUseChangeEvent(elem) {
|
|
return (
|
|
elem.nodeName === 'SELECT' ||
|
|
(elem.nodeName === 'INPUT' && elem.type === 'file')
|
|
);
|
|
}
|
|
|
|
var doesChangeEventBubble = false;
|
|
if (ExecutionEnvironment.canUseDOM) {
|
|
// See `handleChange` comment below
|
|
doesChangeEventBubble = isEventSupported('change') && (
|
|
(!('documentMode' in document) || document.documentMode > 8)
|
|
);
|
|
}
|
|
|
|
function manualDispatchChangeEvent(nativeEvent) {
|
|
var event = SyntheticEvent.getPooled(
|
|
eventTypes.change,
|
|
activeElementID,
|
|
nativeEvent
|
|
);
|
|
EventPropagators.accumulateTwoPhaseDispatches(event);
|
|
|
|
// If change and propertychange bubbled, we'd just bind to it like all the
|
|
// other events and have it go through ReactBrowserEventEmitter. Since it
|
|
// doesn't, we manually listen for the events and so we have to enqueue and
|
|
// process the abstract event manually.
|
|
//
|
|
// Batching is necessary here in order to ensure that all event handlers run
|
|
// before the next rerender (including event handlers attached to ancestor
|
|
// elements instead of directly on the input). Without this, controlled
|
|
// components don't work properly in conjunction with event bubbling because
|
|
// the component is rerendered and the value reverted before all the event
|
|
// handlers can run. See https://github.com/facebook/react/issues/708.
|
|
ReactUpdates.batchedUpdates(runEventInBatch, event);
|
|
}
|
|
|
|
function runEventInBatch(event) {
|
|
EventPluginHub.enqueueEvents(event);
|
|
EventPluginHub.processEventQueue();
|
|
}
|
|
|
|
function startWatchingForChangeEventIE8(target, targetID) {
|
|
activeElement = target;
|
|
activeElementID = targetID;
|
|
activeElement.attachEvent('onchange', manualDispatchChangeEvent);
|
|
}
|
|
|
|
function stopWatchingForChangeEventIE8() {
|
|
if (!activeElement) {
|
|
return;
|
|
}
|
|
activeElement.detachEvent('onchange', manualDispatchChangeEvent);
|
|
activeElement = null;
|
|
activeElementID = null;
|
|
}
|
|
|
|
function getTargetIDForChangeEvent(
|
|
topLevelType,
|
|
topLevelTarget,
|
|
topLevelTargetID) {
|
|
if (topLevelType === topLevelTypes.topChange) {
|
|
return topLevelTargetID;
|
|
}
|
|
}
|
|
function handleEventsForChangeEventIE8(
|
|
topLevelType,
|
|
topLevelTarget,
|
|
topLevelTargetID) {
|
|
if (topLevelType === topLevelTypes.topFocus) {
|
|
// stopWatching() should be a noop here but we call it just in case we
|
|
// missed a blur event somehow.
|
|
stopWatchingForChangeEventIE8();
|
|
startWatchingForChangeEventIE8(topLevelTarget, topLevelTargetID);
|
|
} else if (topLevelType === topLevelTypes.topBlur) {
|
|
stopWatchingForChangeEventIE8();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* SECTION: handle `input` event
|
|
*/
|
|
var isInputEventSupported = false;
|
|
if (ExecutionEnvironment.canUseDOM) {
|
|
// IE9 claims to support the input event but fails to trigger it when
|
|
// deleting text, so we ignore its input events
|
|
isInputEventSupported = isEventSupported('input') && (
|
|
(!('documentMode' in document) || document.documentMode > 9)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* (For old IE.) Replacement getter/setter for the `value` property that gets
|
|
* set on the active element.
|
|
*/
|
|
var newValueProp = {
|
|
get: function() {
|
|
return activeElementValueProp.get.call(this);
|
|
},
|
|
set: function(val) {
|
|
// Cast to a string so we can do equality checks.
|
|
activeElementValue = '' + val;
|
|
activeElementValueProp.set.call(this, val);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* (For old IE.) Starts tracking propertychange events on the passed-in element
|
|
* and override the value property so that we can distinguish user events from
|
|
* value changes in JS.
|
|
*/
|
|
function startWatchingForValueChange(target, targetID) {
|
|
activeElement = target;
|
|
activeElementID = targetID;
|
|
activeElementValue = target.value;
|
|
activeElementValueProp = Object.getOwnPropertyDescriptor(
|
|
target.constructor.prototype,
|
|
'value'
|
|
);
|
|
|
|
Object.defineProperty(activeElement, 'value', newValueProp);
|
|
activeElement.attachEvent('onpropertychange', handlePropertyChange);
|
|
}
|
|
|
|
/**
|
|
* (For old IE.) Removes the event listeners from the currently-tracked element,
|
|
* if any exists.
|
|
*/
|
|
function stopWatchingForValueChange() {
|
|
if (!activeElement) {
|
|
return;
|
|
}
|
|
|
|
// delete restores the original property definition
|
|
delete activeElement.value;
|
|
activeElement.detachEvent('onpropertychange', handlePropertyChange);
|
|
|
|
activeElement = null;
|
|
activeElementID = null;
|
|
activeElementValue = null;
|
|
activeElementValueProp = null;
|
|
}
|
|
|
|
/**
|
|
* (For old IE.) Handles a propertychange event, sending a `change` event if
|
|
* the value of the active element has changed.
|
|
*/
|
|
function handlePropertyChange(nativeEvent) {
|
|
if (nativeEvent.propertyName !== 'value') {
|
|
return;
|
|
}
|
|
var value = nativeEvent.srcElement.value;
|
|
if (value === activeElementValue) {
|
|
return;
|
|
}
|
|
activeElementValue = value;
|
|
|
|
manualDispatchChangeEvent(nativeEvent);
|
|
}
|
|
|
|
/**
|
|
* If a `change` event should be fired, returns the target's ID.
|
|
*/
|
|
function getTargetIDForInputEvent(
|
|
topLevelType,
|
|
topLevelTarget,
|
|
topLevelTargetID) {
|
|
if (topLevelType === topLevelTypes.topInput) {
|
|
// In modern browsers (i.e., not IE8 or IE9), the input event is exactly
|
|
// what we want so fall through here and trigger an abstract event
|
|
return topLevelTargetID;
|
|
}
|
|
}
|
|
|
|
// For IE8 and IE9.
|
|
function handleEventsForInputEventIE(
|
|
topLevelType,
|
|
topLevelTarget,
|
|
topLevelTargetID) {
|
|
if (topLevelType === topLevelTypes.topFocus) {
|
|
// In IE8, we can capture almost all .value changes by adding a
|
|
// propertychange handler and looking for events with propertyName
|
|
// equal to 'value'
|
|
// In IE9, propertychange fires for most input events but is buggy and
|
|
// doesn't fire when text is deleted, but conveniently, selectionchange
|
|
// appears to fire in all of the remaining cases so we catch those and
|
|
// forward the event if the value has changed
|
|
// In either case, we don't want to call the event handler if the value
|
|
// is changed from JS so we redefine a setter for `.value` that updates
|
|
// our activeElementValue variable, allowing us to ignore those changes
|
|
//
|
|
// stopWatching() should be a noop here but we call it just in case we
|
|
// missed a blur event somehow.
|
|
stopWatchingForValueChange();
|
|
startWatchingForValueChange(topLevelTarget, topLevelTargetID);
|
|
} else if (topLevelType === topLevelTypes.topBlur) {
|
|
stopWatchingForValueChange();
|
|
}
|
|
}
|
|
|
|
// For IE8 and IE9.
|
|
function getTargetIDForInputEventIE(
|
|
topLevelType,
|
|
topLevelTarget,
|
|
topLevelTargetID) {
|
|
if (topLevelType === topLevelTypes.topSelectionChange ||
|
|
topLevelType === topLevelTypes.topKeyUp ||
|
|
topLevelType === topLevelTypes.topKeyDown) {
|
|
// On the selectionchange event, the target is just document which isn't
|
|
// helpful for us so just check activeElement instead.
|
|
//
|
|
// 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
|
|
// propertychange on the first input event after setting `value` from a
|
|
// script and fires only keydown, keypress, keyup. Catching keyup usually
|
|
// gets it and catching keydown lets us fire an event for the first
|
|
// keystroke if user does a key repeat (it'll be a little delayed: right
|
|
// before the second keystroke). Other input methods (e.g., paste) seem to
|
|
// fire selectionchange normally.
|
|
if (activeElement && activeElement.value !== activeElementValue) {
|
|
activeElementValue = activeElement.value;
|
|
return activeElementID;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* SECTION: handle `click` event
|
|
*/
|
|
function shouldUseClickEvent(elem) {
|
|
// Use the `click` event to detect changes to checkbox and radio inputs.
|
|
// This approach works across all browsers, whereas `change` does not fire
|
|
// until `blur` in IE8.
|
|
return (
|
|
elem.nodeName === 'INPUT' &&
|
|
(elem.type === 'checkbox' || elem.type === 'radio')
|
|
);
|
|
}
|
|
|
|
function getTargetIDForClickEvent(
|
|
topLevelType,
|
|
topLevelTarget,
|
|
topLevelTargetID) {
|
|
if (topLevelType === topLevelTypes.topClick) {
|
|
return topLevelTargetID;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This plugin creates an `onChange` event that normalizes change events
|
|
* across form elements. This event fires at a time when it's possible to
|
|
* change the element's value without seeing a flicker.
|
|
*
|
|
* Supported elements are:
|
|
* - input (see `isTextInputElement`)
|
|
* - textarea
|
|
* - select
|
|
*/
|
|
var ChangeEventPlugin = {
|
|
|
|
eventTypes: eventTypes,
|
|
|
|
/**
|
|
* @param {string} topLevelType Record from `EventConstants`.
|
|
* @param {DOMEventTarget} topLevelTarget The listening component root node.
|
|
* @param {string} topLevelTargetID ID of `topLevelTarget`.
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @return {*} An accumulation of synthetic events.
|
|
* @see {EventPluginHub.extractEvents}
|
|
*/
|
|
extractEvents: function(
|
|
topLevelType,
|
|
topLevelTarget,
|
|
topLevelTargetID,
|
|
nativeEvent) {
|
|
|
|
var getTargetIDFunc, handleEventFunc;
|
|
if (shouldUseChangeEvent(topLevelTarget)) {
|
|
if (doesChangeEventBubble) {
|
|
getTargetIDFunc = getTargetIDForChangeEvent;
|
|
} else {
|
|
handleEventFunc = handleEventsForChangeEventIE8;
|
|
}
|
|
} else if (isTextInputElement(topLevelTarget)) {
|
|
if (isInputEventSupported) {
|
|
getTargetIDFunc = getTargetIDForInputEvent;
|
|
} else {
|
|
getTargetIDFunc = getTargetIDForInputEventIE;
|
|
handleEventFunc = handleEventsForInputEventIE;
|
|
}
|
|
} else if (shouldUseClickEvent(topLevelTarget)) {
|
|
getTargetIDFunc = getTargetIDForClickEvent;
|
|
}
|
|
|
|
if (getTargetIDFunc) {
|
|
var targetID = getTargetIDFunc(
|
|
topLevelType,
|
|
topLevelTarget,
|
|
topLevelTargetID
|
|
);
|
|
if (targetID) {
|
|
var event = SyntheticEvent.getPooled(
|
|
eventTypes.change,
|
|
targetID,
|
|
nativeEvent
|
|
);
|
|
EventPropagators.accumulateTwoPhaseDispatches(event);
|
|
return event;
|
|
}
|
|
}
|
|
|
|
if (handleEventFunc) {
|
|
handleEventFunc(
|
|
topLevelType,
|
|
topLevelTarget,
|
|
topLevelTargetID
|
|
);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = ChangeEventPlugin;
|
|
|
|
},{"./EventConstants":64,"./EventPluginHub":66,"./EventPropagators":69,"./ExecutionEnvironment":70,"./ReactUpdates":137,"./SyntheticEvent":145,"./isEventSupported":186,"./isTextInputElement":188,"./keyOf":191}],57:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ClientReactRootIndex
|
|
* @typechecks
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var nextReactRootIndex = 0;
|
|
|
|
var ClientReactRootIndex = {
|
|
createReactRootIndex: function() {
|
|
return nextReactRootIndex++;
|
|
}
|
|
};
|
|
|
|
module.exports = ClientReactRootIndex;
|
|
|
|
},{}],58:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule DOMChildrenOperations
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var Danger = require("./Danger");
|
|
var ReactMultiChildUpdateTypes = require("./ReactMultiChildUpdateTypes");
|
|
|
|
var setTextContent = require("./setTextContent");
|
|
var invariant = require("./invariant");
|
|
|
|
/**
|
|
* Inserts `childNode` as a child of `parentNode` at the `index`.
|
|
*
|
|
* @param {DOMElement} parentNode Parent node in which to insert.
|
|
* @param {DOMElement} childNode Child node to insert.
|
|
* @param {number} index Index at which to insert the child.
|
|
* @internal
|
|
*/
|
|
function insertChildAt(parentNode, childNode, index) {
|
|
// By exploiting arrays returning `undefined` for an undefined index, we can
|
|
// rely exclusively on `insertBefore(node, null)` instead of also using
|
|
// `appendChild(node)`. However, using `undefined` is not allowed by all
|
|
// browsers so we must replace it with `null`.
|
|
parentNode.insertBefore(
|
|
childNode,
|
|
parentNode.childNodes[index] || null
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Operations for updating with DOM children.
|
|
*/
|
|
var DOMChildrenOperations = {
|
|
|
|
dangerouslyReplaceNodeWithMarkup: Danger.dangerouslyReplaceNodeWithMarkup,
|
|
|
|
updateTextContent: setTextContent,
|
|
|
|
/**
|
|
* Updates a component's children by processing a series of updates. The
|
|
* update configurations are each expected to have a `parentNode` property.
|
|
*
|
|
* @param {array<object>} updates List of update configurations.
|
|
* @param {array<string>} markupList List of markup strings.
|
|
* @internal
|
|
*/
|
|
processUpdates: function(updates, markupList) {
|
|
var update;
|
|
// Mapping from parent IDs to initial child orderings.
|
|
var initialChildren = null;
|
|
// List of children that will be moved or removed.
|
|
var updatedChildren = null;
|
|
|
|
for (var i = 0; i < updates.length; i++) {
|
|
update = updates[i];
|
|
if (update.type === ReactMultiChildUpdateTypes.MOVE_EXISTING ||
|
|
update.type === ReactMultiChildUpdateTypes.REMOVE_NODE) {
|
|
var updatedIndex = update.fromIndex;
|
|
var updatedChild = update.parentNode.childNodes[updatedIndex];
|
|
var parentID = update.parentID;
|
|
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
updatedChild,
|
|
'processUpdates(): Unable to find child %s of element. This ' +
|
|
'probably means the DOM was unexpectedly mutated (e.g., by the ' +
|
|
'browser), usually due to forgetting a <tbody> when using tables, ' +
|
|
'nesting tags like <form>, <p>, or <a>, or using non-SVG elements ' +
|
|
'in an <svg> parent. Try inspecting the child nodes of the element ' +
|
|
'with React ID `%s`.',
|
|
updatedIndex,
|
|
parentID
|
|
) : invariant(updatedChild));
|
|
|
|
initialChildren = initialChildren || {};
|
|
initialChildren[parentID] = initialChildren[parentID] || [];
|
|
initialChildren[parentID][updatedIndex] = updatedChild;
|
|
|
|
updatedChildren = updatedChildren || [];
|
|
updatedChildren.push(updatedChild);
|
|
}
|
|
}
|
|
|
|
var renderedMarkup = Danger.dangerouslyRenderMarkup(markupList);
|
|
|
|
// Remove updated children first so that `toIndex` is consistent.
|
|
if (updatedChildren) {
|
|
for (var j = 0; j < updatedChildren.length; j++) {
|
|
updatedChildren[j].parentNode.removeChild(updatedChildren[j]);
|
|
}
|
|
}
|
|
|
|
for (var k = 0; k < updates.length; k++) {
|
|
update = updates[k];
|
|
switch (update.type) {
|
|
case ReactMultiChildUpdateTypes.INSERT_MARKUP:
|
|
insertChildAt(
|
|
update.parentNode,
|
|
renderedMarkup[update.markupIndex],
|
|
update.toIndex
|
|
);
|
|
break;
|
|
case ReactMultiChildUpdateTypes.MOVE_EXISTING:
|
|
insertChildAt(
|
|
update.parentNode,
|
|
initialChildren[update.parentID][update.fromIndex],
|
|
update.toIndex
|
|
);
|
|
break;
|
|
case ReactMultiChildUpdateTypes.TEXT_CONTENT:
|
|
setTextContent(
|
|
update.parentNode,
|
|
update.textContent
|
|
);
|
|
break;
|
|
case ReactMultiChildUpdateTypes.REMOVE_NODE:
|
|
// Already removed by the for-loop above.
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = DOMChildrenOperations;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./Danger":61,"./ReactMultiChildUpdateTypes":122,"./invariant":185,"./setTextContent":199,"_process":1}],59:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule DOMProperty
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
/*jslint bitwise: true */
|
|
|
|
'use strict';
|
|
|
|
var invariant = require("./invariant");
|
|
|
|
function checkMask(value, bitmask) {
|
|
return (value & bitmask) === bitmask;
|
|
}
|
|
|
|
var DOMPropertyInjection = {
|
|
/**
|
|
* Mapping from normalized, camelcased property names to a configuration that
|
|
* specifies how the associated DOM property should be accessed or rendered.
|
|
*/
|
|
MUST_USE_ATTRIBUTE: 0x1,
|
|
MUST_USE_PROPERTY: 0x2,
|
|
HAS_SIDE_EFFECTS: 0x4,
|
|
HAS_BOOLEAN_VALUE: 0x8,
|
|
HAS_NUMERIC_VALUE: 0x10,
|
|
HAS_POSITIVE_NUMERIC_VALUE: 0x20 | 0x10,
|
|
HAS_OVERLOADED_BOOLEAN_VALUE: 0x40,
|
|
|
|
/**
|
|
* Inject some specialized knowledge about the DOM. This takes a config object
|
|
* with the following properties:
|
|
*
|
|
* isCustomAttribute: function that given an attribute name will return true
|
|
* if it can be inserted into the DOM verbatim. Useful for data-* or aria-*
|
|
* attributes where it's impossible to enumerate all of the possible
|
|
* attribute names,
|
|
*
|
|
* Properties: object mapping DOM property name to one of the
|
|
* DOMPropertyInjection constants or null. If your attribute isn't in here,
|
|
* it won't get written to the DOM.
|
|
*
|
|
* DOMAttributeNames: object mapping React attribute name to the DOM
|
|
* attribute name. Attribute names not specified use the **lowercase**
|
|
* normalized name.
|
|
*
|
|
* DOMPropertyNames: similar to DOMAttributeNames but for DOM properties.
|
|
* Property names not specified use the normalized name.
|
|
*
|
|
* DOMMutationMethods: Properties that require special mutation methods. If
|
|
* `value` is undefined, the mutation method should unset the property.
|
|
*
|
|
* @param {object} domPropertyConfig the config as described above.
|
|
*/
|
|
injectDOMPropertyConfig: function(domPropertyConfig) {
|
|
var Properties = domPropertyConfig.Properties || {};
|
|
var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {};
|
|
var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {};
|
|
var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {};
|
|
|
|
if (domPropertyConfig.isCustomAttribute) {
|
|
DOMProperty._isCustomAttributeFunctions.push(
|
|
domPropertyConfig.isCustomAttribute
|
|
);
|
|
}
|
|
|
|
for (var propName in Properties) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
!DOMProperty.isStandardName.hasOwnProperty(propName),
|
|
'injectDOMPropertyConfig(...): You\'re trying to inject DOM property ' +
|
|
'\'%s\' which has already been injected. You may be accidentally ' +
|
|
'injecting the same DOM property config twice, or you may be ' +
|
|
'injecting two configs that have conflicting property names.',
|
|
propName
|
|
) : invariant(!DOMProperty.isStandardName.hasOwnProperty(propName)));
|
|
|
|
DOMProperty.isStandardName[propName] = true;
|
|
|
|
var lowerCased = propName.toLowerCase();
|
|
DOMProperty.getPossibleStandardName[lowerCased] = propName;
|
|
|
|
if (DOMAttributeNames.hasOwnProperty(propName)) {
|
|
var attributeName = DOMAttributeNames[propName];
|
|
DOMProperty.getPossibleStandardName[attributeName] = propName;
|
|
DOMProperty.getAttributeName[propName] = attributeName;
|
|
} else {
|
|
DOMProperty.getAttributeName[propName] = lowerCased;
|
|
}
|
|
|
|
DOMProperty.getPropertyName[propName] =
|
|
DOMPropertyNames.hasOwnProperty(propName) ?
|
|
DOMPropertyNames[propName] :
|
|
propName;
|
|
|
|
if (DOMMutationMethods.hasOwnProperty(propName)) {
|
|
DOMProperty.getMutationMethod[propName] = DOMMutationMethods[propName];
|
|
} else {
|
|
DOMProperty.getMutationMethod[propName] = null;
|
|
}
|
|
|
|
var propConfig = Properties[propName];
|
|
DOMProperty.mustUseAttribute[propName] =
|
|
checkMask(propConfig, DOMPropertyInjection.MUST_USE_ATTRIBUTE);
|
|
DOMProperty.mustUseProperty[propName] =
|
|
checkMask(propConfig, DOMPropertyInjection.MUST_USE_PROPERTY);
|
|
DOMProperty.hasSideEffects[propName] =
|
|
checkMask(propConfig, DOMPropertyInjection.HAS_SIDE_EFFECTS);
|
|
DOMProperty.hasBooleanValue[propName] =
|
|
checkMask(propConfig, DOMPropertyInjection.HAS_BOOLEAN_VALUE);
|
|
DOMProperty.hasNumericValue[propName] =
|
|
checkMask(propConfig, DOMPropertyInjection.HAS_NUMERIC_VALUE);
|
|
DOMProperty.hasPositiveNumericValue[propName] =
|
|
checkMask(propConfig, DOMPropertyInjection.HAS_POSITIVE_NUMERIC_VALUE);
|
|
DOMProperty.hasOverloadedBooleanValue[propName] =
|
|
checkMask(propConfig, DOMPropertyInjection.HAS_OVERLOADED_BOOLEAN_VALUE);
|
|
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
!DOMProperty.mustUseAttribute[propName] ||
|
|
!DOMProperty.mustUseProperty[propName],
|
|
'DOMProperty: Cannot require using both attribute and property: %s',
|
|
propName
|
|
) : invariant(!DOMProperty.mustUseAttribute[propName] ||
|
|
!DOMProperty.mustUseProperty[propName]));
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
DOMProperty.mustUseProperty[propName] ||
|
|
!DOMProperty.hasSideEffects[propName],
|
|
'DOMProperty: Properties that have side effects must use property: %s',
|
|
propName
|
|
) : invariant(DOMProperty.mustUseProperty[propName] ||
|
|
!DOMProperty.hasSideEffects[propName]));
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
!!DOMProperty.hasBooleanValue[propName] +
|
|
!!DOMProperty.hasNumericValue[propName] +
|
|
!!DOMProperty.hasOverloadedBooleanValue[propName] <= 1,
|
|
'DOMProperty: Value can be one of boolean, overloaded boolean, or ' +
|
|
'numeric value, but not a combination: %s',
|
|
propName
|
|
) : invariant(!!DOMProperty.hasBooleanValue[propName] +
|
|
!!DOMProperty.hasNumericValue[propName] +
|
|
!!DOMProperty.hasOverloadedBooleanValue[propName] <= 1));
|
|
}
|
|
}
|
|
};
|
|
var defaultValueCache = {};
|
|
|
|
/**
|
|
* DOMProperty exports lookup objects that can be used like functions:
|
|
*
|
|
* > DOMProperty.isValid['id']
|
|
* true
|
|
* > DOMProperty.isValid['foobar']
|
|
* undefined
|
|
*
|
|
* Although this may be confusing, it performs better in general.
|
|
*
|
|
* @see http://jsperf.com/key-exists
|
|
* @see http://jsperf.com/key-missing
|
|
*/
|
|
var DOMProperty = {
|
|
|
|
ID_ATTRIBUTE_NAME: 'data-reactid',
|
|
|
|
/**
|
|
* Checks whether a property name is a standard property.
|
|
* @type {Object}
|
|
*/
|
|
isStandardName: {},
|
|
|
|
/**
|
|
* Mapping from lowercase property names to the properly cased version, used
|
|
* to warn in the case of missing properties.
|
|
* @type {Object}
|
|
*/
|
|
getPossibleStandardName: {},
|
|
|
|
/**
|
|
* Mapping from normalized names to attribute names that differ. Attribute
|
|
* names are used when rendering markup or with `*Attribute()`.
|
|
* @type {Object}
|
|
*/
|
|
getAttributeName: {},
|
|
|
|
/**
|
|
* Mapping from normalized names to properties on DOM node instances.
|
|
* (This includes properties that mutate due to external factors.)
|
|
* @type {Object}
|
|
*/
|
|
getPropertyName: {},
|
|
|
|
/**
|
|
* Mapping from normalized names to mutation methods. This will only exist if
|
|
* mutation cannot be set simply by the property or `setAttribute()`.
|
|
* @type {Object}
|
|
*/
|
|
getMutationMethod: {},
|
|
|
|
/**
|
|
* Whether the property must be accessed and mutated as an object property.
|
|
* @type {Object}
|
|
*/
|
|
mustUseAttribute: {},
|
|
|
|
/**
|
|
* Whether the property must be accessed and mutated using `*Attribute()`.
|
|
* (This includes anything that fails `<propName> in <element>`.)
|
|
* @type {Object}
|
|
*/
|
|
mustUseProperty: {},
|
|
|
|
/**
|
|
* Whether or not setting a value causes side effects such as triggering
|
|
* resources to be loaded or text selection changes. We must ensure that
|
|
* the value is only set if it has changed.
|
|
* @type {Object}
|
|
*/
|
|
hasSideEffects: {},
|
|
|
|
/**
|
|
* Whether the property should be removed when set to a falsey value.
|
|
* @type {Object}
|
|
*/
|
|
hasBooleanValue: {},
|
|
|
|
/**
|
|
* Whether the property must be numeric or parse as a
|
|
* numeric and should be removed when set to a falsey value.
|
|
* @type {Object}
|
|
*/
|
|
hasNumericValue: {},
|
|
|
|
/**
|
|
* Whether the property must be positive numeric or parse as a positive
|
|
* numeric and should be removed when set to a falsey value.
|
|
* @type {Object}
|
|
*/
|
|
hasPositiveNumericValue: {},
|
|
|
|
/**
|
|
* Whether the property can be used as a flag as well as with a value. Removed
|
|
* when strictly equal to false; present without a value when strictly equal
|
|
* to true; present with a value otherwise.
|
|
* @type {Object}
|
|
*/
|
|
hasOverloadedBooleanValue: {},
|
|
|
|
/**
|
|
* All of the isCustomAttribute() functions that have been injected.
|
|
*/
|
|
_isCustomAttributeFunctions: [],
|
|
|
|
/**
|
|
* Checks whether a property name is a custom attribute.
|
|
* @method
|
|
*/
|
|
isCustomAttribute: function(attributeName) {
|
|
for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) {
|
|
var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i];
|
|
if (isCustomAttributeFn(attributeName)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
},
|
|
|
|
/**
|
|
* Returns the default property value for a DOM property (i.e., not an
|
|
* attribute). Most default values are '' or false, but not all. Worse yet,
|
|
* some (in particular, `type`) vary depending on the type of element.
|
|
*
|
|
* TODO: Is it better to grab all the possible properties when creating an
|
|
* element to avoid having to create the same element twice?
|
|
*/
|
|
getDefaultValueForProperty: function(nodeName, prop) {
|
|
var nodeDefaults = defaultValueCache[nodeName];
|
|
var testElement;
|
|
if (!nodeDefaults) {
|
|
defaultValueCache[nodeName] = nodeDefaults = {};
|
|
}
|
|
if (!(prop in nodeDefaults)) {
|
|
testElement = document.createElement(nodeName);
|
|
nodeDefaults[prop] = testElement[prop];
|
|
}
|
|
return nodeDefaults[prop];
|
|
},
|
|
|
|
injection: DOMPropertyInjection
|
|
};
|
|
|
|
module.exports = DOMProperty;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./invariant":185,"_process":1}],60:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule DOMPropertyOperations
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var DOMProperty = require("./DOMProperty");
|
|
|
|
var quoteAttributeValueForBrowser = require("./quoteAttributeValueForBrowser");
|
|
var warning = require("./warning");
|
|
|
|
function shouldIgnoreValue(name, value) {
|
|
return value == null ||
|
|
(DOMProperty.hasBooleanValue[name] && !value) ||
|
|
(DOMProperty.hasNumericValue[name] && isNaN(value)) ||
|
|
(DOMProperty.hasPositiveNumericValue[name] && (value < 1)) ||
|
|
(DOMProperty.hasOverloadedBooleanValue[name] && value === false);
|
|
}
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
var reactProps = {
|
|
children: true,
|
|
dangerouslySetInnerHTML: true,
|
|
key: true,
|
|
ref: true
|
|
};
|
|
var warnedProperties = {};
|
|
|
|
var warnUnknownProperty = function(name) {
|
|
if (reactProps.hasOwnProperty(name) && reactProps[name] ||
|
|
warnedProperties.hasOwnProperty(name) && warnedProperties[name]) {
|
|
return;
|
|
}
|
|
|
|
warnedProperties[name] = true;
|
|
var lowerCasedName = name.toLowerCase();
|
|
|
|
// data-* attributes should be lowercase; suggest the lowercase version
|
|
var standardName = (
|
|
DOMProperty.isCustomAttribute(lowerCasedName) ?
|
|
lowerCasedName :
|
|
DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ?
|
|
DOMProperty.getPossibleStandardName[lowerCasedName] :
|
|
null
|
|
);
|
|
|
|
// For now, only warn when we have a suggested correction. This prevents
|
|
// logging too much when using transferPropsTo.
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
standardName == null,
|
|
'Unknown DOM property %s. Did you mean %s?',
|
|
name,
|
|
standardName
|
|
) : null);
|
|
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Operations for dealing with DOM properties.
|
|
*/
|
|
var DOMPropertyOperations = {
|
|
|
|
/**
|
|
* Creates markup for the ID property.
|
|
*
|
|
* @param {string} id Unescaped ID.
|
|
* @return {string} Markup string.
|
|
*/
|
|
createMarkupForID: function(id) {
|
|
return DOMProperty.ID_ATTRIBUTE_NAME + '=' +
|
|
quoteAttributeValueForBrowser(id);
|
|
},
|
|
|
|
/**
|
|
* Creates markup for a property.
|
|
*
|
|
* @param {string} name
|
|
* @param {*} value
|
|
* @return {?string} Markup string, or null if the property was invalid.
|
|
*/
|
|
createMarkupForProperty: function(name, value) {
|
|
if (DOMProperty.isStandardName.hasOwnProperty(name) &&
|
|
DOMProperty.isStandardName[name]) {
|
|
if (shouldIgnoreValue(name, value)) {
|
|
return '';
|
|
}
|
|
var attributeName = DOMProperty.getAttributeName[name];
|
|
if (DOMProperty.hasBooleanValue[name] ||
|
|
(DOMProperty.hasOverloadedBooleanValue[name] && value === true)) {
|
|
return attributeName;
|
|
}
|
|
return attributeName + '=' + quoteAttributeValueForBrowser(value);
|
|
} else if (DOMProperty.isCustomAttribute(name)) {
|
|
if (value == null) {
|
|
return '';
|
|
}
|
|
return name + '=' + quoteAttributeValueForBrowser(value);
|
|
} else if ("production" !== process.env.NODE_ENV) {
|
|
warnUnknownProperty(name);
|
|
}
|
|
return null;
|
|
},
|
|
|
|
/**
|
|
* Sets the value for a property on a node.
|
|
*
|
|
* @param {DOMElement} node
|
|
* @param {string} name
|
|
* @param {*} value
|
|
*/
|
|
setValueForProperty: function(node, name, value) {
|
|
if (DOMProperty.isStandardName.hasOwnProperty(name) &&
|
|
DOMProperty.isStandardName[name]) {
|
|
var mutationMethod = DOMProperty.getMutationMethod[name];
|
|
if (mutationMethod) {
|
|
mutationMethod(node, value);
|
|
} else if (shouldIgnoreValue(name, value)) {
|
|
this.deleteValueForProperty(node, name);
|
|
} else if (DOMProperty.mustUseAttribute[name]) {
|
|
// `setAttribute` with objects becomes only `[object]` in IE8/9,
|
|
// ('' + value) makes it output the correct toString()-value.
|
|
node.setAttribute(DOMProperty.getAttributeName[name], '' + value);
|
|
} else {
|
|
var propName = DOMProperty.getPropertyName[name];
|
|
// Must explicitly cast values for HAS_SIDE_EFFECTS-properties to the
|
|
// property type before comparing; only `value` does and is string.
|
|
if (!DOMProperty.hasSideEffects[name] ||
|
|
('' + node[propName]) !== ('' + value)) {
|
|
// Contrary to `setAttribute`, object properties are properly
|
|
// `toString`ed by IE8/9.
|
|
node[propName] = value;
|
|
}
|
|
}
|
|
} else if (DOMProperty.isCustomAttribute(name)) {
|
|
if (value == null) {
|
|
node.removeAttribute(name);
|
|
} else {
|
|
node.setAttribute(name, '' + value);
|
|
}
|
|
} else if ("production" !== process.env.NODE_ENV) {
|
|
warnUnknownProperty(name);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Deletes the value for a property on a node.
|
|
*
|
|
* @param {DOMElement} node
|
|
* @param {string} name
|
|
*/
|
|
deleteValueForProperty: function(node, name) {
|
|
if (DOMProperty.isStandardName.hasOwnProperty(name) &&
|
|
DOMProperty.isStandardName[name]) {
|
|
var mutationMethod = DOMProperty.getMutationMethod[name];
|
|
if (mutationMethod) {
|
|
mutationMethod(node, undefined);
|
|
} else if (DOMProperty.mustUseAttribute[name]) {
|
|
node.removeAttribute(DOMProperty.getAttributeName[name]);
|
|
} else {
|
|
var propName = DOMProperty.getPropertyName[name];
|
|
var defaultValue = DOMProperty.getDefaultValueForProperty(
|
|
node.nodeName,
|
|
propName
|
|
);
|
|
if (!DOMProperty.hasSideEffects[name] ||
|
|
('' + node[propName]) !== defaultValue) {
|
|
node[propName] = defaultValue;
|
|
}
|
|
}
|
|
} else if (DOMProperty.isCustomAttribute(name)) {
|
|
node.removeAttribute(name);
|
|
} else if ("production" !== process.env.NODE_ENV) {
|
|
warnUnknownProperty(name);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = DOMPropertyOperations;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./DOMProperty":59,"./quoteAttributeValueForBrowser":197,"./warning":204,"_process":1}],61:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule Danger
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
/*jslint evil: true, sub: true */
|
|
|
|
'use strict';
|
|
|
|
var ExecutionEnvironment = require("./ExecutionEnvironment");
|
|
|
|
var createNodesFromMarkup = require("./createNodesFromMarkup");
|
|
var emptyFunction = require("./emptyFunction");
|
|
var getMarkupWrap = require("./getMarkupWrap");
|
|
var invariant = require("./invariant");
|
|
|
|
var OPEN_TAG_NAME_EXP = /^(<[^ \/>]+)/;
|
|
var RESULT_INDEX_ATTR = 'data-danger-index';
|
|
|
|
/**
|
|
* Extracts the `nodeName` from a string of markup.
|
|
*
|
|
* NOTE: Extracting the `nodeName` does not require a regular expression match
|
|
* because we make assumptions about React-generated markup (i.e. there are no
|
|
* spaces surrounding the opening tag and there is at least one attribute).
|
|
*
|
|
* @param {string} markup String of markup.
|
|
* @return {string} Node name of the supplied markup.
|
|
* @see http://jsperf.com/extract-nodename
|
|
*/
|
|
function getNodeName(markup) {
|
|
return markup.substring(1, markup.indexOf(' '));
|
|
}
|
|
|
|
var Danger = {
|
|
|
|
/**
|
|
* Renders markup into an array of nodes. The markup is expected to render
|
|
* into a list of root nodes. Also, the length of `resultList` and
|
|
* `markupList` should be the same.
|
|
*
|
|
* @param {array<string>} markupList List of markup strings to render.
|
|
* @return {array<DOMElement>} List of rendered nodes.
|
|
* @internal
|
|
*/
|
|
dangerouslyRenderMarkup: function(markupList) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
ExecutionEnvironment.canUseDOM,
|
|
'dangerouslyRenderMarkup(...): Cannot render markup in a worker ' +
|
|
'thread. Make sure `window` and `document` are available globally ' +
|
|
'before requiring React when unit testing or use ' +
|
|
'React.renderToString for server rendering.'
|
|
) : invariant(ExecutionEnvironment.canUseDOM));
|
|
var nodeName;
|
|
var markupByNodeName = {};
|
|
// Group markup by `nodeName` if a wrap is necessary, else by '*'.
|
|
for (var i = 0; i < markupList.length; i++) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
markupList[i],
|
|
'dangerouslyRenderMarkup(...): Missing markup.'
|
|
) : invariant(markupList[i]));
|
|
nodeName = getNodeName(markupList[i]);
|
|
nodeName = getMarkupWrap(nodeName) ? nodeName : '*';
|
|
markupByNodeName[nodeName] = markupByNodeName[nodeName] || [];
|
|
markupByNodeName[nodeName][i] = markupList[i];
|
|
}
|
|
var resultList = [];
|
|
var resultListAssignmentCount = 0;
|
|
for (nodeName in markupByNodeName) {
|
|
if (!markupByNodeName.hasOwnProperty(nodeName)) {
|
|
continue;
|
|
}
|
|
var markupListByNodeName = markupByNodeName[nodeName];
|
|
|
|
// This for-in loop skips the holes of the sparse array. The order of
|
|
// iteration should follow the order of assignment, which happens to match
|
|
// numerical index order, but we don't rely on that.
|
|
var resultIndex;
|
|
for (resultIndex in markupListByNodeName) {
|
|
if (markupListByNodeName.hasOwnProperty(resultIndex)) {
|
|
var markup = markupListByNodeName[resultIndex];
|
|
|
|
// Push the requested markup with an additional RESULT_INDEX_ATTR
|
|
// attribute. If the markup does not start with a < character, it
|
|
// will be discarded below (with an appropriate console.error).
|
|
markupListByNodeName[resultIndex] = markup.replace(
|
|
OPEN_TAG_NAME_EXP,
|
|
// This index will be parsed back out below.
|
|
'$1 ' + RESULT_INDEX_ATTR + '="' + resultIndex + '" '
|
|
);
|
|
}
|
|
}
|
|
|
|
// Render each group of markup with similar wrapping `nodeName`.
|
|
var renderNodes = createNodesFromMarkup(
|
|
markupListByNodeName.join(''),
|
|
emptyFunction // Do nothing special with <script> tags.
|
|
);
|
|
|
|
for (var j = 0; j < renderNodes.length; ++j) {
|
|
var renderNode = renderNodes[j];
|
|
if (renderNode.hasAttribute &&
|
|
renderNode.hasAttribute(RESULT_INDEX_ATTR)) {
|
|
|
|
resultIndex = +renderNode.getAttribute(RESULT_INDEX_ATTR);
|
|
renderNode.removeAttribute(RESULT_INDEX_ATTR);
|
|
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
!resultList.hasOwnProperty(resultIndex),
|
|
'Danger: Assigning to an already-occupied result index.'
|
|
) : invariant(!resultList.hasOwnProperty(resultIndex)));
|
|
|
|
resultList[resultIndex] = renderNode;
|
|
|
|
// This should match resultList.length and markupList.length when
|
|
// we're done.
|
|
resultListAssignmentCount += 1;
|
|
|
|
} else if ("production" !== process.env.NODE_ENV) {
|
|
console.error(
|
|
'Danger: Discarding unexpected node:',
|
|
renderNode
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Although resultList was populated out of order, it should now be a dense
|
|
// array.
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
resultListAssignmentCount === resultList.length,
|
|
'Danger: Did not assign to every index of resultList.'
|
|
) : invariant(resultListAssignmentCount === resultList.length));
|
|
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
resultList.length === markupList.length,
|
|
'Danger: Expected markup to render %s nodes, but rendered %s.',
|
|
markupList.length,
|
|
resultList.length
|
|
) : invariant(resultList.length === markupList.length));
|
|
|
|
return resultList;
|
|
},
|
|
|
|
/**
|
|
* Replaces a node with a string of markup at its current position within its
|
|
* parent. The markup must render into a single root node.
|
|
*
|
|
* @param {DOMElement} oldChild Child node to replace.
|
|
* @param {string} markup Markup to render in place of the child node.
|
|
* @internal
|
|
*/
|
|
dangerouslyReplaceNodeWithMarkup: function(oldChild, markup) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
ExecutionEnvironment.canUseDOM,
|
|
'dangerouslyReplaceNodeWithMarkup(...): Cannot render markup in a ' +
|
|
'worker thread. Make sure `window` and `document` are available ' +
|
|
'globally before requiring React when unit testing or use ' +
|
|
'React.renderToString for server rendering.'
|
|
) : invariant(ExecutionEnvironment.canUseDOM));
|
|
("production" !== process.env.NODE_ENV ? invariant(markup, 'dangerouslyReplaceNodeWithMarkup(...): Missing markup.') : invariant(markup));
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
oldChild.tagName.toLowerCase() !== 'html',
|
|
'dangerouslyReplaceNodeWithMarkup(...): Cannot replace markup of the ' +
|
|
'<html> node. This is because browser quirks make this unreliable ' +
|
|
'and/or slow. If you want to render to the root you must use ' +
|
|
'server rendering. See React.renderToString().'
|
|
) : invariant(oldChild.tagName.toLowerCase() !== 'html'));
|
|
|
|
var newChild = createNodesFromMarkup(markup, emptyFunction)[0];
|
|
oldChild.parentNode.replaceChild(newChild, oldChild);
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = Danger;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./ExecutionEnvironment":70,"./createNodesFromMarkup":162,"./emptyFunction":164,"./getMarkupWrap":177,"./invariant":185,"_process":1}],62:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule DefaultEventPluginOrder
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var keyOf = require("./keyOf");
|
|
|
|
/**
|
|
* Module that is injectable into `EventPluginHub`, that specifies a
|
|
* deterministic ordering of `EventPlugin`s. A convenient way to reason about
|
|
* plugins, without having to package every one of them. This is better than
|
|
* having plugins be ordered in the same order that they are injected because
|
|
* that ordering would be influenced by the packaging order.
|
|
* `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that
|
|
* preventing default on events is convenient in `SimpleEventPlugin` handlers.
|
|
*/
|
|
var DefaultEventPluginOrder = [
|
|
keyOf({ResponderEventPlugin: null}),
|
|
keyOf({SimpleEventPlugin: null}),
|
|
keyOf({TapEventPlugin: null}),
|
|
keyOf({EnterLeaveEventPlugin: null}),
|
|
keyOf({ChangeEventPlugin: null}),
|
|
keyOf({SelectEventPlugin: null}),
|
|
keyOf({BeforeInputEventPlugin: null}),
|
|
keyOf({AnalyticsEventPlugin: null}),
|
|
keyOf({MobileSafariClickEventPlugin: null})
|
|
];
|
|
|
|
module.exports = DefaultEventPluginOrder;
|
|
|
|
},{"./keyOf":191}],63:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule EnterLeaveEventPlugin
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var EventConstants = require("./EventConstants");
|
|
var EventPropagators = require("./EventPropagators");
|
|
var SyntheticMouseEvent = require("./SyntheticMouseEvent");
|
|
|
|
var ReactMount = require("./ReactMount");
|
|
var keyOf = require("./keyOf");
|
|
|
|
var topLevelTypes = EventConstants.topLevelTypes;
|
|
var getFirstReactDOM = ReactMount.getFirstReactDOM;
|
|
|
|
var eventTypes = {
|
|
mouseEnter: {
|
|
registrationName: keyOf({onMouseEnter: null}),
|
|
dependencies: [
|
|
topLevelTypes.topMouseOut,
|
|
topLevelTypes.topMouseOver
|
|
]
|
|
},
|
|
mouseLeave: {
|
|
registrationName: keyOf({onMouseLeave: null}),
|
|
dependencies: [
|
|
topLevelTypes.topMouseOut,
|
|
topLevelTypes.topMouseOver
|
|
]
|
|
}
|
|
};
|
|
|
|
var extractedEvents = [null, null];
|
|
|
|
var EnterLeaveEventPlugin = {
|
|
|
|
eventTypes: eventTypes,
|
|
|
|
/**
|
|
* For almost every interaction we care about, there will be both a top-level
|
|
* `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
|
|
* we do not extract duplicate events. However, moving the mouse into the
|
|
* browser from outside will not fire a `mouseout` event. In this case, we use
|
|
* the `mouseover` top-level event.
|
|
*
|
|
* @param {string} topLevelType Record from `EventConstants`.
|
|
* @param {DOMEventTarget} topLevelTarget The listening component root node.
|
|
* @param {string} topLevelTargetID ID of `topLevelTarget`.
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @return {*} An accumulation of synthetic events.
|
|
* @see {EventPluginHub.extractEvents}
|
|
*/
|
|
extractEvents: function(
|
|
topLevelType,
|
|
topLevelTarget,
|
|
topLevelTargetID,
|
|
nativeEvent) {
|
|
if (topLevelType === topLevelTypes.topMouseOver &&
|
|
(nativeEvent.relatedTarget || nativeEvent.fromElement)) {
|
|
return null;
|
|
}
|
|
if (topLevelType !== topLevelTypes.topMouseOut &&
|
|
topLevelType !== topLevelTypes.topMouseOver) {
|
|
// Must not be a mouse in or mouse out - ignoring.
|
|
return null;
|
|
}
|
|
|
|
var win;
|
|
if (topLevelTarget.window === topLevelTarget) {
|
|
// `topLevelTarget` is probably a window object.
|
|
win = topLevelTarget;
|
|
} else {
|
|
// TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
|
|
var doc = topLevelTarget.ownerDocument;
|
|
if (doc) {
|
|
win = doc.defaultView || doc.parentWindow;
|
|
} else {
|
|
win = window;
|
|
}
|
|
}
|
|
|
|
var from, to;
|
|
if (topLevelType === topLevelTypes.topMouseOut) {
|
|
from = topLevelTarget;
|
|
to =
|
|
getFirstReactDOM(nativeEvent.relatedTarget || nativeEvent.toElement) ||
|
|
win;
|
|
} else {
|
|
from = win;
|
|
to = topLevelTarget;
|
|
}
|
|
|
|
if (from === to) {
|
|
// Nothing pertains to our managed components.
|
|
return null;
|
|
}
|
|
|
|
var fromID = from ? ReactMount.getID(from) : '';
|
|
var toID = to ? ReactMount.getID(to) : '';
|
|
|
|
var leave = SyntheticMouseEvent.getPooled(
|
|
eventTypes.mouseLeave,
|
|
fromID,
|
|
nativeEvent
|
|
);
|
|
leave.type = 'mouseleave';
|
|
leave.target = from;
|
|
leave.relatedTarget = to;
|
|
|
|
var enter = SyntheticMouseEvent.getPooled(
|
|
eventTypes.mouseEnter,
|
|
toID,
|
|
nativeEvent
|
|
);
|
|
enter.type = 'mouseenter';
|
|
enter.target = to;
|
|
enter.relatedTarget = from;
|
|
|
|
EventPropagators.accumulateEnterLeaveDispatches(leave, enter, fromID, toID);
|
|
|
|
extractedEvents[0] = leave;
|
|
extractedEvents[1] = enter;
|
|
|
|
return extractedEvents;
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = EnterLeaveEventPlugin;
|
|
|
|
},{"./EventConstants":64,"./EventPropagators":69,"./ReactMount":120,"./SyntheticMouseEvent":149,"./keyOf":191}],64:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule EventConstants
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var keyMirror = require("./keyMirror");
|
|
|
|
var PropagationPhases = keyMirror({bubbled: null, captured: null});
|
|
|
|
/**
|
|
* Types of raw signals from the browser caught at the top level.
|
|
*/
|
|
var topLevelTypes = keyMirror({
|
|
topBlur: null,
|
|
topChange: null,
|
|
topClick: null,
|
|
topCompositionEnd: null,
|
|
topCompositionStart: null,
|
|
topCompositionUpdate: null,
|
|
topContextMenu: null,
|
|
topCopy: null,
|
|
topCut: null,
|
|
topDoubleClick: null,
|
|
topDrag: null,
|
|
topDragEnd: null,
|
|
topDragEnter: null,
|
|
topDragExit: null,
|
|
topDragLeave: null,
|
|
topDragOver: null,
|
|
topDragStart: null,
|
|
topDrop: null,
|
|
topError: null,
|
|
topFocus: null,
|
|
topInput: null,
|
|
topKeyDown: null,
|
|
topKeyPress: null,
|
|
topKeyUp: null,
|
|
topLoad: null,
|
|
topMouseDown: null,
|
|
topMouseMove: null,
|
|
topMouseOut: null,
|
|
topMouseOver: null,
|
|
topMouseUp: null,
|
|
topPaste: null,
|
|
topReset: null,
|
|
topScroll: null,
|
|
topSelectionChange: null,
|
|
topSubmit: null,
|
|
topTextInput: null,
|
|
topTouchCancel: null,
|
|
topTouchEnd: null,
|
|
topTouchMove: null,
|
|
topTouchStart: null,
|
|
topWheel: null
|
|
});
|
|
|
|
var EventConstants = {
|
|
topLevelTypes: topLevelTypes,
|
|
PropagationPhases: PropagationPhases
|
|
};
|
|
|
|
module.exports = EventConstants;
|
|
|
|
},{"./keyMirror":190}],65:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
* @providesModule EventListener
|
|
* @typechecks
|
|
*/
|
|
|
|
var emptyFunction = require("./emptyFunction");
|
|
|
|
/**
|
|
* Upstream version of event listener. Does not take into account specific
|
|
* nature of platform.
|
|
*/
|
|
var EventListener = {
|
|
/**
|
|
* Listen to DOM events during the bubble phase.
|
|
*
|
|
* @param {DOMEventTarget} target DOM element to register listener on.
|
|
* @param {string} eventType Event type, e.g. 'click' or 'mouseover'.
|
|
* @param {function} callback Callback function.
|
|
* @return {object} Object with a `remove` method.
|
|
*/
|
|
listen: function(target, eventType, callback) {
|
|
if (target.addEventListener) {
|
|
target.addEventListener(eventType, callback, false);
|
|
return {
|
|
remove: function() {
|
|
target.removeEventListener(eventType, callback, false);
|
|
}
|
|
};
|
|
} else if (target.attachEvent) {
|
|
target.attachEvent('on' + eventType, callback);
|
|
return {
|
|
remove: function() {
|
|
target.detachEvent('on' + eventType, callback);
|
|
}
|
|
};
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Listen to DOM events during the capture phase.
|
|
*
|
|
* @param {DOMEventTarget} target DOM element to register listener on.
|
|
* @param {string} eventType Event type, e.g. 'click' or 'mouseover'.
|
|
* @param {function} callback Callback function.
|
|
* @return {object} Object with a `remove` method.
|
|
*/
|
|
capture: function(target, eventType, callback) {
|
|
if (!target.addEventListener) {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
console.error(
|
|
'Attempted to listen to events during the capture phase on a ' +
|
|
'browser that does not support the capture phase. Your application ' +
|
|
'will not receive some events.'
|
|
);
|
|
}
|
|
return {
|
|
remove: emptyFunction
|
|
};
|
|
} else {
|
|
target.addEventListener(eventType, callback, true);
|
|
return {
|
|
remove: function() {
|
|
target.removeEventListener(eventType, callback, true);
|
|
}
|
|
};
|
|
}
|
|
},
|
|
|
|
registerDefault: function() {}
|
|
};
|
|
|
|
module.exports = EventListener;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./emptyFunction":164,"_process":1}],66:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule EventPluginHub
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var EventPluginRegistry = require("./EventPluginRegistry");
|
|
var EventPluginUtils = require("./EventPluginUtils");
|
|
|
|
var accumulateInto = require("./accumulateInto");
|
|
var forEachAccumulated = require("./forEachAccumulated");
|
|
var invariant = require("./invariant");
|
|
|
|
/**
|
|
* Internal store for event listeners
|
|
*/
|
|
var listenerBank = {};
|
|
|
|
/**
|
|
* Internal queue of events that have accumulated their dispatches and are
|
|
* waiting to have their dispatches executed.
|
|
*/
|
|
var eventQueue = null;
|
|
|
|
/**
|
|
* Dispatches an event and releases it back into the pool, unless persistent.
|
|
*
|
|
* @param {?object} event Synthetic event to be dispatched.
|
|
* @private
|
|
*/
|
|
var executeDispatchesAndRelease = function(event) {
|
|
if (event) {
|
|
var executeDispatch = EventPluginUtils.executeDispatch;
|
|
// Plugins can provide custom behavior when dispatching events.
|
|
var PluginModule = EventPluginRegistry.getPluginModuleForEvent(event);
|
|
if (PluginModule && PluginModule.executeDispatch) {
|
|
executeDispatch = PluginModule.executeDispatch;
|
|
}
|
|
EventPluginUtils.executeDispatchesInOrder(event, executeDispatch);
|
|
|
|
if (!event.isPersistent()) {
|
|
event.constructor.release(event);
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* - `InstanceHandle`: [required] Module that performs logical traversals of DOM
|
|
* hierarchy given ids of the logical DOM elements involved.
|
|
*/
|
|
var InstanceHandle = null;
|
|
|
|
function validateInstanceHandle() {
|
|
var valid =
|
|
InstanceHandle &&
|
|
InstanceHandle.traverseTwoPhase &&
|
|
InstanceHandle.traverseEnterLeave;
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
valid,
|
|
'InstanceHandle not injected before use!'
|
|
) : invariant(valid));
|
|
}
|
|
|
|
/**
|
|
* This is a unified interface for event plugins to be installed and configured.
|
|
*
|
|
* Event plugins can implement the following properties:
|
|
*
|
|
* `extractEvents` {function(string, DOMEventTarget, string, object): *}
|
|
* Required. When a top-level event is fired, this method is expected to
|
|
* extract synthetic events that will in turn be queued and dispatched.
|
|
*
|
|
* `eventTypes` {object}
|
|
* Optional, plugins that fire events must publish a mapping of registration
|
|
* names that are used to register listeners. Values of this mapping must
|
|
* be objects that contain `registrationName` or `phasedRegistrationNames`.
|
|
*
|
|
* `executeDispatch` {function(object, function, string)}
|
|
* Optional, allows plugins to override how an event gets dispatched. By
|
|
* default, the listener is simply invoked.
|
|
*
|
|
* Each plugin that is injected into `EventsPluginHub` is immediately operable.
|
|
*
|
|
* @public
|
|
*/
|
|
var EventPluginHub = {
|
|
|
|
/**
|
|
* Methods for injecting dependencies.
|
|
*/
|
|
injection: {
|
|
|
|
/**
|
|
* @param {object} InjectedMount
|
|
* @public
|
|
*/
|
|
injectMount: EventPluginUtils.injection.injectMount,
|
|
|
|
/**
|
|
* @param {object} InjectedInstanceHandle
|
|
* @public
|
|
*/
|
|
injectInstanceHandle: function(InjectedInstanceHandle) {
|
|
InstanceHandle = InjectedInstanceHandle;
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
validateInstanceHandle();
|
|
}
|
|
},
|
|
|
|
getInstanceHandle: function() {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
validateInstanceHandle();
|
|
}
|
|
return InstanceHandle;
|
|
},
|
|
|
|
/**
|
|
* @param {array} InjectedEventPluginOrder
|
|
* @public
|
|
*/
|
|
injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder,
|
|
|
|
/**
|
|
* @param {object} injectedNamesToPlugins Map from names to plugin modules.
|
|
*/
|
|
injectEventPluginsByName: EventPluginRegistry.injectEventPluginsByName
|
|
|
|
},
|
|
|
|
eventNameDispatchConfigs: EventPluginRegistry.eventNameDispatchConfigs,
|
|
|
|
registrationNameModules: EventPluginRegistry.registrationNameModules,
|
|
|
|
/**
|
|
* Stores `listener` at `listenerBank[registrationName][id]`. Is idempotent.
|
|
*
|
|
* @param {string} id ID of the DOM element.
|
|
* @param {string} registrationName Name of listener (e.g. `onClick`).
|
|
* @param {?function} listener The callback to store.
|
|
*/
|
|
putListener: function(id, registrationName, listener) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
!listener || typeof listener === 'function',
|
|
'Expected %s listener to be a function, instead got type %s',
|
|
registrationName, typeof listener
|
|
) : invariant(!listener || typeof listener === 'function'));
|
|
|
|
var bankForRegistrationName =
|
|
listenerBank[registrationName] || (listenerBank[registrationName] = {});
|
|
bankForRegistrationName[id] = listener;
|
|
},
|
|
|
|
/**
|
|
* @param {string} id ID of the DOM element.
|
|
* @param {string} registrationName Name of listener (e.g. `onClick`).
|
|
* @return {?function} The stored callback.
|
|
*/
|
|
getListener: function(id, registrationName) {
|
|
var bankForRegistrationName = listenerBank[registrationName];
|
|
return bankForRegistrationName && bankForRegistrationName[id];
|
|
},
|
|
|
|
/**
|
|
* Deletes a listener from the registration bank.
|
|
*
|
|
* @param {string} id ID of the DOM element.
|
|
* @param {string} registrationName Name of listener (e.g. `onClick`).
|
|
*/
|
|
deleteListener: function(id, registrationName) {
|
|
var bankForRegistrationName = listenerBank[registrationName];
|
|
if (bankForRegistrationName) {
|
|
delete bankForRegistrationName[id];
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Deletes all listeners for the DOM element with the supplied ID.
|
|
*
|
|
* @param {string} id ID of the DOM element.
|
|
*/
|
|
deleteAllListeners: function(id) {
|
|
for (var registrationName in listenerBank) {
|
|
delete listenerBank[registrationName][id];
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Allows registered plugins an opportunity to extract events from top-level
|
|
* native browser events.
|
|
*
|
|
* @param {string} topLevelType Record from `EventConstants`.
|
|
* @param {DOMEventTarget} topLevelTarget The listening component root node.
|
|
* @param {string} topLevelTargetID ID of `topLevelTarget`.
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @return {*} An accumulation of synthetic events.
|
|
* @internal
|
|
*/
|
|
extractEvents: function(
|
|
topLevelType,
|
|
topLevelTarget,
|
|
topLevelTargetID,
|
|
nativeEvent) {
|
|
var events;
|
|
var plugins = EventPluginRegistry.plugins;
|
|
for (var i = 0, l = plugins.length; i < l; i++) {
|
|
// Not every plugin in the ordering may be loaded at runtime.
|
|
var possiblePlugin = plugins[i];
|
|
if (possiblePlugin) {
|
|
var extractedEvents = possiblePlugin.extractEvents(
|
|
topLevelType,
|
|
topLevelTarget,
|
|
topLevelTargetID,
|
|
nativeEvent
|
|
);
|
|
if (extractedEvents) {
|
|
events = accumulateInto(events, extractedEvents);
|
|
}
|
|
}
|
|
}
|
|
return events;
|
|
},
|
|
|
|
/**
|
|
* Enqueues a synthetic event that should be dispatched when
|
|
* `processEventQueue` is invoked.
|
|
*
|
|
* @param {*} events An accumulation of synthetic events.
|
|
* @internal
|
|
*/
|
|
enqueueEvents: function(events) {
|
|
if (events) {
|
|
eventQueue = accumulateInto(eventQueue, events);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Dispatches all synthetic events on the event queue.
|
|
*
|
|
* @internal
|
|
*/
|
|
processEventQueue: function() {
|
|
// Set `eventQueue` to null before processing it so that we can tell if more
|
|
// events get enqueued while processing.
|
|
var processingEventQueue = eventQueue;
|
|
eventQueue = null;
|
|
forEachAccumulated(processingEventQueue, executeDispatchesAndRelease);
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
!eventQueue,
|
|
'processEventQueue(): Additional events were enqueued while processing ' +
|
|
'an event queue. Support for this has not yet been implemented.'
|
|
) : invariant(!eventQueue));
|
|
},
|
|
|
|
/**
|
|
* These are needed for tests only. Do not use!
|
|
*/
|
|
__purge: function() {
|
|
listenerBank = {};
|
|
},
|
|
|
|
__getListenerBank: function() {
|
|
return listenerBank;
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = EventPluginHub;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./EventPluginRegistry":67,"./EventPluginUtils":68,"./accumulateInto":155,"./forEachAccumulated":170,"./invariant":185,"_process":1}],67:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule EventPluginRegistry
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var invariant = require("./invariant");
|
|
|
|
/**
|
|
* Injectable ordering of event plugins.
|
|
*/
|
|
var EventPluginOrder = null;
|
|
|
|
/**
|
|
* Injectable mapping from names to event plugin modules.
|
|
*/
|
|
var namesToPlugins = {};
|
|
|
|
/**
|
|
* Recomputes the plugin list using the injected plugins and plugin ordering.
|
|
*
|
|
* @private
|
|
*/
|
|
function recomputePluginOrdering() {
|
|
if (!EventPluginOrder) {
|
|
// Wait until an `EventPluginOrder` is injected.
|
|
return;
|
|
}
|
|
for (var pluginName in namesToPlugins) {
|
|
var PluginModule = namesToPlugins[pluginName];
|
|
var pluginIndex = EventPluginOrder.indexOf(pluginName);
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
pluginIndex > -1,
|
|
'EventPluginRegistry: Cannot inject event plugins that do not exist in ' +
|
|
'the plugin ordering, `%s`.',
|
|
pluginName
|
|
) : invariant(pluginIndex > -1));
|
|
if (EventPluginRegistry.plugins[pluginIndex]) {
|
|
continue;
|
|
}
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
PluginModule.extractEvents,
|
|
'EventPluginRegistry: Event plugins must implement an `extractEvents` ' +
|
|
'method, but `%s` does not.',
|
|
pluginName
|
|
) : invariant(PluginModule.extractEvents));
|
|
EventPluginRegistry.plugins[pluginIndex] = PluginModule;
|
|
var publishedEvents = PluginModule.eventTypes;
|
|
for (var eventName in publishedEvents) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
publishEventForPlugin(
|
|
publishedEvents[eventName],
|
|
PluginModule,
|
|
eventName
|
|
),
|
|
'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.',
|
|
eventName,
|
|
pluginName
|
|
) : invariant(publishEventForPlugin(
|
|
publishedEvents[eventName],
|
|
PluginModule,
|
|
eventName
|
|
)));
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Publishes an event so that it can be dispatched by the supplied plugin.
|
|
*
|
|
* @param {object} dispatchConfig Dispatch configuration for the event.
|
|
* @param {object} PluginModule Plugin publishing the event.
|
|
* @return {boolean} True if the event was successfully published.
|
|
* @private
|
|
*/
|
|
function publishEventForPlugin(dispatchConfig, PluginModule, eventName) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName),
|
|
'EventPluginHub: More than one plugin attempted to publish the same ' +
|
|
'event name, `%s`.',
|
|
eventName
|
|
) : invariant(!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName)));
|
|
EventPluginRegistry.eventNameDispatchConfigs[eventName] = dispatchConfig;
|
|
|
|
var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
|
|
if (phasedRegistrationNames) {
|
|
for (var phaseName in phasedRegistrationNames) {
|
|
if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
|
|
var phasedRegistrationName = phasedRegistrationNames[phaseName];
|
|
publishRegistrationName(
|
|
phasedRegistrationName,
|
|
PluginModule,
|
|
eventName
|
|
);
|
|
}
|
|
}
|
|
return true;
|
|
} else if (dispatchConfig.registrationName) {
|
|
publishRegistrationName(
|
|
dispatchConfig.registrationName,
|
|
PluginModule,
|
|
eventName
|
|
);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Publishes a registration name that is used to identify dispatched events and
|
|
* can be used with `EventPluginHub.putListener` to register listeners.
|
|
*
|
|
* @param {string} registrationName Registration name to add.
|
|
* @param {object} PluginModule Plugin publishing the event.
|
|
* @private
|
|
*/
|
|
function publishRegistrationName(registrationName, PluginModule, eventName) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
!EventPluginRegistry.registrationNameModules[registrationName],
|
|
'EventPluginHub: More than one plugin attempted to publish the same ' +
|
|
'registration name, `%s`.',
|
|
registrationName
|
|
) : invariant(!EventPluginRegistry.registrationNameModules[registrationName]));
|
|
EventPluginRegistry.registrationNameModules[registrationName] = PluginModule;
|
|
EventPluginRegistry.registrationNameDependencies[registrationName] =
|
|
PluginModule.eventTypes[eventName].dependencies;
|
|
}
|
|
|
|
/**
|
|
* Registers plugins so that they can extract and dispatch events.
|
|
*
|
|
* @see {EventPluginHub}
|
|
*/
|
|
var EventPluginRegistry = {
|
|
|
|
/**
|
|
* Ordered list of injected plugins.
|
|
*/
|
|
plugins: [],
|
|
|
|
/**
|
|
* Mapping from event name to dispatch config
|
|
*/
|
|
eventNameDispatchConfigs: {},
|
|
|
|
/**
|
|
* Mapping from registration name to plugin module
|
|
*/
|
|
registrationNameModules: {},
|
|
|
|
/**
|
|
* Mapping from registration name to event name
|
|
*/
|
|
registrationNameDependencies: {},
|
|
|
|
/**
|
|
* Injects an ordering of plugins (by plugin name). This allows the ordering
|
|
* to be decoupled from injection of the actual plugins so that ordering is
|
|
* always deterministic regardless of packaging, on-the-fly injection, etc.
|
|
*
|
|
* @param {array} InjectedEventPluginOrder
|
|
* @internal
|
|
* @see {EventPluginHub.injection.injectEventPluginOrder}
|
|
*/
|
|
injectEventPluginOrder: function(InjectedEventPluginOrder) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
!EventPluginOrder,
|
|
'EventPluginRegistry: Cannot inject event plugin ordering more than ' +
|
|
'once. You are likely trying to load more than one copy of React.'
|
|
) : invariant(!EventPluginOrder));
|
|
// Clone the ordering so it cannot be dynamically mutated.
|
|
EventPluginOrder = Array.prototype.slice.call(InjectedEventPluginOrder);
|
|
recomputePluginOrdering();
|
|
},
|
|
|
|
/**
|
|
* Injects plugins to be used by `EventPluginHub`. The plugin names must be
|
|
* in the ordering injected by `injectEventPluginOrder`.
|
|
*
|
|
* Plugins can be injected as part of page initialization or on-the-fly.
|
|
*
|
|
* @param {object} injectedNamesToPlugins Map from names to plugin modules.
|
|
* @internal
|
|
* @see {EventPluginHub.injection.injectEventPluginsByName}
|
|
*/
|
|
injectEventPluginsByName: function(injectedNamesToPlugins) {
|
|
var isOrderingDirty = false;
|
|
for (var pluginName in injectedNamesToPlugins) {
|
|
if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
|
|
continue;
|
|
}
|
|
var PluginModule = injectedNamesToPlugins[pluginName];
|
|
if (!namesToPlugins.hasOwnProperty(pluginName) ||
|
|
namesToPlugins[pluginName] !== PluginModule) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
!namesToPlugins[pluginName],
|
|
'EventPluginRegistry: Cannot inject two different event plugins ' +
|
|
'using the same name, `%s`.',
|
|
pluginName
|
|
) : invariant(!namesToPlugins[pluginName]));
|
|
namesToPlugins[pluginName] = PluginModule;
|
|
isOrderingDirty = true;
|
|
}
|
|
}
|
|
if (isOrderingDirty) {
|
|
recomputePluginOrdering();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Looks up the plugin for the supplied event.
|
|
*
|
|
* @param {object} event A synthetic event.
|
|
* @return {?object} The plugin that created the supplied event.
|
|
* @internal
|
|
*/
|
|
getPluginModuleForEvent: function(event) {
|
|
var dispatchConfig = event.dispatchConfig;
|
|
if (dispatchConfig.registrationName) {
|
|
return EventPluginRegistry.registrationNameModules[
|
|
dispatchConfig.registrationName
|
|
] || null;
|
|
}
|
|
for (var phase in dispatchConfig.phasedRegistrationNames) {
|
|
if (!dispatchConfig.phasedRegistrationNames.hasOwnProperty(phase)) {
|
|
continue;
|
|
}
|
|
var PluginModule = EventPluginRegistry.registrationNameModules[
|
|
dispatchConfig.phasedRegistrationNames[phase]
|
|
];
|
|
if (PluginModule) {
|
|
return PluginModule;
|
|
}
|
|
}
|
|
return null;
|
|
},
|
|
|
|
/**
|
|
* Exposed for unit testing.
|
|
* @private
|
|
*/
|
|
_resetEventPlugins: function() {
|
|
EventPluginOrder = null;
|
|
for (var pluginName in namesToPlugins) {
|
|
if (namesToPlugins.hasOwnProperty(pluginName)) {
|
|
delete namesToPlugins[pluginName];
|
|
}
|
|
}
|
|
EventPluginRegistry.plugins.length = 0;
|
|
|
|
var eventNameDispatchConfigs = EventPluginRegistry.eventNameDispatchConfigs;
|
|
for (var eventName in eventNameDispatchConfigs) {
|
|
if (eventNameDispatchConfigs.hasOwnProperty(eventName)) {
|
|
delete eventNameDispatchConfigs[eventName];
|
|
}
|
|
}
|
|
|
|
var registrationNameModules = EventPluginRegistry.registrationNameModules;
|
|
for (var registrationName in registrationNameModules) {
|
|
if (registrationNameModules.hasOwnProperty(registrationName)) {
|
|
delete registrationNameModules[registrationName];
|
|
}
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = EventPluginRegistry;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./invariant":185,"_process":1}],68:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule EventPluginUtils
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var EventConstants = require("./EventConstants");
|
|
|
|
var invariant = require("./invariant");
|
|
|
|
/**
|
|
* Injected dependencies:
|
|
*/
|
|
|
|
/**
|
|
* - `Mount`: [required] Module that can convert between React dom IDs and
|
|
* actual node references.
|
|
*/
|
|
var injection = {
|
|
Mount: null,
|
|
injectMount: function(InjectedMount) {
|
|
injection.Mount = InjectedMount;
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
InjectedMount && InjectedMount.getNode,
|
|
'EventPluginUtils.injection.injectMount(...): Injected Mount module ' +
|
|
'is missing getNode.'
|
|
) : invariant(InjectedMount && InjectedMount.getNode));
|
|
}
|
|
}
|
|
};
|
|
|
|
var topLevelTypes = EventConstants.topLevelTypes;
|
|
|
|
function isEndish(topLevelType) {
|
|
return topLevelType === topLevelTypes.topMouseUp ||
|
|
topLevelType === topLevelTypes.topTouchEnd ||
|
|
topLevelType === topLevelTypes.topTouchCancel;
|
|
}
|
|
|
|
function isMoveish(topLevelType) {
|
|
return topLevelType === topLevelTypes.topMouseMove ||
|
|
topLevelType === topLevelTypes.topTouchMove;
|
|
}
|
|
function isStartish(topLevelType) {
|
|
return topLevelType === topLevelTypes.topMouseDown ||
|
|
topLevelType === topLevelTypes.topTouchStart;
|
|
}
|
|
|
|
|
|
var validateEventDispatches;
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
validateEventDispatches = function(event) {
|
|
var dispatchListeners = event._dispatchListeners;
|
|
var dispatchIDs = event._dispatchIDs;
|
|
|
|
var listenersIsArr = Array.isArray(dispatchListeners);
|
|
var idsIsArr = Array.isArray(dispatchIDs);
|
|
var IDsLen = idsIsArr ? dispatchIDs.length : dispatchIDs ? 1 : 0;
|
|
var listenersLen = listenersIsArr ?
|
|
dispatchListeners.length :
|
|
dispatchListeners ? 1 : 0;
|
|
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
idsIsArr === listenersIsArr && IDsLen === listenersLen,
|
|
'EventPluginUtils: Invalid `event`.'
|
|
) : invariant(idsIsArr === listenersIsArr && IDsLen === listenersLen));
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Invokes `cb(event, listener, id)`. Avoids using call if no scope is
|
|
* provided. The `(listener,id)` pair effectively forms the "dispatch" but are
|
|
* kept separate to conserve memory.
|
|
*/
|
|
function forEachEventDispatch(event, cb) {
|
|
var dispatchListeners = event._dispatchListeners;
|
|
var dispatchIDs = event._dispatchIDs;
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
validateEventDispatches(event);
|
|
}
|
|
if (Array.isArray(dispatchListeners)) {
|
|
for (var i = 0; i < dispatchListeners.length; i++) {
|
|
if (event.isPropagationStopped()) {
|
|
break;
|
|
}
|
|
// Listeners and IDs are two parallel arrays that are always in sync.
|
|
cb(event, dispatchListeners[i], dispatchIDs[i]);
|
|
}
|
|
} else if (dispatchListeners) {
|
|
cb(event, dispatchListeners, dispatchIDs);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Default implementation of PluginModule.executeDispatch().
|
|
* @param {SyntheticEvent} SyntheticEvent to handle
|
|
* @param {function} Application-level callback
|
|
* @param {string} domID DOM id to pass to the callback.
|
|
*/
|
|
function executeDispatch(event, listener, domID) {
|
|
event.currentTarget = injection.Mount.getNode(domID);
|
|
var returnValue = listener(event, domID);
|
|
event.currentTarget = null;
|
|
return returnValue;
|
|
}
|
|
|
|
/**
|
|
* Standard/simple iteration through an event's collected dispatches.
|
|
*/
|
|
function executeDispatchesInOrder(event, cb) {
|
|
forEachEventDispatch(event, cb);
|
|
event._dispatchListeners = null;
|
|
event._dispatchIDs = null;
|
|
}
|
|
|
|
/**
|
|
* Standard/simple iteration through an event's collected dispatches, but stops
|
|
* at the first dispatch execution returning true, and returns that id.
|
|
*
|
|
* @return id of the first dispatch execution who's listener returns true, or
|
|
* null if no listener returned true.
|
|
*/
|
|
function executeDispatchesInOrderStopAtTrueImpl(event) {
|
|
var dispatchListeners = event._dispatchListeners;
|
|
var dispatchIDs = event._dispatchIDs;
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
validateEventDispatches(event);
|
|
}
|
|
if (Array.isArray(dispatchListeners)) {
|
|
for (var i = 0; i < dispatchListeners.length; i++) {
|
|
if (event.isPropagationStopped()) {
|
|
break;
|
|
}
|
|
// Listeners and IDs are two parallel arrays that are always in sync.
|
|
if (dispatchListeners[i](event, dispatchIDs[i])) {
|
|
return dispatchIDs[i];
|
|
}
|
|
}
|
|
} else if (dispatchListeners) {
|
|
if (dispatchListeners(event, dispatchIDs)) {
|
|
return dispatchIDs;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @see executeDispatchesInOrderStopAtTrueImpl
|
|
*/
|
|
function executeDispatchesInOrderStopAtTrue(event) {
|
|
var ret = executeDispatchesInOrderStopAtTrueImpl(event);
|
|
event._dispatchIDs = null;
|
|
event._dispatchListeners = null;
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* Execution of a "direct" dispatch - there must be at most one dispatch
|
|
* accumulated on the event or it is considered an error. It doesn't really make
|
|
* sense for an event with multiple dispatches (bubbled) to keep track of the
|
|
* return values at each dispatch execution, but it does tend to make sense when
|
|
* dealing with "direct" dispatches.
|
|
*
|
|
* @return The return value of executing the single dispatch.
|
|
*/
|
|
function executeDirectDispatch(event) {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
validateEventDispatches(event);
|
|
}
|
|
var dispatchListener = event._dispatchListeners;
|
|
var dispatchID = event._dispatchIDs;
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
!Array.isArray(dispatchListener),
|
|
'executeDirectDispatch(...): Invalid `event`.'
|
|
) : invariant(!Array.isArray(dispatchListener)));
|
|
var res = dispatchListener ?
|
|
dispatchListener(event, dispatchID) :
|
|
null;
|
|
event._dispatchListeners = null;
|
|
event._dispatchIDs = null;
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* @param {SyntheticEvent} event
|
|
* @return {bool} True iff number of dispatches accumulated is greater than 0.
|
|
*/
|
|
function hasDispatches(event) {
|
|
return !!event._dispatchListeners;
|
|
}
|
|
|
|
/**
|
|
* General utilities that are useful in creating custom Event Plugins.
|
|
*/
|
|
var EventPluginUtils = {
|
|
isEndish: isEndish,
|
|
isMoveish: isMoveish,
|
|
isStartish: isStartish,
|
|
|
|
executeDirectDispatch: executeDirectDispatch,
|
|
executeDispatch: executeDispatch,
|
|
executeDispatchesInOrder: executeDispatchesInOrder,
|
|
executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue,
|
|
hasDispatches: hasDispatches,
|
|
injection: injection,
|
|
useTouchEvents: false
|
|
};
|
|
|
|
module.exports = EventPluginUtils;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./EventConstants":64,"./invariant":185,"_process":1}],69:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule EventPropagators
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var EventConstants = require("./EventConstants");
|
|
var EventPluginHub = require("./EventPluginHub");
|
|
|
|
var accumulateInto = require("./accumulateInto");
|
|
var forEachAccumulated = require("./forEachAccumulated");
|
|
|
|
var PropagationPhases = EventConstants.PropagationPhases;
|
|
var getListener = EventPluginHub.getListener;
|
|
|
|
/**
|
|
* Some event types have a notion of different registration names for different
|
|
* "phases" of propagation. This finds listeners by a given phase.
|
|
*/
|
|
function listenerAtPhase(id, event, propagationPhase) {
|
|
var registrationName =
|
|
event.dispatchConfig.phasedRegistrationNames[propagationPhase];
|
|
return getListener(id, registrationName);
|
|
}
|
|
|
|
/**
|
|
* Tags a `SyntheticEvent` with dispatched listeners. Creating this function
|
|
* here, allows us to not have to bind or create functions for each event.
|
|
* Mutating the event's members allows us to not have to create a wrapping
|
|
* "dispatch" object that pairs the event with the listener.
|
|
*/
|
|
function accumulateDirectionalDispatches(domID, upwards, event) {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
if (!domID) {
|
|
throw new Error('Dispatching id must not be null');
|
|
}
|
|
}
|
|
var phase = upwards ? PropagationPhases.bubbled : PropagationPhases.captured;
|
|
var listener = listenerAtPhase(domID, event, phase);
|
|
if (listener) {
|
|
event._dispatchListeners =
|
|
accumulateInto(event._dispatchListeners, listener);
|
|
event._dispatchIDs = accumulateInto(event._dispatchIDs, domID);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Collect dispatches (must be entirely collected before dispatching - see unit
|
|
* tests). Lazily allocate the array to conserve memory. We must loop through
|
|
* each event and perform the traversal for each one. We can not perform a
|
|
* single traversal for the entire collection of events because each event may
|
|
* have a different target.
|
|
*/
|
|
function accumulateTwoPhaseDispatchesSingle(event) {
|
|
if (event && event.dispatchConfig.phasedRegistrationNames) {
|
|
EventPluginHub.injection.getInstanceHandle().traverseTwoPhase(
|
|
event.dispatchMarker,
|
|
accumulateDirectionalDispatches,
|
|
event
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Accumulates without regard to direction, does not look for phased
|
|
* registration names. Same as `accumulateDirectDispatchesSingle` but without
|
|
* requiring that the `dispatchMarker` be the same as the dispatched ID.
|
|
*/
|
|
function accumulateDispatches(id, ignoredDirection, event) {
|
|
if (event && event.dispatchConfig.registrationName) {
|
|
var registrationName = event.dispatchConfig.registrationName;
|
|
var listener = getListener(id, registrationName);
|
|
if (listener) {
|
|
event._dispatchListeners =
|
|
accumulateInto(event._dispatchListeners, listener);
|
|
event._dispatchIDs = accumulateInto(event._dispatchIDs, id);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Accumulates dispatches on an `SyntheticEvent`, but only for the
|
|
* `dispatchMarker`.
|
|
* @param {SyntheticEvent} event
|
|
*/
|
|
function accumulateDirectDispatchesSingle(event) {
|
|
if (event && event.dispatchConfig.registrationName) {
|
|
accumulateDispatches(event.dispatchMarker, null, event);
|
|
}
|
|
}
|
|
|
|
function accumulateTwoPhaseDispatches(events) {
|
|
forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
|
|
}
|
|
|
|
function accumulateEnterLeaveDispatches(leave, enter, fromID, toID) {
|
|
EventPluginHub.injection.getInstanceHandle().traverseEnterLeave(
|
|
fromID,
|
|
toID,
|
|
accumulateDispatches,
|
|
leave,
|
|
enter
|
|
);
|
|
}
|
|
|
|
|
|
function accumulateDirectDispatches(events) {
|
|
forEachAccumulated(events, accumulateDirectDispatchesSingle);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* A small set of propagation patterns, each of which will accept a small amount
|
|
* of information, and generate a set of "dispatch ready event objects" - which
|
|
* are sets of events that have already been annotated with a set of dispatched
|
|
* listener functions/ids. The API is designed this way to discourage these
|
|
* propagation strategies from actually executing the dispatches, since we
|
|
* always want to collect the entire set of dispatches before executing event a
|
|
* single one.
|
|
*
|
|
* @constructor EventPropagators
|
|
*/
|
|
var EventPropagators = {
|
|
accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches,
|
|
accumulateDirectDispatches: accumulateDirectDispatches,
|
|
accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches
|
|
};
|
|
|
|
module.exports = EventPropagators;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./EventConstants":64,"./EventPluginHub":66,"./accumulateInto":155,"./forEachAccumulated":170,"_process":1}],70:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ExecutionEnvironment
|
|
*/
|
|
|
|
/*jslint evil: true */
|
|
|
|
"use strict";
|
|
|
|
var canUseDOM = !!(
|
|
(typeof window !== 'undefined' &&
|
|
window.document && window.document.createElement)
|
|
);
|
|
|
|
/**
|
|
* Simple, lightweight module assisting with the detection and context of
|
|
* Worker. Helps avoid circular dependencies and allows code to reason about
|
|
* whether or not they are in a Worker, even if they never include the main
|
|
* `ReactWorker` dependency.
|
|
*/
|
|
var ExecutionEnvironment = {
|
|
|
|
canUseDOM: canUseDOM,
|
|
|
|
canUseWorkers: typeof Worker !== 'undefined',
|
|
|
|
canUseEventListeners:
|
|
canUseDOM && !!(window.addEventListener || window.attachEvent),
|
|
|
|
canUseViewport: canUseDOM && !!window.screen,
|
|
|
|
isInWorker: !canUseDOM // For now, this is true - might change in the future.
|
|
|
|
};
|
|
|
|
module.exports = ExecutionEnvironment;
|
|
|
|
},{}],71:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule FallbackCompositionState
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var PooledClass = require("./PooledClass");
|
|
|
|
var assign = require("./Object.assign");
|
|
var getTextContentAccessor = require("./getTextContentAccessor");
|
|
|
|
/**
|
|
* This helper class stores information about text content of a target node,
|
|
* allowing comparison of content before and after a given event.
|
|
*
|
|
* Identify the node where selection currently begins, then observe
|
|
* both its text content and its current position in the DOM. Since the
|
|
* browser may natively replace the target node during composition, we can
|
|
* use its position to find its replacement.
|
|
*
|
|
* @param {DOMEventTarget} root
|
|
*/
|
|
function FallbackCompositionState(root) {
|
|
this._root = root;
|
|
this._startText = this.getText();
|
|
this._fallbackText = null;
|
|
}
|
|
|
|
assign(FallbackCompositionState.prototype, {
|
|
/**
|
|
* Get current text of input.
|
|
*
|
|
* @return {string}
|
|
*/
|
|
getText: function() {
|
|
if ('value' in this._root) {
|
|
return this._root.value;
|
|
}
|
|
return this._root[getTextContentAccessor()];
|
|
},
|
|
|
|
/**
|
|
* Determine the differing substring between the initially stored
|
|
* text content and the current content.
|
|
*
|
|
* @return {string}
|
|
*/
|
|
getData: function() {
|
|
if (this._fallbackText) {
|
|
return this._fallbackText;
|
|
}
|
|
|
|
var start;
|
|
var startValue = this._startText;
|
|
var startLength = startValue.length;
|
|
var end;
|
|
var endValue = this.getText();
|
|
var endLength = endValue.length;
|
|
|
|
for (start = 0; start < startLength; start++) {
|
|
if (startValue[start] !== endValue[start]) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
var minEnd = startLength - start;
|
|
for (end = 1; end <= minEnd; end++) {
|
|
if (startValue[startLength - end] !== endValue[endLength - end]) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
var sliceTail = end > 1 ? 1 - end : undefined;
|
|
this._fallbackText = endValue.slice(start, sliceTail);
|
|
return this._fallbackText;
|
|
}
|
|
});
|
|
|
|
PooledClass.addPoolingTo(FallbackCompositionState);
|
|
|
|
module.exports = FallbackCompositionState;
|
|
|
|
},{"./Object.assign":76,"./PooledClass":77,"./getTextContentAccessor":180}],72:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule HTMLDOMPropertyConfig
|
|
*/
|
|
|
|
/*jslint bitwise: true*/
|
|
|
|
'use strict';
|
|
|
|
var DOMProperty = require("./DOMProperty");
|
|
var ExecutionEnvironment = require("./ExecutionEnvironment");
|
|
|
|
var MUST_USE_ATTRIBUTE = DOMProperty.injection.MUST_USE_ATTRIBUTE;
|
|
var MUST_USE_PROPERTY = DOMProperty.injection.MUST_USE_PROPERTY;
|
|
var HAS_BOOLEAN_VALUE = DOMProperty.injection.HAS_BOOLEAN_VALUE;
|
|
var HAS_SIDE_EFFECTS = DOMProperty.injection.HAS_SIDE_EFFECTS;
|
|
var HAS_NUMERIC_VALUE = DOMProperty.injection.HAS_NUMERIC_VALUE;
|
|
var HAS_POSITIVE_NUMERIC_VALUE =
|
|
DOMProperty.injection.HAS_POSITIVE_NUMERIC_VALUE;
|
|
var HAS_OVERLOADED_BOOLEAN_VALUE =
|
|
DOMProperty.injection.HAS_OVERLOADED_BOOLEAN_VALUE;
|
|
|
|
var hasSVG;
|
|
if (ExecutionEnvironment.canUseDOM) {
|
|
var implementation = document.implementation;
|
|
hasSVG = (
|
|
implementation &&
|
|
implementation.hasFeature &&
|
|
implementation.hasFeature(
|
|
'http://www.w3.org/TR/SVG11/feature#BasicStructure',
|
|
'1.1'
|
|
)
|
|
);
|
|
}
|
|
|
|
|
|
var HTMLDOMPropertyConfig = {
|
|
isCustomAttribute: RegExp.prototype.test.bind(
|
|
/^(data|aria)-[a-z_][a-z\d_.\-]*$/
|
|
),
|
|
Properties: {
|
|
/**
|
|
* Standard Properties
|
|
*/
|
|
accept: null,
|
|
acceptCharset: null,
|
|
accessKey: null,
|
|
action: null,
|
|
allowFullScreen: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,
|
|
allowTransparency: MUST_USE_ATTRIBUTE,
|
|
alt: null,
|
|
async: HAS_BOOLEAN_VALUE,
|
|
autoComplete: null,
|
|
// autoFocus is polyfilled/normalized by AutoFocusMixin
|
|
// autoFocus: HAS_BOOLEAN_VALUE,
|
|
autoPlay: HAS_BOOLEAN_VALUE,
|
|
cellPadding: null,
|
|
cellSpacing: null,
|
|
charSet: MUST_USE_ATTRIBUTE,
|
|
checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
|
|
classID: MUST_USE_ATTRIBUTE,
|
|
// To set className on SVG elements, it's necessary to use .setAttribute;
|
|
// this works on HTML elements too in all browsers except IE8. Conveniently,
|
|
// IE8 doesn't support SVG and so we can simply use the attribute in
|
|
// browsers that support SVG and the property in browsers that don't,
|
|
// regardless of whether the element is HTML or SVG.
|
|
className: hasSVG ? MUST_USE_ATTRIBUTE : MUST_USE_PROPERTY,
|
|
cols: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE,
|
|
colSpan: null,
|
|
content: null,
|
|
contentEditable: null,
|
|
contextMenu: MUST_USE_ATTRIBUTE,
|
|
controls: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
|
|
coords: null,
|
|
crossOrigin: null,
|
|
data: null, // For `<object />` acts as `src`.
|
|
dateTime: MUST_USE_ATTRIBUTE,
|
|
defer: HAS_BOOLEAN_VALUE,
|
|
dir: null,
|
|
disabled: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,
|
|
download: HAS_OVERLOADED_BOOLEAN_VALUE,
|
|
draggable: null,
|
|
encType: null,
|
|
form: MUST_USE_ATTRIBUTE,
|
|
formAction: MUST_USE_ATTRIBUTE,
|
|
formEncType: MUST_USE_ATTRIBUTE,
|
|
formMethod: MUST_USE_ATTRIBUTE,
|
|
formNoValidate: HAS_BOOLEAN_VALUE,
|
|
formTarget: MUST_USE_ATTRIBUTE,
|
|
frameBorder: MUST_USE_ATTRIBUTE,
|
|
headers: null,
|
|
height: MUST_USE_ATTRIBUTE,
|
|
hidden: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,
|
|
high: null,
|
|
href: null,
|
|
hrefLang: null,
|
|
htmlFor: null,
|
|
httpEquiv: null,
|
|
icon: null,
|
|
id: MUST_USE_PROPERTY,
|
|
label: null,
|
|
lang: null,
|
|
list: MUST_USE_ATTRIBUTE,
|
|
loop: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
|
|
low: null,
|
|
manifest: MUST_USE_ATTRIBUTE,
|
|
marginHeight: null,
|
|
marginWidth: null,
|
|
max: null,
|
|
maxLength: MUST_USE_ATTRIBUTE,
|
|
media: MUST_USE_ATTRIBUTE,
|
|
mediaGroup: null,
|
|
method: null,
|
|
min: null,
|
|
multiple: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
|
|
muted: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
|
|
name: null,
|
|
noValidate: HAS_BOOLEAN_VALUE,
|
|
open: HAS_BOOLEAN_VALUE,
|
|
optimum: null,
|
|
pattern: null,
|
|
placeholder: null,
|
|
poster: null,
|
|
preload: null,
|
|
radioGroup: null,
|
|
readOnly: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
|
|
rel: null,
|
|
required: HAS_BOOLEAN_VALUE,
|
|
role: MUST_USE_ATTRIBUTE,
|
|
rows: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE,
|
|
rowSpan: null,
|
|
sandbox: null,
|
|
scope: null,
|
|
scoped: HAS_BOOLEAN_VALUE,
|
|
scrolling: null,
|
|
seamless: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,
|
|
selected: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
|
|
shape: null,
|
|
size: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE,
|
|
sizes: MUST_USE_ATTRIBUTE,
|
|
span: HAS_POSITIVE_NUMERIC_VALUE,
|
|
spellCheck: null,
|
|
src: null,
|
|
srcDoc: MUST_USE_PROPERTY,
|
|
srcSet: MUST_USE_ATTRIBUTE,
|
|
start: HAS_NUMERIC_VALUE,
|
|
step: null,
|
|
style: null,
|
|
tabIndex: null,
|
|
target: null,
|
|
title: null,
|
|
type: null,
|
|
useMap: null,
|
|
value: MUST_USE_PROPERTY | HAS_SIDE_EFFECTS,
|
|
width: MUST_USE_ATTRIBUTE,
|
|
wmode: MUST_USE_ATTRIBUTE,
|
|
|
|
/**
|
|
* Non-standard Properties
|
|
*/
|
|
// autoCapitalize and autoCorrect are supported in Mobile Safari for
|
|
// keyboard hints.
|
|
autoCapitalize: null,
|
|
autoCorrect: null,
|
|
// itemProp, itemScope, itemType are for
|
|
// Microdata support. See http://schema.org/docs/gs.html
|
|
itemProp: MUST_USE_ATTRIBUTE,
|
|
itemScope: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,
|
|
itemType: MUST_USE_ATTRIBUTE,
|
|
// itemID and itemRef are for Microdata support as well but
|
|
// only specified in the the WHATWG spec document. See
|
|
// https://html.spec.whatwg.org/multipage/microdata.html#microdata-dom-api
|
|
itemID: MUST_USE_ATTRIBUTE,
|
|
itemRef: MUST_USE_ATTRIBUTE,
|
|
// property is supported for OpenGraph in meta tags.
|
|
property: null,
|
|
// IE-only attribute that controls focus behavior
|
|
unselectable: MUST_USE_ATTRIBUTE
|
|
},
|
|
DOMAttributeNames: {
|
|
acceptCharset: 'accept-charset',
|
|
className: 'class',
|
|
htmlFor: 'for',
|
|
httpEquiv: 'http-equiv'
|
|
},
|
|
DOMPropertyNames: {
|
|
autoCapitalize: 'autocapitalize',
|
|
autoComplete: 'autocomplete',
|
|
autoCorrect: 'autocorrect',
|
|
autoFocus: 'autofocus',
|
|
autoPlay: 'autoplay',
|
|
// `encoding` is equivalent to `enctype`, IE8 lacks an `enctype` setter.
|
|
// http://www.w3.org/TR/html5/forms.html#dom-fs-encoding
|
|
encType: 'encoding',
|
|
hrefLang: 'hreflang',
|
|
radioGroup: 'radiogroup',
|
|
spellCheck: 'spellcheck',
|
|
srcDoc: 'srcdoc',
|
|
srcSet: 'srcset'
|
|
}
|
|
};
|
|
|
|
module.exports = HTMLDOMPropertyConfig;
|
|
|
|
},{"./DOMProperty":59,"./ExecutionEnvironment":70}],73:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule LinkedValueUtils
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactPropTypes = require("./ReactPropTypes");
|
|
|
|
var invariant = require("./invariant");
|
|
|
|
var hasReadOnlyValue = {
|
|
'button': true,
|
|
'checkbox': true,
|
|
'image': true,
|
|
'hidden': true,
|
|
'radio': true,
|
|
'reset': true,
|
|
'submit': true
|
|
};
|
|
|
|
function _assertSingleLink(input) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
input.props.checkedLink == null || input.props.valueLink == null,
|
|
'Cannot provide a checkedLink and a valueLink. If you want to use ' +
|
|
'checkedLink, you probably don\'t want to use valueLink and vice versa.'
|
|
) : invariant(input.props.checkedLink == null || input.props.valueLink == null));
|
|
}
|
|
function _assertValueLink(input) {
|
|
_assertSingleLink(input);
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
input.props.value == null && input.props.onChange == null,
|
|
'Cannot provide a valueLink and a value or onChange event. If you want ' +
|
|
'to use value or onChange, you probably don\'t want to use valueLink.'
|
|
) : invariant(input.props.value == null && input.props.onChange == null));
|
|
}
|
|
|
|
function _assertCheckedLink(input) {
|
|
_assertSingleLink(input);
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
input.props.checked == null && input.props.onChange == null,
|
|
'Cannot provide a checkedLink and a checked property or onChange event. ' +
|
|
'If you want to use checked or onChange, you probably don\'t want to ' +
|
|
'use checkedLink'
|
|
) : invariant(input.props.checked == null && input.props.onChange == null));
|
|
}
|
|
|
|
/**
|
|
* @param {SyntheticEvent} e change event to handle
|
|
*/
|
|
function _handleLinkedValueChange(e) {
|
|
/*jshint validthis:true */
|
|
this.props.valueLink.requestChange(e.target.value);
|
|
}
|
|
|
|
/**
|
|
* @param {SyntheticEvent} e change event to handle
|
|
*/
|
|
function _handleLinkedCheckChange(e) {
|
|
/*jshint validthis:true */
|
|
this.props.checkedLink.requestChange(e.target.checked);
|
|
}
|
|
|
|
/**
|
|
* Provide a linked `value` attribute for controlled forms. You should not use
|
|
* this outside of the ReactDOM controlled form components.
|
|
*/
|
|
var LinkedValueUtils = {
|
|
Mixin: {
|
|
propTypes: {
|
|
value: function(props, propName, componentName) {
|
|
if (!props[propName] ||
|
|
hasReadOnlyValue[props.type] ||
|
|
props.onChange ||
|
|
props.readOnly ||
|
|
props.disabled) {
|
|
return null;
|
|
}
|
|
return new Error(
|
|
'You provided a `value` prop to a form field without an ' +
|
|
'`onChange` handler. This will render a read-only field. If ' +
|
|
'the field should be mutable use `defaultValue`. Otherwise, ' +
|
|
'set either `onChange` or `readOnly`.'
|
|
);
|
|
},
|
|
checked: function(props, propName, componentName) {
|
|
if (!props[propName] ||
|
|
props.onChange ||
|
|
props.readOnly ||
|
|
props.disabled) {
|
|
return null;
|
|
}
|
|
return new Error(
|
|
'You provided a `checked` prop to a form field without an ' +
|
|
'`onChange` handler. This will render a read-only field. If ' +
|
|
'the field should be mutable use `defaultChecked`. Otherwise, ' +
|
|
'set either `onChange` or `readOnly`.'
|
|
);
|
|
},
|
|
onChange: ReactPropTypes.func
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @param {ReactComponent} input Form component
|
|
* @return {*} current value of the input either from value prop or link.
|
|
*/
|
|
getValue: function(input) {
|
|
if (input.props.valueLink) {
|
|
_assertValueLink(input);
|
|
return input.props.valueLink.value;
|
|
}
|
|
return input.props.value;
|
|
},
|
|
|
|
/**
|
|
* @param {ReactComponent} input Form component
|
|
* @return {*} current checked status of the input either from checked prop
|
|
* or link.
|
|
*/
|
|
getChecked: function(input) {
|
|
if (input.props.checkedLink) {
|
|
_assertCheckedLink(input);
|
|
return input.props.checkedLink.value;
|
|
}
|
|
return input.props.checked;
|
|
},
|
|
|
|
/**
|
|
* @param {ReactComponent} input Form component
|
|
* @return {function} change callback either from onChange prop or link.
|
|
*/
|
|
getOnChange: function(input) {
|
|
if (input.props.valueLink) {
|
|
_assertValueLink(input);
|
|
return _handleLinkedValueChange;
|
|
} else if (input.props.checkedLink) {
|
|
_assertCheckedLink(input);
|
|
return _handleLinkedCheckChange;
|
|
}
|
|
return input.props.onChange;
|
|
}
|
|
};
|
|
|
|
module.exports = LinkedValueUtils;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./ReactPropTypes":128,"./invariant":185,"_process":1}],74:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2014-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule LocalEventTrapMixin
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter");
|
|
|
|
var accumulateInto = require("./accumulateInto");
|
|
var forEachAccumulated = require("./forEachAccumulated");
|
|
var invariant = require("./invariant");
|
|
|
|
function remove(event) {
|
|
event.remove();
|
|
}
|
|
|
|
var LocalEventTrapMixin = {
|
|
trapBubbledEvent:function(topLevelType, handlerBaseName) {
|
|
("production" !== process.env.NODE_ENV ? invariant(this.isMounted(), 'Must be mounted to trap events') : invariant(this.isMounted()));
|
|
// If a component renders to null or if another component fatals and causes
|
|
// the state of the tree to be corrupted, `node` here can be null.
|
|
var node = this.getDOMNode();
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
node,
|
|
'LocalEventTrapMixin.trapBubbledEvent(...): Requires node to be rendered.'
|
|
) : invariant(node));
|
|
var listener = ReactBrowserEventEmitter.trapBubbledEvent(
|
|
topLevelType,
|
|
handlerBaseName,
|
|
node
|
|
);
|
|
this._localEventListeners =
|
|
accumulateInto(this._localEventListeners, listener);
|
|
},
|
|
|
|
// trapCapturedEvent would look nearly identical. We don't implement that
|
|
// method because it isn't currently needed.
|
|
|
|
componentWillUnmount:function() {
|
|
if (this._localEventListeners) {
|
|
forEachAccumulated(this._localEventListeners, remove);
|
|
}
|
|
}
|
|
};
|
|
|
|
module.exports = LocalEventTrapMixin;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./ReactBrowserEventEmitter":80,"./accumulateInto":155,"./forEachAccumulated":170,"./invariant":185,"_process":1}],75:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule MobileSafariClickEventPlugin
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var EventConstants = require("./EventConstants");
|
|
|
|
var emptyFunction = require("./emptyFunction");
|
|
|
|
var topLevelTypes = EventConstants.topLevelTypes;
|
|
|
|
/**
|
|
* Mobile Safari does not fire properly bubble click events on non-interactive
|
|
* elements, which means delegated click listeners do not fire. The workaround
|
|
* for this bug involves attaching an empty click listener on the target node.
|
|
*
|
|
* This particular plugin works around the bug by attaching an empty click
|
|
* listener on `touchstart` (which does fire on every element).
|
|
*/
|
|
var MobileSafariClickEventPlugin = {
|
|
|
|
eventTypes: null,
|
|
|
|
/**
|
|
* @param {string} topLevelType Record from `EventConstants`.
|
|
* @param {DOMEventTarget} topLevelTarget The listening component root node.
|
|
* @param {string} topLevelTargetID ID of `topLevelTarget`.
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @return {*} An accumulation of synthetic events.
|
|
* @see {EventPluginHub.extractEvents}
|
|
*/
|
|
extractEvents: function(
|
|
topLevelType,
|
|
topLevelTarget,
|
|
topLevelTargetID,
|
|
nativeEvent) {
|
|
if (topLevelType === topLevelTypes.topTouchStart) {
|
|
var target = nativeEvent.target;
|
|
if (target && !target.onclick) {
|
|
target.onclick = emptyFunction;
|
|
}
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = MobileSafariClickEventPlugin;
|
|
|
|
},{"./EventConstants":64,"./emptyFunction":164}],76:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2014-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule Object.assign
|
|
*/
|
|
|
|
// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign
|
|
|
|
'use strict';
|
|
|
|
function assign(target, sources) {
|
|
if (target == null) {
|
|
throw new TypeError('Object.assign target cannot be null or undefined');
|
|
}
|
|
|
|
var to = Object(target);
|
|
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
|
|
for (var nextIndex = 1; nextIndex < arguments.length; nextIndex++) {
|
|
var nextSource = arguments[nextIndex];
|
|
if (nextSource == null) {
|
|
continue;
|
|
}
|
|
|
|
var from = Object(nextSource);
|
|
|
|
// We don't currently support accessors nor proxies. Therefore this
|
|
// copy cannot throw. If we ever supported this then we must handle
|
|
// exceptions and side-effects. We don't support symbols so they won't
|
|
// be transferred.
|
|
|
|
for (var key in from) {
|
|
if (hasOwnProperty.call(from, key)) {
|
|
to[key] = from[key];
|
|
}
|
|
}
|
|
}
|
|
|
|
return to;
|
|
}
|
|
|
|
module.exports = assign;
|
|
|
|
},{}],77:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule PooledClass
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var invariant = require("./invariant");
|
|
|
|
/**
|
|
* Static poolers. Several custom versions for each potential number of
|
|
* arguments. A completely generic pooler is easy to implement, but would
|
|
* require accessing the `arguments` object. In each of these, `this` refers to
|
|
* the Class itself, not an instance. If any others are needed, simply add them
|
|
* here, or in their own files.
|
|
*/
|
|
var oneArgumentPooler = function(copyFieldsFrom) {
|
|
var Klass = this;
|
|
if (Klass.instancePool.length) {
|
|
var instance = Klass.instancePool.pop();
|
|
Klass.call(instance, copyFieldsFrom);
|
|
return instance;
|
|
} else {
|
|
return new Klass(copyFieldsFrom);
|
|
}
|
|
};
|
|
|
|
var twoArgumentPooler = function(a1, a2) {
|
|
var Klass = this;
|
|
if (Klass.instancePool.length) {
|
|
var instance = Klass.instancePool.pop();
|
|
Klass.call(instance, a1, a2);
|
|
return instance;
|
|
} else {
|
|
return new Klass(a1, a2);
|
|
}
|
|
};
|
|
|
|
var threeArgumentPooler = function(a1, a2, a3) {
|
|
var Klass = this;
|
|
if (Klass.instancePool.length) {
|
|
var instance = Klass.instancePool.pop();
|
|
Klass.call(instance, a1, a2, a3);
|
|
return instance;
|
|
} else {
|
|
return new Klass(a1, a2, a3);
|
|
}
|
|
};
|
|
|
|
var fiveArgumentPooler = function(a1, a2, a3, a4, a5) {
|
|
var Klass = this;
|
|
if (Klass.instancePool.length) {
|
|
var instance = Klass.instancePool.pop();
|
|
Klass.call(instance, a1, a2, a3, a4, a5);
|
|
return instance;
|
|
} else {
|
|
return new Klass(a1, a2, a3, a4, a5);
|
|
}
|
|
};
|
|
|
|
var standardReleaser = function(instance) {
|
|
var Klass = this;
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
instance instanceof Klass,
|
|
'Trying to release an instance into a pool of a different type.'
|
|
) : invariant(instance instanceof Klass));
|
|
if (instance.destructor) {
|
|
instance.destructor();
|
|
}
|
|
if (Klass.instancePool.length < Klass.poolSize) {
|
|
Klass.instancePool.push(instance);
|
|
}
|
|
};
|
|
|
|
var DEFAULT_POOL_SIZE = 10;
|
|
var DEFAULT_POOLER = oneArgumentPooler;
|
|
|
|
/**
|
|
* Augments `CopyConstructor` to be a poolable class, augmenting only the class
|
|
* itself (statically) not adding any prototypical fields. Any CopyConstructor
|
|
* you give this may have a `poolSize` property, and will look for a
|
|
* prototypical `destructor` on instances (optional).
|
|
*
|
|
* @param {Function} CopyConstructor Constructor that can be used to reset.
|
|
* @param {Function} pooler Customizable pooler.
|
|
*/
|
|
var addPoolingTo = function(CopyConstructor, pooler) {
|
|
var NewKlass = CopyConstructor;
|
|
NewKlass.instancePool = [];
|
|
NewKlass.getPooled = pooler || DEFAULT_POOLER;
|
|
if (!NewKlass.poolSize) {
|
|
NewKlass.poolSize = DEFAULT_POOL_SIZE;
|
|
}
|
|
NewKlass.release = standardReleaser;
|
|
return NewKlass;
|
|
};
|
|
|
|
var PooledClass = {
|
|
addPoolingTo: addPoolingTo,
|
|
oneArgumentPooler: oneArgumentPooler,
|
|
twoArgumentPooler: twoArgumentPooler,
|
|
threeArgumentPooler: threeArgumentPooler,
|
|
fiveArgumentPooler: fiveArgumentPooler
|
|
};
|
|
|
|
module.exports = PooledClass;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./invariant":185,"_process":1}],78:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule React
|
|
*/
|
|
|
|
/* globals __REACT_DEVTOOLS_GLOBAL_HOOK__*/
|
|
|
|
'use strict';
|
|
|
|
var EventPluginUtils = require("./EventPluginUtils");
|
|
var ReactChildren = require("./ReactChildren");
|
|
var ReactComponent = require("./ReactComponent");
|
|
var ReactClass = require("./ReactClass");
|
|
var ReactContext = require("./ReactContext");
|
|
var ReactCurrentOwner = require("./ReactCurrentOwner");
|
|
var ReactElement = require("./ReactElement");
|
|
var ReactElementValidator = require("./ReactElementValidator");
|
|
var ReactDOM = require("./ReactDOM");
|
|
var ReactDOMTextComponent = require("./ReactDOMTextComponent");
|
|
var ReactDefaultInjection = require("./ReactDefaultInjection");
|
|
var ReactInstanceHandles = require("./ReactInstanceHandles");
|
|
var ReactMount = require("./ReactMount");
|
|
var ReactPerf = require("./ReactPerf");
|
|
var ReactPropTypes = require("./ReactPropTypes");
|
|
var ReactReconciler = require("./ReactReconciler");
|
|
var ReactServerRendering = require("./ReactServerRendering");
|
|
|
|
var assign = require("./Object.assign");
|
|
var findDOMNode = require("./findDOMNode");
|
|
var onlyChild = require("./onlyChild");
|
|
|
|
ReactDefaultInjection.inject();
|
|
|
|
var createElement = ReactElement.createElement;
|
|
var createFactory = ReactElement.createFactory;
|
|
var cloneElement = ReactElement.cloneElement;
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
createElement = ReactElementValidator.createElement;
|
|
createFactory = ReactElementValidator.createFactory;
|
|
cloneElement = ReactElementValidator.cloneElement;
|
|
}
|
|
|
|
var render = ReactPerf.measure('React', 'render', ReactMount.render);
|
|
|
|
var React = {
|
|
Children: {
|
|
map: ReactChildren.map,
|
|
forEach: ReactChildren.forEach,
|
|
count: ReactChildren.count,
|
|
only: onlyChild
|
|
},
|
|
Component: ReactComponent,
|
|
DOM: ReactDOM,
|
|
PropTypes: ReactPropTypes,
|
|
initializeTouchEvents: function(shouldUseTouch) {
|
|
EventPluginUtils.useTouchEvents = shouldUseTouch;
|
|
},
|
|
createClass: ReactClass.createClass,
|
|
createElement: createElement,
|
|
cloneElement: cloneElement,
|
|
createFactory: createFactory,
|
|
createMixin: function(mixin) {
|
|
// Currently a noop. Will be used to validate and trace mixins.
|
|
return mixin;
|
|
},
|
|
constructAndRenderComponent: ReactMount.constructAndRenderComponent,
|
|
constructAndRenderComponentByID: ReactMount.constructAndRenderComponentByID,
|
|
findDOMNode: findDOMNode,
|
|
render: render,
|
|
renderToString: ReactServerRendering.renderToString,
|
|
renderToStaticMarkup: ReactServerRendering.renderToStaticMarkup,
|
|
unmountComponentAtNode: ReactMount.unmountComponentAtNode,
|
|
isValidElement: ReactElement.isValidElement,
|
|
withContext: ReactContext.withContext,
|
|
|
|
// Hook for JSX spread, don't use this for anything else.
|
|
__spread: assign
|
|
};
|
|
|
|
// Inject the runtime into a devtools global hook regardless of browser.
|
|
// Allows for debugging when the hook is injected on the page.
|
|
if (
|
|
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
|
|
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') {
|
|
__REACT_DEVTOOLS_GLOBAL_HOOK__.inject({
|
|
CurrentOwner: ReactCurrentOwner,
|
|
InstanceHandles: ReactInstanceHandles,
|
|
Mount: ReactMount,
|
|
Reconciler: ReactReconciler,
|
|
TextComponent: ReactDOMTextComponent
|
|
});
|
|
}
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
var ExecutionEnvironment = require("./ExecutionEnvironment");
|
|
if (ExecutionEnvironment.canUseDOM && window.top === window.self) {
|
|
|
|
// If we're in Chrome, look for the devtools marker and provide a download
|
|
// link if not installed.
|
|
if (navigator.userAgent.indexOf('Chrome') > -1) {
|
|
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
|
|
console.debug(
|
|
'Download the React DevTools for a better development experience: ' +
|
|
'https://fb.me/react-devtools'
|
|
);
|
|
}
|
|
}
|
|
|
|
var expectedFeatures = [
|
|
// shims
|
|
Array.isArray,
|
|
Array.prototype.every,
|
|
Array.prototype.forEach,
|
|
Array.prototype.indexOf,
|
|
Array.prototype.map,
|
|
Date.now,
|
|
Function.prototype.bind,
|
|
Object.keys,
|
|
String.prototype.split,
|
|
String.prototype.trim,
|
|
|
|
// shams
|
|
Object.create,
|
|
Object.freeze
|
|
];
|
|
|
|
for (var i = 0; i < expectedFeatures.length; i++) {
|
|
if (!expectedFeatures[i]) {
|
|
console.error(
|
|
'One or more ES5 shim/shams expected by React are not available: ' +
|
|
'https://fb.me/react-warning-polyfills'
|
|
);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
React.version = '0.13.3';
|
|
|
|
module.exports = React;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./EventPluginUtils":68,"./ExecutionEnvironment":70,"./Object.assign":76,"./ReactChildren":82,"./ReactClass":83,"./ReactComponent":84,"./ReactContext":88,"./ReactCurrentOwner":89,"./ReactDOM":90,"./ReactDOMTextComponent":101,"./ReactDefaultInjection":104,"./ReactElement":107,"./ReactElementValidator":108,"./ReactInstanceHandles":116,"./ReactMount":120,"./ReactPerf":125,"./ReactPropTypes":128,"./ReactReconciler":131,"./ReactServerRendering":134,"./findDOMNode":167,"./onlyChild":194,"_process":1}],79:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactBrowserComponentMixin
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var findDOMNode = require("./findDOMNode");
|
|
|
|
var ReactBrowserComponentMixin = {
|
|
/**
|
|
* Returns the DOM node rendered by this component.
|
|
*
|
|
* @return {DOMElement} The root node of this component.
|
|
* @final
|
|
* @protected
|
|
*/
|
|
getDOMNode: function() {
|
|
return findDOMNode(this);
|
|
}
|
|
};
|
|
|
|
module.exports = ReactBrowserComponentMixin;
|
|
|
|
},{"./findDOMNode":167}],80:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactBrowserEventEmitter
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var EventConstants = require("./EventConstants");
|
|
var EventPluginHub = require("./EventPluginHub");
|
|
var EventPluginRegistry = require("./EventPluginRegistry");
|
|
var ReactEventEmitterMixin = require("./ReactEventEmitterMixin");
|
|
var ViewportMetrics = require("./ViewportMetrics");
|
|
|
|
var assign = require("./Object.assign");
|
|
var isEventSupported = require("./isEventSupported");
|
|
|
|
/**
|
|
* Summary of `ReactBrowserEventEmitter` event handling:
|
|
*
|
|
* - Top-level delegation is used to trap most native browser events. This
|
|
* may only occur in the main thread and is the responsibility of
|
|
* ReactEventListener, which is injected and can therefore support pluggable
|
|
* event sources. This is the only work that occurs in the main thread.
|
|
*
|
|
* - We normalize and de-duplicate events to account for browser quirks. This
|
|
* may be done in the worker thread.
|
|
*
|
|
* - Forward these native events (with the associated top-level type used to
|
|
* trap it) to `EventPluginHub`, which in turn will ask plugins if they want
|
|
* to extract any synthetic events.
|
|
*
|
|
* - The `EventPluginHub` will then process each event by annotating them with
|
|
* "dispatches", a sequence of listeners and IDs that care about that event.
|
|
*
|
|
* - The `EventPluginHub` then dispatches the events.
|
|
*
|
|
* Overview of React and the event system:
|
|
*
|
|
* +------------+ .
|
|
* | DOM | .
|
|
* +------------+ .
|
|
* | .
|
|
* v .
|
|
* +------------+ .
|
|
* | ReactEvent | .
|
|
* | Listener | .
|
|
* +------------+ . +-----------+
|
|
* | . +--------+|SimpleEvent|
|
|
* | . | |Plugin |
|
|
* +-----|------+ . v +-----------+
|
|
* | | | . +--------------+ +------------+
|
|
* | +-----------.--->|EventPluginHub| | Event |
|
|
* | | . | | +-----------+ | Propagators|
|
|
* | ReactEvent | . | | |TapEvent | |------------|
|
|
* | Emitter | . | |<---+|Plugin | |other plugin|
|
|
* | | . | | +-----------+ | utilities |
|
|
* | +-----------.--->| | +------------+
|
|
* | | | . +--------------+
|
|
* +-----|------+ . ^ +-----------+
|
|
* | . | |Enter/Leave|
|
|
* + . +-------+|Plugin |
|
|
* +-------------+ . +-----------+
|
|
* | application | .
|
|
* |-------------| .
|
|
* | | .
|
|
* | | .
|
|
* +-------------+ .
|
|
* .
|
|
* React Core . General Purpose Event Plugin System
|
|
*/
|
|
|
|
var alreadyListeningTo = {};
|
|
var isMonitoringScrollValue = false;
|
|
var reactTopListenersCounter = 0;
|
|
|
|
// For events like 'submit' which don't consistently bubble (which we trap at a
|
|
// lower node than `document`), binding at `document` would cause duplicate
|
|
// events so we don't include them here
|
|
var topEventMapping = {
|
|
topBlur: 'blur',
|
|
topChange: 'change',
|
|
topClick: 'click',
|
|
topCompositionEnd: 'compositionend',
|
|
topCompositionStart: 'compositionstart',
|
|
topCompositionUpdate: 'compositionupdate',
|
|
topContextMenu: 'contextmenu',
|
|
topCopy: 'copy',
|
|
topCut: 'cut',
|
|
topDoubleClick: 'dblclick',
|
|
topDrag: 'drag',
|
|
topDragEnd: 'dragend',
|
|
topDragEnter: 'dragenter',
|
|
topDragExit: 'dragexit',
|
|
topDragLeave: 'dragleave',
|
|
topDragOver: 'dragover',
|
|
topDragStart: 'dragstart',
|
|
topDrop: 'drop',
|
|
topFocus: 'focus',
|
|
topInput: 'input',
|
|
topKeyDown: 'keydown',
|
|
topKeyPress: 'keypress',
|
|
topKeyUp: 'keyup',
|
|
topMouseDown: 'mousedown',
|
|
topMouseMove: 'mousemove',
|
|
topMouseOut: 'mouseout',
|
|
topMouseOver: 'mouseover',
|
|
topMouseUp: 'mouseup',
|
|
topPaste: 'paste',
|
|
topScroll: 'scroll',
|
|
topSelectionChange: 'selectionchange',
|
|
topTextInput: 'textInput',
|
|
topTouchCancel: 'touchcancel',
|
|
topTouchEnd: 'touchend',
|
|
topTouchMove: 'touchmove',
|
|
topTouchStart: 'touchstart',
|
|
topWheel: 'wheel'
|
|
};
|
|
|
|
/**
|
|
* To ensure no conflicts with other potential React instances on the page
|
|
*/
|
|
var topListenersIDKey = '_reactListenersID' + String(Math.random()).slice(2);
|
|
|
|
function getListeningForDocument(mountAt) {
|
|
// In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty`
|
|
// directly.
|
|
if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) {
|
|
mountAt[topListenersIDKey] = reactTopListenersCounter++;
|
|
alreadyListeningTo[mountAt[topListenersIDKey]] = {};
|
|
}
|
|
return alreadyListeningTo[mountAt[topListenersIDKey]];
|
|
}
|
|
|
|
/**
|
|
* `ReactBrowserEventEmitter` is used to attach top-level event listeners. For
|
|
* example:
|
|
*
|
|
* ReactBrowserEventEmitter.putListener('myID', 'onClick', myFunction);
|
|
*
|
|
* This would allocate a "registration" of `('onClick', myFunction)` on 'myID'.
|
|
*
|
|
* @internal
|
|
*/
|
|
var ReactBrowserEventEmitter = assign({}, ReactEventEmitterMixin, {
|
|
|
|
/**
|
|
* Injectable event backend
|
|
*/
|
|
ReactEventListener: null,
|
|
|
|
injection: {
|
|
/**
|
|
* @param {object} ReactEventListener
|
|
*/
|
|
injectReactEventListener: function(ReactEventListener) {
|
|
ReactEventListener.setHandleTopLevel(
|
|
ReactBrowserEventEmitter.handleTopLevel
|
|
);
|
|
ReactBrowserEventEmitter.ReactEventListener = ReactEventListener;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Sets whether or not any created callbacks should be enabled.
|
|
*
|
|
* @param {boolean} enabled True if callbacks should be enabled.
|
|
*/
|
|
setEnabled: function(enabled) {
|
|
if (ReactBrowserEventEmitter.ReactEventListener) {
|
|
ReactBrowserEventEmitter.ReactEventListener.setEnabled(enabled);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @return {boolean} True if callbacks are enabled.
|
|
*/
|
|
isEnabled: function() {
|
|
return !!(
|
|
(ReactBrowserEventEmitter.ReactEventListener && ReactBrowserEventEmitter.ReactEventListener.isEnabled())
|
|
);
|
|
},
|
|
|
|
/**
|
|
* We listen for bubbled touch events on the document object.
|
|
*
|
|
* Firefox v8.01 (and possibly others) exhibited strange behavior when
|
|
* mounting `onmousemove` events at some node that was not the document
|
|
* element. The symptoms were that if your mouse is not moving over something
|
|
* contained within that mount point (for example on the background) the
|
|
* top-level listeners for `onmousemove` won't be called. However, if you
|
|
* register the `mousemove` on the document object, then it will of course
|
|
* catch all `mousemove`s. This along with iOS quirks, justifies restricting
|
|
* top-level listeners to the document object only, at least for these
|
|
* movement types of events and possibly all events.
|
|
*
|
|
* @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
|
|
*
|
|
* Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
|
|
* they bubble to document.
|
|
*
|
|
* @param {string} registrationName Name of listener (e.g. `onClick`).
|
|
* @param {object} contentDocumentHandle Document which owns the container
|
|
*/
|
|
listenTo: function(registrationName, contentDocumentHandle) {
|
|
var mountAt = contentDocumentHandle;
|
|
var isListening = getListeningForDocument(mountAt);
|
|
var dependencies = EventPluginRegistry.
|
|
registrationNameDependencies[registrationName];
|
|
|
|
var topLevelTypes = EventConstants.topLevelTypes;
|
|
for (var i = 0, l = dependencies.length; i < l; i++) {
|
|
var dependency = dependencies[i];
|
|
if (!(
|
|
(isListening.hasOwnProperty(dependency) && isListening[dependency])
|
|
)) {
|
|
if (dependency === topLevelTypes.topWheel) {
|
|
if (isEventSupported('wheel')) {
|
|
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
|
|
topLevelTypes.topWheel,
|
|
'wheel',
|
|
mountAt
|
|
);
|
|
} else if (isEventSupported('mousewheel')) {
|
|
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
|
|
topLevelTypes.topWheel,
|
|
'mousewheel',
|
|
mountAt
|
|
);
|
|
} else {
|
|
// Firefox needs to capture a different mouse scroll event.
|
|
// @see http://www.quirksmode.org/dom/events/tests/scroll.html
|
|
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
|
|
topLevelTypes.topWheel,
|
|
'DOMMouseScroll',
|
|
mountAt
|
|
);
|
|
}
|
|
} else if (dependency === topLevelTypes.topScroll) {
|
|
|
|
if (isEventSupported('scroll', true)) {
|
|
ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(
|
|
topLevelTypes.topScroll,
|
|
'scroll',
|
|
mountAt
|
|
);
|
|
} else {
|
|
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
|
|
topLevelTypes.topScroll,
|
|
'scroll',
|
|
ReactBrowserEventEmitter.ReactEventListener.WINDOW_HANDLE
|
|
);
|
|
}
|
|
} else if (dependency === topLevelTypes.topFocus ||
|
|
dependency === topLevelTypes.topBlur) {
|
|
|
|
if (isEventSupported('focus', true)) {
|
|
ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(
|
|
topLevelTypes.topFocus,
|
|
'focus',
|
|
mountAt
|
|
);
|
|
ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(
|
|
topLevelTypes.topBlur,
|
|
'blur',
|
|
mountAt
|
|
);
|
|
} else if (isEventSupported('focusin')) {
|
|
// IE has `focusin` and `focusout` events which bubble.
|
|
// @see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
|
|
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
|
|
topLevelTypes.topFocus,
|
|
'focusin',
|
|
mountAt
|
|
);
|
|
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
|
|
topLevelTypes.topBlur,
|
|
'focusout',
|
|
mountAt
|
|
);
|
|
}
|
|
|
|
// to make sure blur and focus event listeners are only attached once
|
|
isListening[topLevelTypes.topBlur] = true;
|
|
isListening[topLevelTypes.topFocus] = true;
|
|
} else if (topEventMapping.hasOwnProperty(dependency)) {
|
|
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
|
|
dependency,
|
|
topEventMapping[dependency],
|
|
mountAt
|
|
);
|
|
}
|
|
|
|
isListening[dependency] = true;
|
|
}
|
|
}
|
|
},
|
|
|
|
trapBubbledEvent: function(topLevelType, handlerBaseName, handle) {
|
|
return ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
|
|
topLevelType,
|
|
handlerBaseName,
|
|
handle
|
|
);
|
|
},
|
|
|
|
trapCapturedEvent: function(topLevelType, handlerBaseName, handle) {
|
|
return ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(
|
|
topLevelType,
|
|
handlerBaseName,
|
|
handle
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Listens to window scroll and resize events. We cache scroll values so that
|
|
* application code can access them without triggering reflows.
|
|
*
|
|
* NOTE: Scroll events do not bubble.
|
|
*
|
|
* @see http://www.quirksmode.org/dom/events/scroll.html
|
|
*/
|
|
ensureScrollValueMonitoring: function() {
|
|
if (!isMonitoringScrollValue) {
|
|
var refresh = ViewportMetrics.refreshScrollValues;
|
|
ReactBrowserEventEmitter.ReactEventListener.monitorScrollValue(refresh);
|
|
isMonitoringScrollValue = true;
|
|
}
|
|
},
|
|
|
|
eventNameDispatchConfigs: EventPluginHub.eventNameDispatchConfigs,
|
|
|
|
registrationNameModules: EventPluginHub.registrationNameModules,
|
|
|
|
putListener: EventPluginHub.putListener,
|
|
|
|
getListener: EventPluginHub.getListener,
|
|
|
|
deleteListener: EventPluginHub.deleteListener,
|
|
|
|
deleteAllListeners: EventPluginHub.deleteAllListeners
|
|
|
|
});
|
|
|
|
module.exports = ReactBrowserEventEmitter;
|
|
|
|
},{"./EventConstants":64,"./EventPluginHub":66,"./EventPluginRegistry":67,"./Object.assign":76,"./ReactEventEmitterMixin":111,"./ViewportMetrics":154,"./isEventSupported":186}],81:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2014-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactChildReconciler
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactReconciler = require("./ReactReconciler");
|
|
|
|
var flattenChildren = require("./flattenChildren");
|
|
var instantiateReactComponent = require("./instantiateReactComponent");
|
|
var shouldUpdateReactComponent = require("./shouldUpdateReactComponent");
|
|
|
|
/**
|
|
* ReactChildReconciler provides helpers for initializing or updating a set of
|
|
* children. Its output is suitable for passing it onto ReactMultiChild which
|
|
* does diffed reordering and insertion.
|
|
*/
|
|
var ReactChildReconciler = {
|
|
|
|
/**
|
|
* Generates a "mount image" for each of the supplied children. In the case
|
|
* of `ReactDOMComponent`, a mount image is a string of markup.
|
|
*
|
|
* @param {?object} nestedChildNodes Nested child maps.
|
|
* @return {?object} A set of child instances.
|
|
* @internal
|
|
*/
|
|
instantiateChildren: function(nestedChildNodes, transaction, context) {
|
|
var children = flattenChildren(nestedChildNodes);
|
|
for (var name in children) {
|
|
if (children.hasOwnProperty(name)) {
|
|
var child = children[name];
|
|
// The rendered children must be turned into instances as they're
|
|
// mounted.
|
|
var childInstance = instantiateReactComponent(child, null);
|
|
children[name] = childInstance;
|
|
}
|
|
}
|
|
return children;
|
|
},
|
|
|
|
/**
|
|
* Updates the rendered children and returns a new set of children.
|
|
*
|
|
* @param {?object} prevChildren Previously initialized set of children.
|
|
* @param {?object} nextNestedChildNodes Nested child maps.
|
|
* @param {ReactReconcileTransaction} transaction
|
|
* @param {object} context
|
|
* @return {?object} A new set of child instances.
|
|
* @internal
|
|
*/
|
|
updateChildren: function(
|
|
prevChildren,
|
|
nextNestedChildNodes,
|
|
transaction,
|
|
context) {
|
|
// We currently don't have a way to track moves here but if we use iterators
|
|
// instead of for..in we can zip the iterators and check if an item has
|
|
// moved.
|
|
// TODO: If nothing has changed, return the prevChildren object so that we
|
|
// can quickly bailout if nothing has changed.
|
|
var nextChildren = flattenChildren(nextNestedChildNodes);
|
|
if (!nextChildren && !prevChildren) {
|
|
return null;
|
|
}
|
|
var name;
|
|
for (name in nextChildren) {
|
|
if (!nextChildren.hasOwnProperty(name)) {
|
|
continue;
|
|
}
|
|
var prevChild = prevChildren && prevChildren[name];
|
|
var prevElement = prevChild && prevChild._currentElement;
|
|
var nextElement = nextChildren[name];
|
|
if (shouldUpdateReactComponent(prevElement, nextElement)) {
|
|
ReactReconciler.receiveComponent(
|
|
prevChild, nextElement, transaction, context
|
|
);
|
|
nextChildren[name] = prevChild;
|
|
} else {
|
|
if (prevChild) {
|
|
ReactReconciler.unmountComponent(prevChild, name);
|
|
}
|
|
// The child must be instantiated before it's mounted.
|
|
var nextChildInstance = instantiateReactComponent(
|
|
nextElement,
|
|
null
|
|
);
|
|
nextChildren[name] = nextChildInstance;
|
|
}
|
|
}
|
|
// Unmount children that are no longer present.
|
|
for (name in prevChildren) {
|
|
if (prevChildren.hasOwnProperty(name) &&
|
|
!(nextChildren && nextChildren.hasOwnProperty(name))) {
|
|
ReactReconciler.unmountComponent(prevChildren[name]);
|
|
}
|
|
}
|
|
return nextChildren;
|
|
},
|
|
|
|
/**
|
|
* Unmounts all rendered children. This should be used to clean up children
|
|
* when this component is unmounted.
|
|
*
|
|
* @param {?object} renderedChildren Previously initialized set of children.
|
|
* @internal
|
|
*/
|
|
unmountChildren: function(renderedChildren) {
|
|
for (var name in renderedChildren) {
|
|
var renderedChild = renderedChildren[name];
|
|
ReactReconciler.unmountComponent(renderedChild);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = ReactChildReconciler;
|
|
|
|
},{"./ReactReconciler":131,"./flattenChildren":168,"./instantiateReactComponent":184,"./shouldUpdateReactComponent":201}],82:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactChildren
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var PooledClass = require("./PooledClass");
|
|
var ReactFragment = require("./ReactFragment");
|
|
|
|
var traverseAllChildren = require("./traverseAllChildren");
|
|
var warning = require("./warning");
|
|
|
|
var twoArgumentPooler = PooledClass.twoArgumentPooler;
|
|
var threeArgumentPooler = PooledClass.threeArgumentPooler;
|
|
|
|
/**
|
|
* PooledClass representing the bookkeeping associated with performing a child
|
|
* traversal. Allows avoiding binding callbacks.
|
|
*
|
|
* @constructor ForEachBookKeeping
|
|
* @param {!function} forEachFunction Function to perform traversal with.
|
|
* @param {?*} forEachContext Context to perform context with.
|
|
*/
|
|
function ForEachBookKeeping(forEachFunction, forEachContext) {
|
|
this.forEachFunction = forEachFunction;
|
|
this.forEachContext = forEachContext;
|
|
}
|
|
PooledClass.addPoolingTo(ForEachBookKeeping, twoArgumentPooler);
|
|
|
|
function forEachSingleChild(traverseContext, child, name, i) {
|
|
var forEachBookKeeping = traverseContext;
|
|
forEachBookKeeping.forEachFunction.call(
|
|
forEachBookKeeping.forEachContext, child, i);
|
|
}
|
|
|
|
/**
|
|
* Iterates through children that are typically specified as `props.children`.
|
|
*
|
|
* The provided forEachFunc(child, index) will be called for each
|
|
* leaf child.
|
|
*
|
|
* @param {?*} children Children tree container.
|
|
* @param {function(*, int)} forEachFunc.
|
|
* @param {*} forEachContext Context for forEachContext.
|
|
*/
|
|
function forEachChildren(children, forEachFunc, forEachContext) {
|
|
if (children == null) {
|
|
return children;
|
|
}
|
|
|
|
var traverseContext =
|
|
ForEachBookKeeping.getPooled(forEachFunc, forEachContext);
|
|
traverseAllChildren(children, forEachSingleChild, traverseContext);
|
|
ForEachBookKeeping.release(traverseContext);
|
|
}
|
|
|
|
/**
|
|
* PooledClass representing the bookkeeping associated with performing a child
|
|
* mapping. Allows avoiding binding callbacks.
|
|
*
|
|
* @constructor MapBookKeeping
|
|
* @param {!*} mapResult Object containing the ordered map of results.
|
|
* @param {!function} mapFunction Function to perform mapping with.
|
|
* @param {?*} mapContext Context to perform mapping with.
|
|
*/
|
|
function MapBookKeeping(mapResult, mapFunction, mapContext) {
|
|
this.mapResult = mapResult;
|
|
this.mapFunction = mapFunction;
|
|
this.mapContext = mapContext;
|
|
}
|
|
PooledClass.addPoolingTo(MapBookKeeping, threeArgumentPooler);
|
|
|
|
function mapSingleChildIntoContext(traverseContext, child, name, i) {
|
|
var mapBookKeeping = traverseContext;
|
|
var mapResult = mapBookKeeping.mapResult;
|
|
|
|
var keyUnique = !mapResult.hasOwnProperty(name);
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
keyUnique,
|
|
'ReactChildren.map(...): Encountered two children with the same key, ' +
|
|
'`%s`. Child keys must be unique; when two children share a key, only ' +
|
|
'the first child will be used.',
|
|
name
|
|
) : null);
|
|
}
|
|
|
|
if (keyUnique) {
|
|
var mappedChild =
|
|
mapBookKeeping.mapFunction.call(mapBookKeeping.mapContext, child, i);
|
|
mapResult[name] = mappedChild;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Maps children that are typically specified as `props.children`.
|
|
*
|
|
* The provided mapFunction(child, key, index) will be called for each
|
|
* leaf child.
|
|
*
|
|
* TODO: This may likely break any calls to `ReactChildren.map` that were
|
|
* previously relying on the fact that we guarded against null children.
|
|
*
|
|
* @param {?*} children Children tree container.
|
|
* @param {function(*, int)} mapFunction.
|
|
* @param {*} mapContext Context for mapFunction.
|
|
* @return {object} Object containing the ordered map of results.
|
|
*/
|
|
function mapChildren(children, func, context) {
|
|
if (children == null) {
|
|
return children;
|
|
}
|
|
|
|
var mapResult = {};
|
|
var traverseContext = MapBookKeeping.getPooled(mapResult, func, context);
|
|
traverseAllChildren(children, mapSingleChildIntoContext, traverseContext);
|
|
MapBookKeeping.release(traverseContext);
|
|
return ReactFragment.create(mapResult);
|
|
}
|
|
|
|
function forEachSingleChildDummy(traverseContext, child, name, i) {
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Count the number of children that are typically specified as
|
|
* `props.children`.
|
|
*
|
|
* @param {?*} children Children tree container.
|
|
* @return {number} The number of children.
|
|
*/
|
|
function countChildren(children, context) {
|
|
return traverseAllChildren(children, forEachSingleChildDummy, null);
|
|
}
|
|
|
|
var ReactChildren = {
|
|
forEach: forEachChildren,
|
|
map: mapChildren,
|
|
count: countChildren
|
|
};
|
|
|
|
module.exports = ReactChildren;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./PooledClass":77,"./ReactFragment":113,"./traverseAllChildren":203,"./warning":204,"_process":1}],83:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactClass
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactComponent = require("./ReactComponent");
|
|
var ReactCurrentOwner = require("./ReactCurrentOwner");
|
|
var ReactElement = require("./ReactElement");
|
|
var ReactErrorUtils = require("./ReactErrorUtils");
|
|
var ReactInstanceMap = require("./ReactInstanceMap");
|
|
var ReactLifeCycle = require("./ReactLifeCycle");
|
|
var ReactPropTypeLocations = require("./ReactPropTypeLocations");
|
|
var ReactPropTypeLocationNames = require("./ReactPropTypeLocationNames");
|
|
var ReactUpdateQueue = require("./ReactUpdateQueue");
|
|
|
|
var assign = require("./Object.assign");
|
|
var invariant = require("./invariant");
|
|
var keyMirror = require("./keyMirror");
|
|
var keyOf = require("./keyOf");
|
|
var warning = require("./warning");
|
|
|
|
var MIXINS_KEY = keyOf({mixins: null});
|
|
|
|
/**
|
|
* Policies that describe methods in `ReactClassInterface`.
|
|
*/
|
|
var SpecPolicy = keyMirror({
|
|
/**
|
|
* These methods may be defined only once by the class specification or mixin.
|
|
*/
|
|
DEFINE_ONCE: null,
|
|
/**
|
|
* These methods may be defined by both the class specification and mixins.
|
|
* Subsequent definitions will be chained. These methods must return void.
|
|
*/
|
|
DEFINE_MANY: null,
|
|
/**
|
|
* These methods are overriding the base class.
|
|
*/
|
|
OVERRIDE_BASE: null,
|
|
/**
|
|
* These methods are similar to DEFINE_MANY, except we assume they return
|
|
* objects. We try to merge the keys of the return values of all the mixed in
|
|
* functions. If there is a key conflict we throw.
|
|
*/
|
|
DEFINE_MANY_MERGED: null
|
|
});
|
|
|
|
|
|
var injectedMixins = [];
|
|
|
|
/**
|
|
* Composite components are higher-level components that compose other composite
|
|
* or native components.
|
|
*
|
|
* To create a new type of `ReactClass`, pass a specification of
|
|
* your new class to `React.createClass`. The only requirement of your class
|
|
* specification is that you implement a `render` method.
|
|
*
|
|
* var MyComponent = React.createClass({
|
|
* render: function() {
|
|
* return <div>Hello World</div>;
|
|
* }
|
|
* });
|
|
*
|
|
* The class specification supports a specific protocol of methods that have
|
|
* special meaning (e.g. `render`). See `ReactClassInterface` for
|
|
* more the comprehensive protocol. Any other properties and methods in the
|
|
* class specification will available on the prototype.
|
|
*
|
|
* @interface ReactClassInterface
|
|
* @internal
|
|
*/
|
|
var ReactClassInterface = {
|
|
|
|
/**
|
|
* An array of Mixin objects to include when defining your component.
|
|
*
|
|
* @type {array}
|
|
* @optional
|
|
*/
|
|
mixins: SpecPolicy.DEFINE_MANY,
|
|
|
|
/**
|
|
* An object containing properties and methods that should be defined on
|
|
* the component's constructor instead of its prototype (static methods).
|
|
*
|
|
* @type {object}
|
|
* @optional
|
|
*/
|
|
statics: SpecPolicy.DEFINE_MANY,
|
|
|
|
/**
|
|
* Definition of prop types for this component.
|
|
*
|
|
* @type {object}
|
|
* @optional
|
|
*/
|
|
propTypes: SpecPolicy.DEFINE_MANY,
|
|
|
|
/**
|
|
* Definition of context types for this component.
|
|
*
|
|
* @type {object}
|
|
* @optional
|
|
*/
|
|
contextTypes: SpecPolicy.DEFINE_MANY,
|
|
|
|
/**
|
|
* Definition of context types this component sets for its children.
|
|
*
|
|
* @type {object}
|
|
* @optional
|
|
*/
|
|
childContextTypes: SpecPolicy.DEFINE_MANY,
|
|
|
|
// ==== Definition methods ====
|
|
|
|
/**
|
|
* Invoked when the component is mounted. Values in the mapping will be set on
|
|
* `this.props` if that prop is not specified (i.e. using an `in` check).
|
|
*
|
|
* This method is invoked before `getInitialState` and therefore cannot rely
|
|
* on `this.state` or use `this.setState`.
|
|
*
|
|
* @return {object}
|
|
* @optional
|
|
*/
|
|
getDefaultProps: SpecPolicy.DEFINE_MANY_MERGED,
|
|
|
|
/**
|
|
* Invoked once before the component is mounted. The return value will be used
|
|
* as the initial value of `this.state`.
|
|
*
|
|
* getInitialState: function() {
|
|
* return {
|
|
* isOn: false,
|
|
* fooBaz: new BazFoo()
|
|
* }
|
|
* }
|
|
*
|
|
* @return {object}
|
|
* @optional
|
|
*/
|
|
getInitialState: SpecPolicy.DEFINE_MANY_MERGED,
|
|
|
|
/**
|
|
* @return {object}
|
|
* @optional
|
|
*/
|
|
getChildContext: SpecPolicy.DEFINE_MANY_MERGED,
|
|
|
|
/**
|
|
* Uses props from `this.props` and state from `this.state` to render the
|
|
* structure of the component.
|
|
*
|
|
* No guarantees are made about when or how often this method is invoked, so
|
|
* it must not have side effects.
|
|
*
|
|
* render: function() {
|
|
* var name = this.props.name;
|
|
* return <div>Hello, {name}!</div>;
|
|
* }
|
|
*
|
|
* @return {ReactComponent}
|
|
* @nosideeffects
|
|
* @required
|
|
*/
|
|
render: SpecPolicy.DEFINE_ONCE,
|
|
|
|
|
|
|
|
// ==== Delegate methods ====
|
|
|
|
/**
|
|
* Invoked when the component is initially created and about to be mounted.
|
|
* This may have side effects, but any external subscriptions or data created
|
|
* by this method must be cleaned up in `componentWillUnmount`.
|
|
*
|
|
* @optional
|
|
*/
|
|
componentWillMount: SpecPolicy.DEFINE_MANY,
|
|
|
|
/**
|
|
* Invoked when the component has been mounted and has a DOM representation.
|
|
* However, there is no guarantee that the DOM node is in the document.
|
|
*
|
|
* Use this as an opportunity to operate on the DOM when the component has
|
|
* been mounted (initialized and rendered) for the first time.
|
|
*
|
|
* @param {DOMElement} rootNode DOM element representing the component.
|
|
* @optional
|
|
*/
|
|
componentDidMount: SpecPolicy.DEFINE_MANY,
|
|
|
|
/**
|
|
* Invoked before the component receives new props.
|
|
*
|
|
* Use this as an opportunity to react to a prop transition by updating the
|
|
* state using `this.setState`. Current props are accessed via `this.props`.
|
|
*
|
|
* componentWillReceiveProps: function(nextProps, nextContext) {
|
|
* this.setState({
|
|
* likesIncreasing: nextProps.likeCount > this.props.likeCount
|
|
* });
|
|
* }
|
|
*
|
|
* NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop
|
|
* transition may cause a state change, but the opposite is not true. If you
|
|
* need it, you are probably looking for `componentWillUpdate`.
|
|
*
|
|
* @param {object} nextProps
|
|
* @optional
|
|
*/
|
|
componentWillReceiveProps: SpecPolicy.DEFINE_MANY,
|
|
|
|
/**
|
|
* Invoked while deciding if the component should be updated as a result of
|
|
* receiving new props, state and/or context.
|
|
*
|
|
* Use this as an opportunity to `return false` when you're certain that the
|
|
* transition to the new props/state/context will not require a component
|
|
* update.
|
|
*
|
|
* shouldComponentUpdate: function(nextProps, nextState, nextContext) {
|
|
* return !equal(nextProps, this.props) ||
|
|
* !equal(nextState, this.state) ||
|
|
* !equal(nextContext, this.context);
|
|
* }
|
|
*
|
|
* @param {object} nextProps
|
|
* @param {?object} nextState
|
|
* @param {?object} nextContext
|
|
* @return {boolean} True if the component should update.
|
|
* @optional
|
|
*/
|
|
shouldComponentUpdate: SpecPolicy.DEFINE_ONCE,
|
|
|
|
/**
|
|
* Invoked when the component is about to update due to a transition from
|
|
* `this.props`, `this.state` and `this.context` to `nextProps`, `nextState`
|
|
* and `nextContext`.
|
|
*
|
|
* Use this as an opportunity to perform preparation before an update occurs.
|
|
*
|
|
* NOTE: You **cannot** use `this.setState()` in this method.
|
|
*
|
|
* @param {object} nextProps
|
|
* @param {?object} nextState
|
|
* @param {?object} nextContext
|
|
* @param {ReactReconcileTransaction} transaction
|
|
* @optional
|
|
*/
|
|
componentWillUpdate: SpecPolicy.DEFINE_MANY,
|
|
|
|
/**
|
|
* Invoked when the component's DOM representation has been updated.
|
|
*
|
|
* Use this as an opportunity to operate on the DOM when the component has
|
|
* been updated.
|
|
*
|
|
* @param {object} prevProps
|
|
* @param {?object} prevState
|
|
* @param {?object} prevContext
|
|
* @param {DOMElement} rootNode DOM element representing the component.
|
|
* @optional
|
|
*/
|
|
componentDidUpdate: SpecPolicy.DEFINE_MANY,
|
|
|
|
/**
|
|
* Invoked when the component is about to be removed from its parent and have
|
|
* its DOM representation destroyed.
|
|
*
|
|
* Use this as an opportunity to deallocate any external resources.
|
|
*
|
|
* NOTE: There is no `componentDidUnmount` since your component will have been
|
|
* destroyed by that point.
|
|
*
|
|
* @optional
|
|
*/
|
|
componentWillUnmount: SpecPolicy.DEFINE_MANY,
|
|
|
|
|
|
|
|
// ==== Advanced methods ====
|
|
|
|
/**
|
|
* Updates the component's currently mounted DOM representation.
|
|
*
|
|
* By default, this implements React's rendering and reconciliation algorithm.
|
|
* Sophisticated clients may wish to override this.
|
|
*
|
|
* @param {ReactReconcileTransaction} transaction
|
|
* @internal
|
|
* @overridable
|
|
*/
|
|
updateComponent: SpecPolicy.OVERRIDE_BASE
|
|
|
|
};
|
|
|
|
/**
|
|
* Mapping from class specification keys to special processing functions.
|
|
*
|
|
* Although these are declared like instance properties in the specification
|
|
* when defining classes using `React.createClass`, they are actually static
|
|
* and are accessible on the constructor instead of the prototype. Despite
|
|
* being static, they must be defined outside of the "statics" key under
|
|
* which all other static methods are defined.
|
|
*/
|
|
var RESERVED_SPEC_KEYS = {
|
|
displayName: function(Constructor, displayName) {
|
|
Constructor.displayName = displayName;
|
|
},
|
|
mixins: function(Constructor, mixins) {
|
|
if (mixins) {
|
|
for (var i = 0; i < mixins.length; i++) {
|
|
mixSpecIntoComponent(Constructor, mixins[i]);
|
|
}
|
|
}
|
|
},
|
|
childContextTypes: function(Constructor, childContextTypes) {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
validateTypeDef(
|
|
Constructor,
|
|
childContextTypes,
|
|
ReactPropTypeLocations.childContext
|
|
);
|
|
}
|
|
Constructor.childContextTypes = assign(
|
|
{},
|
|
Constructor.childContextTypes,
|
|
childContextTypes
|
|
);
|
|
},
|
|
contextTypes: function(Constructor, contextTypes) {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
validateTypeDef(
|
|
Constructor,
|
|
contextTypes,
|
|
ReactPropTypeLocations.context
|
|
);
|
|
}
|
|
Constructor.contextTypes = assign(
|
|
{},
|
|
Constructor.contextTypes,
|
|
contextTypes
|
|
);
|
|
},
|
|
/**
|
|
* Special case getDefaultProps which should move into statics but requires
|
|
* automatic merging.
|
|
*/
|
|
getDefaultProps: function(Constructor, getDefaultProps) {
|
|
if (Constructor.getDefaultProps) {
|
|
Constructor.getDefaultProps = createMergedResultFunction(
|
|
Constructor.getDefaultProps,
|
|
getDefaultProps
|
|
);
|
|
} else {
|
|
Constructor.getDefaultProps = getDefaultProps;
|
|
}
|
|
},
|
|
propTypes: function(Constructor, propTypes) {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
validateTypeDef(
|
|
Constructor,
|
|
propTypes,
|
|
ReactPropTypeLocations.prop
|
|
);
|
|
}
|
|
Constructor.propTypes = assign(
|
|
{},
|
|
Constructor.propTypes,
|
|
propTypes
|
|
);
|
|
},
|
|
statics: function(Constructor, statics) {
|
|
mixStaticSpecIntoComponent(Constructor, statics);
|
|
}
|
|
};
|
|
|
|
function validateTypeDef(Constructor, typeDef, location) {
|
|
for (var propName in typeDef) {
|
|
if (typeDef.hasOwnProperty(propName)) {
|
|
// use a warning instead of an invariant so components
|
|
// don't show up in prod but not in __DEV__
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
typeof typeDef[propName] === 'function',
|
|
'%s: %s type `%s` is invalid; it must be a function, usually from ' +
|
|
'React.PropTypes.',
|
|
Constructor.displayName || 'ReactClass',
|
|
ReactPropTypeLocationNames[location],
|
|
propName
|
|
) : null);
|
|
}
|
|
}
|
|
}
|
|
|
|
function validateMethodOverride(proto, name) {
|
|
var specPolicy = ReactClassInterface.hasOwnProperty(name) ?
|
|
ReactClassInterface[name] :
|
|
null;
|
|
|
|
// Disallow overriding of base class methods unless explicitly allowed.
|
|
if (ReactClassMixin.hasOwnProperty(name)) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
specPolicy === SpecPolicy.OVERRIDE_BASE,
|
|
'ReactClassInterface: You are attempting to override ' +
|
|
'`%s` from your class specification. Ensure that your method names ' +
|
|
'do not overlap with React methods.',
|
|
name
|
|
) : invariant(specPolicy === SpecPolicy.OVERRIDE_BASE));
|
|
}
|
|
|
|
// Disallow defining methods more than once unless explicitly allowed.
|
|
if (proto.hasOwnProperty(name)) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
specPolicy === SpecPolicy.DEFINE_MANY ||
|
|
specPolicy === SpecPolicy.DEFINE_MANY_MERGED,
|
|
'ReactClassInterface: You are attempting to define ' +
|
|
'`%s` on your component more than once. This conflict may be due ' +
|
|
'to a mixin.',
|
|
name
|
|
) : invariant(specPolicy === SpecPolicy.DEFINE_MANY ||
|
|
specPolicy === SpecPolicy.DEFINE_MANY_MERGED));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Mixin helper which handles policy validation and reserved
|
|
* specification keys when building React classses.
|
|
*/
|
|
function mixSpecIntoComponent(Constructor, spec) {
|
|
if (!spec) {
|
|
return;
|
|
}
|
|
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
typeof spec !== 'function',
|
|
'ReactClass: You\'re attempting to ' +
|
|
'use a component class as a mixin. Instead, just use a regular object.'
|
|
) : invariant(typeof spec !== 'function'));
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
!ReactElement.isValidElement(spec),
|
|
'ReactClass: You\'re attempting to ' +
|
|
'use a component as a mixin. Instead, just use a regular object.'
|
|
) : invariant(!ReactElement.isValidElement(spec)));
|
|
|
|
var proto = Constructor.prototype;
|
|
|
|
// By handling mixins before any other properties, we ensure the same
|
|
// chaining order is applied to methods with DEFINE_MANY policy, whether
|
|
// mixins are listed before or after these methods in the spec.
|
|
if (spec.hasOwnProperty(MIXINS_KEY)) {
|
|
RESERVED_SPEC_KEYS.mixins(Constructor, spec.mixins);
|
|
}
|
|
|
|
for (var name in spec) {
|
|
if (!spec.hasOwnProperty(name)) {
|
|
continue;
|
|
}
|
|
|
|
if (name === MIXINS_KEY) {
|
|
// We have already handled mixins in a special case above
|
|
continue;
|
|
}
|
|
|
|
var property = spec[name];
|
|
validateMethodOverride(proto, name);
|
|
|
|
if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) {
|
|
RESERVED_SPEC_KEYS[name](Constructor, property);
|
|
} else {
|
|
// Setup methods on prototype:
|
|
// The following member methods should not be automatically bound:
|
|
// 1. Expected ReactClass methods (in the "interface").
|
|
// 2. Overridden methods (that were mixed in).
|
|
var isReactClassMethod =
|
|
ReactClassInterface.hasOwnProperty(name);
|
|
var isAlreadyDefined = proto.hasOwnProperty(name);
|
|
var markedDontBind = property && property.__reactDontBind;
|
|
var isFunction = typeof property === 'function';
|
|
var shouldAutoBind =
|
|
isFunction &&
|
|
!isReactClassMethod &&
|
|
!isAlreadyDefined &&
|
|
!markedDontBind;
|
|
|
|
if (shouldAutoBind) {
|
|
if (!proto.__reactAutoBindMap) {
|
|
proto.__reactAutoBindMap = {};
|
|
}
|
|
proto.__reactAutoBindMap[name] = property;
|
|
proto[name] = property;
|
|
} else {
|
|
if (isAlreadyDefined) {
|
|
var specPolicy = ReactClassInterface[name];
|
|
|
|
// These cases should already be caught by validateMethodOverride
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
isReactClassMethod && (
|
|
(specPolicy === SpecPolicy.DEFINE_MANY_MERGED || specPolicy === SpecPolicy.DEFINE_MANY)
|
|
),
|
|
'ReactClass: Unexpected spec policy %s for key %s ' +
|
|
'when mixing in component specs.',
|
|
specPolicy,
|
|
name
|
|
) : invariant(isReactClassMethod && (
|
|
(specPolicy === SpecPolicy.DEFINE_MANY_MERGED || specPolicy === SpecPolicy.DEFINE_MANY)
|
|
)));
|
|
|
|
// For methods which are defined more than once, call the existing
|
|
// methods before calling the new property, merging if appropriate.
|
|
if (specPolicy === SpecPolicy.DEFINE_MANY_MERGED) {
|
|
proto[name] = createMergedResultFunction(proto[name], property);
|
|
} else if (specPolicy === SpecPolicy.DEFINE_MANY) {
|
|
proto[name] = createChainedFunction(proto[name], property);
|
|
}
|
|
} else {
|
|
proto[name] = property;
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
// Add verbose displayName to the function, which helps when looking
|
|
// at profiling tools.
|
|
if (typeof property === 'function' && spec.displayName) {
|
|
proto[name].displayName = spec.displayName + '_' + name;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function mixStaticSpecIntoComponent(Constructor, statics) {
|
|
if (!statics) {
|
|
return;
|
|
}
|
|
for (var name in statics) {
|
|
var property = statics[name];
|
|
if (!statics.hasOwnProperty(name)) {
|
|
continue;
|
|
}
|
|
|
|
var isReserved = name in RESERVED_SPEC_KEYS;
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
!isReserved,
|
|
'ReactClass: You are attempting to define a reserved ' +
|
|
'property, `%s`, that shouldn\'t be on the "statics" key. Define it ' +
|
|
'as an instance property instead; it will still be accessible on the ' +
|
|
'constructor.',
|
|
name
|
|
) : invariant(!isReserved));
|
|
|
|
var isInherited = name in Constructor;
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
!isInherited,
|
|
'ReactClass: You are attempting to define ' +
|
|
'`%s` on your component more than once. This conflict may be ' +
|
|
'due to a mixin.',
|
|
name
|
|
) : invariant(!isInherited));
|
|
Constructor[name] = property;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Merge two objects, but throw if both contain the same key.
|
|
*
|
|
* @param {object} one The first object, which is mutated.
|
|
* @param {object} two The second object
|
|
* @return {object} one after it has been mutated to contain everything in two.
|
|
*/
|
|
function mergeIntoWithNoDuplicateKeys(one, two) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
one && two && typeof one === 'object' && typeof two === 'object',
|
|
'mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects.'
|
|
) : invariant(one && two && typeof one === 'object' && typeof two === 'object'));
|
|
|
|
for (var key in two) {
|
|
if (two.hasOwnProperty(key)) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
one[key] === undefined,
|
|
'mergeIntoWithNoDuplicateKeys(): ' +
|
|
'Tried to merge two objects with the same key: `%s`. This conflict ' +
|
|
'may be due to a mixin; in particular, this may be caused by two ' +
|
|
'getInitialState() or getDefaultProps() methods returning objects ' +
|
|
'with clashing keys.',
|
|
key
|
|
) : invariant(one[key] === undefined));
|
|
one[key] = two[key];
|
|
}
|
|
}
|
|
return one;
|
|
}
|
|
|
|
/**
|
|
* Creates a function that invokes two functions and merges their return values.
|
|
*
|
|
* @param {function} one Function to invoke first.
|
|
* @param {function} two Function to invoke second.
|
|
* @return {function} Function that invokes the two argument functions.
|
|
* @private
|
|
*/
|
|
function createMergedResultFunction(one, two) {
|
|
return function mergedResult() {
|
|
var a = one.apply(this, arguments);
|
|
var b = two.apply(this, arguments);
|
|
if (a == null) {
|
|
return b;
|
|
} else if (b == null) {
|
|
return a;
|
|
}
|
|
var c = {};
|
|
mergeIntoWithNoDuplicateKeys(c, a);
|
|
mergeIntoWithNoDuplicateKeys(c, b);
|
|
return c;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function that invokes two functions and ignores their return vales.
|
|
*
|
|
* @param {function} one Function to invoke first.
|
|
* @param {function} two Function to invoke second.
|
|
* @return {function} Function that invokes the two argument functions.
|
|
* @private
|
|
*/
|
|
function createChainedFunction(one, two) {
|
|
return function chainedFunction() {
|
|
one.apply(this, arguments);
|
|
two.apply(this, arguments);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Binds a method to the component.
|
|
*
|
|
* @param {object} component Component whose method is going to be bound.
|
|
* @param {function} method Method to be bound.
|
|
* @return {function} The bound method.
|
|
*/
|
|
function bindAutoBindMethod(component, method) {
|
|
var boundMethod = method.bind(component);
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
boundMethod.__reactBoundContext = component;
|
|
boundMethod.__reactBoundMethod = method;
|
|
boundMethod.__reactBoundArguments = null;
|
|
var componentName = component.constructor.displayName;
|
|
var _bind = boundMethod.bind;
|
|
/* eslint-disable block-scoped-var, no-undef */
|
|
boundMethod.bind = function(newThis ) {for (var args=[],$__0=1,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]);
|
|
// User is trying to bind() an autobound method; we effectively will
|
|
// ignore the value of "this" that the user is trying to use, so
|
|
// let's warn.
|
|
if (newThis !== component && newThis !== null) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
false,
|
|
'bind(): React component methods may only be bound to the ' +
|
|
'component instance. See %s',
|
|
componentName
|
|
) : null);
|
|
} else if (!args.length) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
false,
|
|
'bind(): You are binding a component method to the component. ' +
|
|
'React does this for you automatically in a high-performance ' +
|
|
'way, so you can safely remove this call. See %s',
|
|
componentName
|
|
) : null);
|
|
return boundMethod;
|
|
}
|
|
var reboundMethod = _bind.apply(boundMethod, arguments);
|
|
reboundMethod.__reactBoundContext = component;
|
|
reboundMethod.__reactBoundMethod = method;
|
|
reboundMethod.__reactBoundArguments = args;
|
|
return reboundMethod;
|
|
/* eslint-enable */
|
|
};
|
|
}
|
|
return boundMethod;
|
|
}
|
|
|
|
/**
|
|
* Binds all auto-bound methods in a component.
|
|
*
|
|
* @param {object} component Component whose method is going to be bound.
|
|
*/
|
|
function bindAutoBindMethods(component) {
|
|
for (var autoBindKey in component.__reactAutoBindMap) {
|
|
if (component.__reactAutoBindMap.hasOwnProperty(autoBindKey)) {
|
|
var method = component.__reactAutoBindMap[autoBindKey];
|
|
component[autoBindKey] = bindAutoBindMethod(
|
|
component,
|
|
ReactErrorUtils.guard(
|
|
method,
|
|
component.constructor.displayName + '.' + autoBindKey
|
|
)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
var typeDeprecationDescriptor = {
|
|
enumerable: false,
|
|
get: function() {
|
|
var displayName = this.displayName || this.name || 'Component';
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
false,
|
|
'%s.type is deprecated. Use %s directly to access the class.',
|
|
displayName,
|
|
displayName
|
|
) : null);
|
|
Object.defineProperty(this, 'type', {
|
|
value: this
|
|
});
|
|
return this;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Add more to the ReactClass base class. These are all legacy features and
|
|
* therefore not already part of the modern ReactComponent.
|
|
*/
|
|
var ReactClassMixin = {
|
|
|
|
/**
|
|
* TODO: This will be deprecated because state should always keep a consistent
|
|
* type signature and the only use case for this, is to avoid that.
|
|
*/
|
|
replaceState: function(newState, callback) {
|
|
ReactUpdateQueue.enqueueReplaceState(this, newState);
|
|
if (callback) {
|
|
ReactUpdateQueue.enqueueCallback(this, callback);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Checks whether or not this composite component is mounted.
|
|
* @return {boolean} True if mounted, false otherwise.
|
|
* @protected
|
|
* @final
|
|
*/
|
|
isMounted: function() {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
var owner = ReactCurrentOwner.current;
|
|
if (owner !== null) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
owner._warnedAboutRefsInRender,
|
|
'%s is accessing isMounted inside its render() function. ' +
|
|
'render() should be a pure function of props and state. It should ' +
|
|
'never access something that requires stale data from the previous ' +
|
|
'render, such as refs. Move this logic to componentDidMount and ' +
|
|
'componentDidUpdate instead.',
|
|
owner.getName() || 'A component'
|
|
) : null);
|
|
owner._warnedAboutRefsInRender = true;
|
|
}
|
|
}
|
|
var internalInstance = ReactInstanceMap.get(this);
|
|
return (
|
|
internalInstance &&
|
|
internalInstance !== ReactLifeCycle.currentlyMountingInstance
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Sets a subset of the props.
|
|
*
|
|
* @param {object} partialProps Subset of the next props.
|
|
* @param {?function} callback Called after props are updated.
|
|
* @final
|
|
* @public
|
|
* @deprecated
|
|
*/
|
|
setProps: function(partialProps, callback) {
|
|
ReactUpdateQueue.enqueueSetProps(this, partialProps);
|
|
if (callback) {
|
|
ReactUpdateQueue.enqueueCallback(this, callback);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Replace all the props.
|
|
*
|
|
* @param {object} newProps Subset of the next props.
|
|
* @param {?function} callback Called after props are updated.
|
|
* @final
|
|
* @public
|
|
* @deprecated
|
|
*/
|
|
replaceProps: function(newProps, callback) {
|
|
ReactUpdateQueue.enqueueReplaceProps(this, newProps);
|
|
if (callback) {
|
|
ReactUpdateQueue.enqueueCallback(this, callback);
|
|
}
|
|
}
|
|
};
|
|
|
|
var ReactClassComponent = function() {};
|
|
assign(
|
|
ReactClassComponent.prototype,
|
|
ReactComponent.prototype,
|
|
ReactClassMixin
|
|
);
|
|
|
|
/**
|
|
* Module for creating composite components.
|
|
*
|
|
* @class ReactClass
|
|
*/
|
|
var ReactClass = {
|
|
|
|
/**
|
|
* Creates a composite component class given a class specification.
|
|
*
|
|
* @param {object} spec Class specification (which must define `render`).
|
|
* @return {function} Component constructor function.
|
|
* @public
|
|
*/
|
|
createClass: function(spec) {
|
|
var Constructor = function(props, context) {
|
|
// This constructor is overridden by mocks. The argument is used
|
|
// by mocks to assert on what gets mounted.
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
this instanceof Constructor,
|
|
'Something is calling a React component directly. Use a factory or ' +
|
|
'JSX instead. See: https://fb.me/react-legacyfactory'
|
|
) : null);
|
|
}
|
|
|
|
// Wire up auto-binding
|
|
if (this.__reactAutoBindMap) {
|
|
bindAutoBindMethods(this);
|
|
}
|
|
|
|
this.props = props;
|
|
this.context = context;
|
|
this.state = null;
|
|
|
|
// ReactClasses doesn't have constructors. Instead, they use the
|
|
// getInitialState and componentWillMount methods for initialization.
|
|
|
|
var initialState = this.getInitialState ? this.getInitialState() : null;
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
// We allow auto-mocks to proceed as if they're returning null.
|
|
if (typeof initialState === 'undefined' &&
|
|
this.getInitialState._isMockFunction) {
|
|
// This is probably bad practice. Consider warning here and
|
|
// deprecating this convenience.
|
|
initialState = null;
|
|
}
|
|
}
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
typeof initialState === 'object' && !Array.isArray(initialState),
|
|
'%s.getInitialState(): must return an object or null',
|
|
Constructor.displayName || 'ReactCompositeComponent'
|
|
) : invariant(typeof initialState === 'object' && !Array.isArray(initialState)));
|
|
|
|
this.state = initialState;
|
|
};
|
|
Constructor.prototype = new ReactClassComponent();
|
|
Constructor.prototype.constructor = Constructor;
|
|
|
|
injectedMixins.forEach(
|
|
mixSpecIntoComponent.bind(null, Constructor)
|
|
);
|
|
|
|
mixSpecIntoComponent(Constructor, spec);
|
|
|
|
// Initialize the defaultProps property after all mixins have been merged
|
|
if (Constructor.getDefaultProps) {
|
|
Constructor.defaultProps = Constructor.getDefaultProps();
|
|
}
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
// This is a tag to indicate that the use of these method names is ok,
|
|
// since it's used with createClass. If it's not, then it's likely a
|
|
// mistake so we'll warn you to use the static property, property
|
|
// initializer or constructor respectively.
|
|
if (Constructor.getDefaultProps) {
|
|
Constructor.getDefaultProps.isReactClassApproved = {};
|
|
}
|
|
if (Constructor.prototype.getInitialState) {
|
|
Constructor.prototype.getInitialState.isReactClassApproved = {};
|
|
}
|
|
}
|
|
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
Constructor.prototype.render,
|
|
'createClass(...): Class specification must implement a `render` method.'
|
|
) : invariant(Constructor.prototype.render));
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
!Constructor.prototype.componentShouldUpdate,
|
|
'%s has a method called ' +
|
|
'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' +
|
|
'The name is phrased as a question because the function is ' +
|
|
'expected to return a value.',
|
|
spec.displayName || 'A component'
|
|
) : null);
|
|
}
|
|
|
|
// Reduce time spent doing lookups by setting these on the prototype.
|
|
for (var methodName in ReactClassInterface) {
|
|
if (!Constructor.prototype[methodName]) {
|
|
Constructor.prototype[methodName] = null;
|
|
}
|
|
}
|
|
|
|
// Legacy hook
|
|
Constructor.type = Constructor;
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
try {
|
|
Object.defineProperty(Constructor, 'type', typeDeprecationDescriptor);
|
|
} catch (x) {
|
|
// IE will fail on defineProperty (es5-shim/sham too)
|
|
}
|
|
}
|
|
|
|
return Constructor;
|
|
},
|
|
|
|
injection: {
|
|
injectMixin: function(mixin) {
|
|
injectedMixins.push(mixin);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = ReactClass;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./Object.assign":76,"./ReactComponent":84,"./ReactCurrentOwner":89,"./ReactElement":107,"./ReactErrorUtils":110,"./ReactInstanceMap":117,"./ReactLifeCycle":118,"./ReactPropTypeLocationNames":126,"./ReactPropTypeLocations":127,"./ReactUpdateQueue":136,"./invariant":185,"./keyMirror":190,"./keyOf":191,"./warning":204,"_process":1}],84:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactComponent
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactUpdateQueue = require("./ReactUpdateQueue");
|
|
|
|
var invariant = require("./invariant");
|
|
var warning = require("./warning");
|
|
|
|
/**
|
|
* Base class helpers for the updating state of a component.
|
|
*/
|
|
function ReactComponent(props, context) {
|
|
this.props = props;
|
|
this.context = context;
|
|
}
|
|
|
|
/**
|
|
* Sets a subset of the state. Always use this to mutate
|
|
* state. You should treat `this.state` as immutable.
|
|
*
|
|
* There is no guarantee that `this.state` will be immediately updated, so
|
|
* accessing `this.state` after calling this method may return the old value.
|
|
*
|
|
* There is no guarantee that calls to `setState` will run synchronously,
|
|
* as they may eventually be batched together. You can provide an optional
|
|
* callback that will be executed when the call to setState is actually
|
|
* completed.
|
|
*
|
|
* When a function is provided to setState, it will be called at some point in
|
|
* the future (not synchronously). It will be called with the up to date
|
|
* component arguments (state, props, context). These values can be different
|
|
* from this.* because your function may be called after receiveProps but before
|
|
* shouldComponentUpdate, and this new state, props, and context will not yet be
|
|
* assigned to this.
|
|
*
|
|
* @param {object|function} partialState Next partial state or function to
|
|
* produce next partial state to be merged with current state.
|
|
* @param {?function} callback Called after state is updated.
|
|
* @final
|
|
* @protected
|
|
*/
|
|
ReactComponent.prototype.setState = function(partialState, callback) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
typeof partialState === 'object' ||
|
|
typeof partialState === 'function' ||
|
|
partialState == null,
|
|
'setState(...): takes an object of state variables to update or a ' +
|
|
'function which returns an object of state variables.'
|
|
) : invariant(typeof partialState === 'object' ||
|
|
typeof partialState === 'function' ||
|
|
partialState == null));
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
partialState != null,
|
|
'setState(...): You passed an undefined or null state object; ' +
|
|
'instead, use forceUpdate().'
|
|
) : null);
|
|
}
|
|
ReactUpdateQueue.enqueueSetState(this, partialState);
|
|
if (callback) {
|
|
ReactUpdateQueue.enqueueCallback(this, callback);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Forces an update. This should only be invoked when it is known with
|
|
* certainty that we are **not** in a DOM transaction.
|
|
*
|
|
* You may want to call this when you know that some deeper aspect of the
|
|
* component's state has changed but `setState` was not called.
|
|
*
|
|
* This will not invoke `shouldComponentUpdate`, but it will invoke
|
|
* `componentWillUpdate` and `componentDidUpdate`.
|
|
*
|
|
* @param {?function} callback Called after update is complete.
|
|
* @final
|
|
* @protected
|
|
*/
|
|
ReactComponent.prototype.forceUpdate = function(callback) {
|
|
ReactUpdateQueue.enqueueForceUpdate(this);
|
|
if (callback) {
|
|
ReactUpdateQueue.enqueueCallback(this, callback);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Deprecated APIs. These APIs used to exist on classic React classes but since
|
|
* we would like to deprecate them, we're not going to move them over to this
|
|
* modern base class. Instead, we define a getter that warns if it's accessed.
|
|
*/
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
var deprecatedAPIs = {
|
|
getDOMNode: [
|
|
'getDOMNode',
|
|
'Use React.findDOMNode(component) instead.'
|
|
],
|
|
isMounted: [
|
|
'isMounted',
|
|
'Instead, make sure to clean up subscriptions and pending requests in ' +
|
|
'componentWillUnmount to prevent memory leaks.'
|
|
],
|
|
replaceProps: [
|
|
'replaceProps',
|
|
'Instead, call React.render again at the top level.'
|
|
],
|
|
replaceState: [
|
|
'replaceState',
|
|
'Refactor your code to use setState instead (see ' +
|
|
'https://github.com/facebook/react/issues/3236).'
|
|
],
|
|
setProps: [
|
|
'setProps',
|
|
'Instead, call React.render again at the top level.'
|
|
]
|
|
};
|
|
var defineDeprecationWarning = function(methodName, info) {
|
|
try {
|
|
Object.defineProperty(ReactComponent.prototype, methodName, {
|
|
get: function() {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
false,
|
|
'%s(...) is deprecated in plain JavaScript React classes. %s',
|
|
info[0],
|
|
info[1]
|
|
) : null);
|
|
return undefined;
|
|
}
|
|
});
|
|
} catch (x) {
|
|
// IE will fail on defineProperty (es5-shim/sham too)
|
|
}
|
|
};
|
|
for (var fnName in deprecatedAPIs) {
|
|
if (deprecatedAPIs.hasOwnProperty(fnName)) {
|
|
defineDeprecationWarning(fnName, deprecatedAPIs[fnName]);
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = ReactComponent;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./ReactUpdateQueue":136,"./invariant":185,"./warning":204,"_process":1}],85:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactComponentBrowserEnvironment
|
|
*/
|
|
|
|
/*jslint evil: true */
|
|
|
|
'use strict';
|
|
|
|
var ReactDOMIDOperations = require("./ReactDOMIDOperations");
|
|
var ReactMount = require("./ReactMount");
|
|
|
|
/**
|
|
* Abstracts away all functionality of the reconciler that requires knowledge of
|
|
* the browser context. TODO: These callers should be refactored to avoid the
|
|
* need for this injection.
|
|
*/
|
|
var ReactComponentBrowserEnvironment = {
|
|
|
|
processChildrenUpdates:
|
|
ReactDOMIDOperations.dangerouslyProcessChildrenUpdates,
|
|
|
|
replaceNodeWithMarkupByID:
|
|
ReactDOMIDOperations.dangerouslyReplaceNodeWithMarkupByID,
|
|
|
|
/**
|
|
* If a particular environment requires that some resources be cleaned up,
|
|
* specify this in the injected Mixin. In the DOM, we would likely want to
|
|
* purge any cached node ID lookups.
|
|
*
|
|
* @private
|
|
*/
|
|
unmountIDFromEnvironment: function(rootNodeID) {
|
|
ReactMount.purgeID(rootNodeID);
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = ReactComponentBrowserEnvironment;
|
|
|
|
},{"./ReactDOMIDOperations":94,"./ReactMount":120}],86:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2014-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactComponentEnvironment
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var invariant = require("./invariant");
|
|
|
|
var injected = false;
|
|
|
|
var ReactComponentEnvironment = {
|
|
|
|
/**
|
|
* Optionally injectable environment dependent cleanup hook. (server vs.
|
|
* browser etc). Example: A browser system caches DOM nodes based on component
|
|
* ID and must remove that cache entry when this instance is unmounted.
|
|
*/
|
|
unmountIDFromEnvironment: null,
|
|
|
|
/**
|
|
* Optionally injectable hook for swapping out mount images in the middle of
|
|
* the tree.
|
|
*/
|
|
replaceNodeWithMarkupByID: null,
|
|
|
|
/**
|
|
* Optionally injectable hook for processing a queue of child updates. Will
|
|
* later move into MultiChildComponents.
|
|
*/
|
|
processChildrenUpdates: null,
|
|
|
|
injection: {
|
|
injectEnvironment: function(environment) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
!injected,
|
|
'ReactCompositeComponent: injectEnvironment() can only be called once.'
|
|
) : invariant(!injected));
|
|
ReactComponentEnvironment.unmountIDFromEnvironment =
|
|
environment.unmountIDFromEnvironment;
|
|
ReactComponentEnvironment.replaceNodeWithMarkupByID =
|
|
environment.replaceNodeWithMarkupByID;
|
|
ReactComponentEnvironment.processChildrenUpdates =
|
|
environment.processChildrenUpdates;
|
|
injected = true;
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = ReactComponentEnvironment;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./invariant":185,"_process":1}],87:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactCompositeComponent
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactComponentEnvironment = require("./ReactComponentEnvironment");
|
|
var ReactContext = require("./ReactContext");
|
|
var ReactCurrentOwner = require("./ReactCurrentOwner");
|
|
var ReactElement = require("./ReactElement");
|
|
var ReactElementValidator = require("./ReactElementValidator");
|
|
var ReactInstanceMap = require("./ReactInstanceMap");
|
|
var ReactLifeCycle = require("./ReactLifeCycle");
|
|
var ReactNativeComponent = require("./ReactNativeComponent");
|
|
var ReactPerf = require("./ReactPerf");
|
|
var ReactPropTypeLocations = require("./ReactPropTypeLocations");
|
|
var ReactPropTypeLocationNames = require("./ReactPropTypeLocationNames");
|
|
var ReactReconciler = require("./ReactReconciler");
|
|
var ReactUpdates = require("./ReactUpdates");
|
|
|
|
var assign = require("./Object.assign");
|
|
var emptyObject = require("./emptyObject");
|
|
var invariant = require("./invariant");
|
|
var shouldUpdateReactComponent = require("./shouldUpdateReactComponent");
|
|
var warning = require("./warning");
|
|
|
|
function getDeclarationErrorAddendum(component) {
|
|
var owner = component._currentElement._owner || null;
|
|
if (owner) {
|
|
var name = owner.getName();
|
|
if (name) {
|
|
return ' Check the render method of `' + name + '`.';
|
|
}
|
|
}
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* ------------------ The Life-Cycle of a Composite Component ------------------
|
|
*
|
|
* - constructor: Initialization of state. The instance is now retained.
|
|
* - componentWillMount
|
|
* - render
|
|
* - [children's constructors]
|
|
* - [children's componentWillMount and render]
|
|
* - [children's componentDidMount]
|
|
* - componentDidMount
|
|
*
|
|
* Update Phases:
|
|
* - componentWillReceiveProps (only called if parent updated)
|
|
* - shouldComponentUpdate
|
|
* - componentWillUpdate
|
|
* - render
|
|
* - [children's constructors or receive props phases]
|
|
* - componentDidUpdate
|
|
*
|
|
* - componentWillUnmount
|
|
* - [children's componentWillUnmount]
|
|
* - [children destroyed]
|
|
* - (destroyed): The instance is now blank, released by React and ready for GC.
|
|
*
|
|
* -----------------------------------------------------------------------------
|
|
*/
|
|
|
|
/**
|
|
* An incrementing ID assigned to each component when it is mounted. This is
|
|
* used to enforce the order in which `ReactUpdates` updates dirty components.
|
|
*
|
|
* @private
|
|
*/
|
|
var nextMountID = 1;
|
|
|
|
/**
|
|
* @lends {ReactCompositeComponent.prototype}
|
|
*/
|
|
var ReactCompositeComponentMixin = {
|
|
|
|
/**
|
|
* Base constructor for all composite component.
|
|
*
|
|
* @param {ReactElement} element
|
|
* @final
|
|
* @internal
|
|
*/
|
|
construct: function(element) {
|
|
this._currentElement = element;
|
|
this._rootNodeID = null;
|
|
this._instance = null;
|
|
|
|
// See ReactUpdateQueue
|
|
this._pendingElement = null;
|
|
this._pendingStateQueue = null;
|
|
this._pendingReplaceState = false;
|
|
this._pendingForceUpdate = false;
|
|
|
|
this._renderedComponent = null;
|
|
|
|
this._context = null;
|
|
this._mountOrder = 0;
|
|
this._isTopLevel = false;
|
|
|
|
// See ReactUpdates and ReactUpdateQueue.
|
|
this._pendingCallbacks = null;
|
|
},
|
|
|
|
/**
|
|
* Initializes the component, renders markup, and registers event listeners.
|
|
*
|
|
* @param {string} rootID DOM ID of the root node.
|
|
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
|
|
* @return {?string} Rendered markup to be inserted into the DOM.
|
|
* @final
|
|
* @internal
|
|
*/
|
|
mountComponent: function(rootID, transaction, context) {
|
|
this._context = context;
|
|
this._mountOrder = nextMountID++;
|
|
this._rootNodeID = rootID;
|
|
|
|
var publicProps = this._processProps(this._currentElement.props);
|
|
var publicContext = this._processContext(this._currentElement._context);
|
|
|
|
var Component = ReactNativeComponent.getComponentClassForElement(
|
|
this._currentElement
|
|
);
|
|
|
|
// Initialize the public class
|
|
var inst = new Component(publicProps, publicContext);
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
// This will throw later in _renderValidatedComponent, but add an early
|
|
// warning now to help debugging
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
inst.render != null,
|
|
'%s(...): No `render` method found on the returned component ' +
|
|
'instance: you may have forgotten to define `render` in your ' +
|
|
'component or you may have accidentally tried to render an element ' +
|
|
'whose type is a function that isn\'t a React component.',
|
|
Component.displayName || Component.name || 'Component'
|
|
) : null);
|
|
}
|
|
|
|
// These should be set up in the constructor, but as a convenience for
|
|
// simpler class abstractions, we set them up after the fact.
|
|
inst.props = publicProps;
|
|
inst.context = publicContext;
|
|
inst.refs = emptyObject;
|
|
|
|
this._instance = inst;
|
|
|
|
// Store a reference from the instance back to the internal representation
|
|
ReactInstanceMap.set(inst, this);
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
this._warnIfContextsDiffer(this._currentElement._context, context);
|
|
}
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
// Since plain JS classes are defined without any special initialization
|
|
// logic, we can not catch common errors early. Therefore, we have to
|
|
// catch them here, at initialization time, instead.
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
!inst.getInitialState ||
|
|
inst.getInitialState.isReactClassApproved,
|
|
'getInitialState was defined on %s, a plain JavaScript class. ' +
|
|
'This is only supported for classes created using React.createClass. ' +
|
|
'Did you mean to define a state property instead?',
|
|
this.getName() || 'a component'
|
|
) : null);
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
!inst.getDefaultProps ||
|
|
inst.getDefaultProps.isReactClassApproved,
|
|
'getDefaultProps was defined on %s, a plain JavaScript class. ' +
|
|
'This is only supported for classes created using React.createClass. ' +
|
|
'Use a static property to define defaultProps instead.',
|
|
this.getName() || 'a component'
|
|
) : null);
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
!inst.propTypes,
|
|
'propTypes was defined as an instance property on %s. Use a static ' +
|
|
'property to define propTypes instead.',
|
|
this.getName() || 'a component'
|
|
) : null);
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
!inst.contextTypes,
|
|
'contextTypes was defined as an instance property on %s. Use a ' +
|
|
'static property to define contextTypes instead.',
|
|
this.getName() || 'a component'
|
|
) : null);
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
typeof inst.componentShouldUpdate !== 'function',
|
|
'%s has a method called ' +
|
|
'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' +
|
|
'The name is phrased as a question because the function is ' +
|
|
'expected to return a value.',
|
|
(this.getName() || 'A component')
|
|
) : null);
|
|
}
|
|
|
|
var initialState = inst.state;
|
|
if (initialState === undefined) {
|
|
inst.state = initialState = null;
|
|
}
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
typeof initialState === 'object' && !Array.isArray(initialState),
|
|
'%s.state: must be set to an object or null',
|
|
this.getName() || 'ReactCompositeComponent'
|
|
) : invariant(typeof initialState === 'object' && !Array.isArray(initialState)));
|
|
|
|
this._pendingStateQueue = null;
|
|
this._pendingReplaceState = false;
|
|
this._pendingForceUpdate = false;
|
|
|
|
var childContext;
|
|
var renderedElement;
|
|
|
|
var previouslyMounting = ReactLifeCycle.currentlyMountingInstance;
|
|
ReactLifeCycle.currentlyMountingInstance = this;
|
|
try {
|
|
if (inst.componentWillMount) {
|
|
inst.componentWillMount();
|
|
// When mounting, calls to `setState` by `componentWillMount` will set
|
|
// `this._pendingStateQueue` without triggering a re-render.
|
|
if (this._pendingStateQueue) {
|
|
inst.state = this._processPendingState(inst.props, inst.context);
|
|
}
|
|
}
|
|
|
|
childContext = this._getValidatedChildContext(context);
|
|
renderedElement = this._renderValidatedComponent(childContext);
|
|
} finally {
|
|
ReactLifeCycle.currentlyMountingInstance = previouslyMounting;
|
|
}
|
|
|
|
this._renderedComponent = this._instantiateReactComponent(
|
|
renderedElement,
|
|
this._currentElement.type // The wrapping type
|
|
);
|
|
|
|
var markup = ReactReconciler.mountComponent(
|
|
this._renderedComponent,
|
|
rootID,
|
|
transaction,
|
|
this._mergeChildContext(context, childContext)
|
|
);
|
|
if (inst.componentDidMount) {
|
|
transaction.getReactMountReady().enqueue(inst.componentDidMount, inst);
|
|
}
|
|
|
|
return markup;
|
|
},
|
|
|
|
/**
|
|
* Releases any resources allocated by `mountComponent`.
|
|
*
|
|
* @final
|
|
* @internal
|
|
*/
|
|
unmountComponent: function() {
|
|
var inst = this._instance;
|
|
|
|
if (inst.componentWillUnmount) {
|
|
var previouslyUnmounting = ReactLifeCycle.currentlyUnmountingInstance;
|
|
ReactLifeCycle.currentlyUnmountingInstance = this;
|
|
try {
|
|
inst.componentWillUnmount();
|
|
} finally {
|
|
ReactLifeCycle.currentlyUnmountingInstance = previouslyUnmounting;
|
|
}
|
|
}
|
|
|
|
ReactReconciler.unmountComponent(this._renderedComponent);
|
|
this._renderedComponent = null;
|
|
|
|
// Reset pending fields
|
|
this._pendingStateQueue = null;
|
|
this._pendingReplaceState = false;
|
|
this._pendingForceUpdate = false;
|
|
this._pendingCallbacks = null;
|
|
this._pendingElement = null;
|
|
|
|
// These fields do not really need to be reset since this object is no
|
|
// longer accessible.
|
|
this._context = null;
|
|
this._rootNodeID = null;
|
|
|
|
// Delete the reference from the instance to this internal representation
|
|
// which allow the internals to be properly cleaned up even if the user
|
|
// leaks a reference to the public instance.
|
|
ReactInstanceMap.remove(inst);
|
|
|
|
// Some existing components rely on inst.props even after they've been
|
|
// destroyed (in event handlers).
|
|
// TODO: inst.props = null;
|
|
// TODO: inst.state = null;
|
|
// TODO: inst.context = null;
|
|
},
|
|
|
|
/**
|
|
* Schedule a partial update to the props. Only used for internal testing.
|
|
*
|
|
* @param {object} partialProps Subset of the next props.
|
|
* @param {?function} callback Called after props are updated.
|
|
* @final
|
|
* @internal
|
|
*/
|
|
_setPropsInternal: function(partialProps, callback) {
|
|
// This is a deoptimized path. We optimize for always having an element.
|
|
// This creates an extra internal element.
|
|
var element = this._pendingElement || this._currentElement;
|
|
this._pendingElement = ReactElement.cloneAndReplaceProps(
|
|
element,
|
|
assign({}, element.props, partialProps)
|
|
);
|
|
ReactUpdates.enqueueUpdate(this, callback);
|
|
},
|
|
|
|
/**
|
|
* Filters the context object to only contain keys specified in
|
|
* `contextTypes`
|
|
*
|
|
* @param {object} context
|
|
* @return {?object}
|
|
* @private
|
|
*/
|
|
_maskContext: function(context) {
|
|
var maskedContext = null;
|
|
// This really should be getting the component class for the element,
|
|
// but we know that we're not going to need it for built-ins.
|
|
if (typeof this._currentElement.type === 'string') {
|
|
return emptyObject;
|
|
}
|
|
var contextTypes = this._currentElement.type.contextTypes;
|
|
if (!contextTypes) {
|
|
return emptyObject;
|
|
}
|
|
maskedContext = {};
|
|
for (var contextName in contextTypes) {
|
|
maskedContext[contextName] = context[contextName];
|
|
}
|
|
return maskedContext;
|
|
},
|
|
|
|
/**
|
|
* Filters the context object to only contain keys specified in
|
|
* `contextTypes`, and asserts that they are valid.
|
|
*
|
|
* @param {object} context
|
|
* @return {?object}
|
|
* @private
|
|
*/
|
|
_processContext: function(context) {
|
|
var maskedContext = this._maskContext(context);
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
var Component = ReactNativeComponent.getComponentClassForElement(
|
|
this._currentElement
|
|
);
|
|
if (Component.contextTypes) {
|
|
this._checkPropTypes(
|
|
Component.contextTypes,
|
|
maskedContext,
|
|
ReactPropTypeLocations.context
|
|
);
|
|
}
|
|
}
|
|
return maskedContext;
|
|
},
|
|
|
|
/**
|
|
* @param {object} currentContext
|
|
* @return {object}
|
|
* @private
|
|
*/
|
|
_getValidatedChildContext: function(currentContext) {
|
|
var inst = this._instance;
|
|
var childContext = inst.getChildContext && inst.getChildContext();
|
|
if (childContext) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
typeof inst.constructor.childContextTypes === 'object',
|
|
'%s.getChildContext(): childContextTypes must be defined in order to ' +
|
|
'use getChildContext().',
|
|
this.getName() || 'ReactCompositeComponent'
|
|
) : invariant(typeof inst.constructor.childContextTypes === 'object'));
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
this._checkPropTypes(
|
|
inst.constructor.childContextTypes,
|
|
childContext,
|
|
ReactPropTypeLocations.childContext
|
|
);
|
|
}
|
|
for (var name in childContext) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
name in inst.constructor.childContextTypes,
|
|
'%s.getChildContext(): key "%s" is not defined in childContextTypes.',
|
|
this.getName() || 'ReactCompositeComponent',
|
|
name
|
|
) : invariant(name in inst.constructor.childContextTypes));
|
|
}
|
|
return childContext;
|
|
}
|
|
return null;
|
|
},
|
|
|
|
_mergeChildContext: function(currentContext, childContext) {
|
|
if (childContext) {
|
|
return assign({}, currentContext, childContext);
|
|
}
|
|
return currentContext;
|
|
},
|
|
|
|
/**
|
|
* Processes props by setting default values for unspecified props and
|
|
* asserting that the props are valid. Does not mutate its argument; returns
|
|
* a new props object with defaults merged in.
|
|
*
|
|
* @param {object} newProps
|
|
* @return {object}
|
|
* @private
|
|
*/
|
|
_processProps: function(newProps) {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
var Component = ReactNativeComponent.getComponentClassForElement(
|
|
this._currentElement
|
|
);
|
|
if (Component.propTypes) {
|
|
this._checkPropTypes(
|
|
Component.propTypes,
|
|
newProps,
|
|
ReactPropTypeLocations.prop
|
|
);
|
|
}
|
|
}
|
|
return newProps;
|
|
},
|
|
|
|
/**
|
|
* Assert that the props are valid
|
|
*
|
|
* @param {object} propTypes Map of prop name to a ReactPropType
|
|
* @param {object} props
|
|
* @param {string} location e.g. "prop", "context", "child context"
|
|
* @private
|
|
*/
|
|
_checkPropTypes: function(propTypes, props, location) {
|
|
// TODO: Stop validating prop types here and only use the element
|
|
// validation.
|
|
var componentName = this.getName();
|
|
for (var propName in propTypes) {
|
|
if (propTypes.hasOwnProperty(propName)) {
|
|
var error;
|
|
try {
|
|
// This is intentionally an invariant that gets caught. It's the same
|
|
// behavior as without this statement except with a better message.
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
typeof propTypes[propName] === 'function',
|
|
'%s: %s type `%s` is invalid; it must be a function, usually ' +
|
|
'from React.PropTypes.',
|
|
componentName || 'React class',
|
|
ReactPropTypeLocationNames[location],
|
|
propName
|
|
) : invariant(typeof propTypes[propName] === 'function'));
|
|
error = propTypes[propName](props, propName, componentName, location);
|
|
} catch (ex) {
|
|
error = ex;
|
|
}
|
|
if (error instanceof Error) {
|
|
// We may want to extend this logic for similar errors in
|
|
// React.render calls, so I'm abstracting it away into
|
|
// a function to minimize refactoring in the future
|
|
var addendum = getDeclarationErrorAddendum(this);
|
|
|
|
if (location === ReactPropTypeLocations.prop) {
|
|
// Preface gives us something to blacklist in warning module
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
false,
|
|
'Failed Composite propType: %s%s',
|
|
error.message,
|
|
addendum
|
|
) : null);
|
|
} else {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
false,
|
|
'Failed Context Types: %s%s',
|
|
error.message,
|
|
addendum
|
|
) : null);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
receiveComponent: function(nextElement, transaction, nextContext) {
|
|
var prevElement = this._currentElement;
|
|
var prevContext = this._context;
|
|
|
|
this._pendingElement = null;
|
|
|
|
this.updateComponent(
|
|
transaction,
|
|
prevElement,
|
|
nextElement,
|
|
prevContext,
|
|
nextContext
|
|
);
|
|
},
|
|
|
|
/**
|
|
* If any of `_pendingElement`, `_pendingStateQueue`, or `_pendingForceUpdate`
|
|
* is set, update the component.
|
|
*
|
|
* @param {ReactReconcileTransaction} transaction
|
|
* @internal
|
|
*/
|
|
performUpdateIfNecessary: function(transaction) {
|
|
if (this._pendingElement != null) {
|
|
ReactReconciler.receiveComponent(
|
|
this,
|
|
this._pendingElement || this._currentElement,
|
|
transaction,
|
|
this._context
|
|
);
|
|
}
|
|
|
|
if (this._pendingStateQueue !== null || this._pendingForceUpdate) {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
ReactElementValidator.checkAndWarnForMutatedProps(
|
|
this._currentElement
|
|
);
|
|
}
|
|
|
|
this.updateComponent(
|
|
transaction,
|
|
this._currentElement,
|
|
this._currentElement,
|
|
this._context,
|
|
this._context
|
|
);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Compare two contexts, warning if they are different
|
|
* TODO: Remove this check when owner-context is removed
|
|
*/
|
|
_warnIfContextsDiffer: function(ownerBasedContext, parentBasedContext) {
|
|
ownerBasedContext = this._maskContext(ownerBasedContext);
|
|
parentBasedContext = this._maskContext(parentBasedContext);
|
|
var parentKeys = Object.keys(parentBasedContext).sort();
|
|
var displayName = this.getName() || 'ReactCompositeComponent';
|
|
for (var i = 0; i < parentKeys.length; i++) {
|
|
var key = parentKeys[i];
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
ownerBasedContext[key] === parentBasedContext[key],
|
|
'owner-based and parent-based contexts differ ' +
|
|
'(values: `%s` vs `%s`) for key (%s) while mounting %s ' +
|
|
'(see: http://fb.me/react-context-by-parent)',
|
|
ownerBasedContext[key],
|
|
parentBasedContext[key],
|
|
key,
|
|
displayName
|
|
) : null);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Perform an update to a mounted component. The componentWillReceiveProps and
|
|
* shouldComponentUpdate methods are called, then (assuming the update isn't
|
|
* skipped) the remaining update lifecycle methods are called and the DOM
|
|
* representation is updated.
|
|
*
|
|
* By default, this implements React's rendering and reconciliation algorithm.
|
|
* Sophisticated clients may wish to override this.
|
|
*
|
|
* @param {ReactReconcileTransaction} transaction
|
|
* @param {ReactElement} prevParentElement
|
|
* @param {ReactElement} nextParentElement
|
|
* @internal
|
|
* @overridable
|
|
*/
|
|
updateComponent: function(
|
|
transaction,
|
|
prevParentElement,
|
|
nextParentElement,
|
|
prevUnmaskedContext,
|
|
nextUnmaskedContext
|
|
) {
|
|
var inst = this._instance;
|
|
|
|
var nextContext = inst.context;
|
|
var nextProps = inst.props;
|
|
|
|
// Distinguish between a props update versus a simple state update
|
|
if (prevParentElement !== nextParentElement) {
|
|
nextContext = this._processContext(nextParentElement._context);
|
|
nextProps = this._processProps(nextParentElement.props);
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
if (nextUnmaskedContext != null) {
|
|
this._warnIfContextsDiffer(
|
|
nextParentElement._context,
|
|
nextUnmaskedContext
|
|
);
|
|
}
|
|
}
|
|
|
|
// An update here will schedule an update but immediately set
|
|
// _pendingStateQueue which will ensure that any state updates gets
|
|
// immediately reconciled instead of waiting for the next batch.
|
|
|
|
if (inst.componentWillReceiveProps) {
|
|
inst.componentWillReceiveProps(nextProps, nextContext);
|
|
}
|
|
}
|
|
|
|
var nextState = this._processPendingState(nextProps, nextContext);
|
|
|
|
var shouldUpdate =
|
|
this._pendingForceUpdate ||
|
|
!inst.shouldComponentUpdate ||
|
|
inst.shouldComponentUpdate(nextProps, nextState, nextContext);
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
typeof shouldUpdate !== 'undefined',
|
|
'%s.shouldComponentUpdate(): Returned undefined instead of a ' +
|
|
'boolean value. Make sure to return true or false.',
|
|
this.getName() || 'ReactCompositeComponent'
|
|
) : null);
|
|
}
|
|
|
|
if (shouldUpdate) {
|
|
this._pendingForceUpdate = false;
|
|
// Will set `this.props`, `this.state` and `this.context`.
|
|
this._performComponentUpdate(
|
|
nextParentElement,
|
|
nextProps,
|
|
nextState,
|
|
nextContext,
|
|
transaction,
|
|
nextUnmaskedContext
|
|
);
|
|
} else {
|
|
// If it's determined that a component should not update, we still want
|
|
// to set props and state but we shortcut the rest of the update.
|
|
this._currentElement = nextParentElement;
|
|
this._context = nextUnmaskedContext;
|
|
inst.props = nextProps;
|
|
inst.state = nextState;
|
|
inst.context = nextContext;
|
|
}
|
|
},
|
|
|
|
_processPendingState: function(props, context) {
|
|
var inst = this._instance;
|
|
var queue = this._pendingStateQueue;
|
|
var replace = this._pendingReplaceState;
|
|
this._pendingReplaceState = false;
|
|
this._pendingStateQueue = null;
|
|
|
|
if (!queue) {
|
|
return inst.state;
|
|
}
|
|
|
|
if (replace && queue.length === 1) {
|
|
return queue[0];
|
|
}
|
|
|
|
var nextState = assign({}, replace ? queue[0] : inst.state);
|
|
for (var i = replace ? 1 : 0; i < queue.length; i++) {
|
|
var partial = queue[i];
|
|
assign(
|
|
nextState,
|
|
typeof partial === 'function' ?
|
|
partial.call(inst, nextState, props, context) :
|
|
partial
|
|
);
|
|
}
|
|
|
|
return nextState;
|
|
},
|
|
|
|
/**
|
|
* Merges new props and state, notifies delegate methods of update and
|
|
* performs update.
|
|
*
|
|
* @param {ReactElement} nextElement Next element
|
|
* @param {object} nextProps Next public object to set as properties.
|
|
* @param {?object} nextState Next object to set as state.
|
|
* @param {?object} nextContext Next public object to set as context.
|
|
* @param {ReactReconcileTransaction} transaction
|
|
* @param {?object} unmaskedContext
|
|
* @private
|
|
*/
|
|
_performComponentUpdate: function(
|
|
nextElement,
|
|
nextProps,
|
|
nextState,
|
|
nextContext,
|
|
transaction,
|
|
unmaskedContext
|
|
) {
|
|
var inst = this._instance;
|
|
|
|
var prevProps = inst.props;
|
|
var prevState = inst.state;
|
|
var prevContext = inst.context;
|
|
|
|
if (inst.componentWillUpdate) {
|
|
inst.componentWillUpdate(nextProps, nextState, nextContext);
|
|
}
|
|
|
|
this._currentElement = nextElement;
|
|
this._context = unmaskedContext;
|
|
inst.props = nextProps;
|
|
inst.state = nextState;
|
|
inst.context = nextContext;
|
|
|
|
this._updateRenderedComponent(transaction, unmaskedContext);
|
|
|
|
if (inst.componentDidUpdate) {
|
|
transaction.getReactMountReady().enqueue(
|
|
inst.componentDidUpdate.bind(inst, prevProps, prevState, prevContext),
|
|
inst
|
|
);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Call the component's `render` method and update the DOM accordingly.
|
|
*
|
|
* @param {ReactReconcileTransaction} transaction
|
|
* @internal
|
|
*/
|
|
_updateRenderedComponent: function(transaction, context) {
|
|
var prevComponentInstance = this._renderedComponent;
|
|
var prevRenderedElement = prevComponentInstance._currentElement;
|
|
var childContext = this._getValidatedChildContext();
|
|
var nextRenderedElement = this._renderValidatedComponent(childContext);
|
|
if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) {
|
|
ReactReconciler.receiveComponent(
|
|
prevComponentInstance,
|
|
nextRenderedElement,
|
|
transaction,
|
|
this._mergeChildContext(context, childContext)
|
|
);
|
|
} else {
|
|
// These two IDs are actually the same! But nothing should rely on that.
|
|
var thisID = this._rootNodeID;
|
|
var prevComponentID = prevComponentInstance._rootNodeID;
|
|
ReactReconciler.unmountComponent(prevComponentInstance);
|
|
|
|
this._renderedComponent = this._instantiateReactComponent(
|
|
nextRenderedElement,
|
|
this._currentElement.type
|
|
);
|
|
var nextMarkup = ReactReconciler.mountComponent(
|
|
this._renderedComponent,
|
|
thisID,
|
|
transaction,
|
|
this._mergeChildContext(context, childContext)
|
|
);
|
|
this._replaceNodeWithMarkupByID(prevComponentID, nextMarkup);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @protected
|
|
*/
|
|
_replaceNodeWithMarkupByID: function(prevComponentID, nextMarkup) {
|
|
ReactComponentEnvironment.replaceNodeWithMarkupByID(
|
|
prevComponentID,
|
|
nextMarkup
|
|
);
|
|
},
|
|
|
|
/**
|
|
* @protected
|
|
*/
|
|
_renderValidatedComponentWithoutOwnerOrContext: function() {
|
|
var inst = this._instance;
|
|
var renderedComponent = inst.render();
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
// We allow auto-mocks to proceed as if they're returning null.
|
|
if (typeof renderedComponent === 'undefined' &&
|
|
inst.render._isMockFunction) {
|
|
// This is probably bad practice. Consider warning here and
|
|
// deprecating this convenience.
|
|
renderedComponent = null;
|
|
}
|
|
}
|
|
|
|
return renderedComponent;
|
|
},
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
_renderValidatedComponent: function(childContext) {
|
|
var renderedComponent;
|
|
var previousContext = ReactContext.current;
|
|
ReactContext.current = this._mergeChildContext(
|
|
this._currentElement._context,
|
|
childContext
|
|
);
|
|
ReactCurrentOwner.current = this;
|
|
try {
|
|
renderedComponent =
|
|
this._renderValidatedComponentWithoutOwnerOrContext();
|
|
} finally {
|
|
ReactContext.current = previousContext;
|
|
ReactCurrentOwner.current = null;
|
|
}
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
// TODO: An `isValidNode` function would probably be more appropriate
|
|
renderedComponent === null || renderedComponent === false ||
|
|
ReactElement.isValidElement(renderedComponent),
|
|
'%s.render(): A valid ReactComponent must be returned. You may have ' +
|
|
'returned undefined, an array or some other invalid object.',
|
|
this.getName() || 'ReactCompositeComponent'
|
|
) : invariant(// TODO: An `isValidNode` function would probably be more appropriate
|
|
renderedComponent === null || renderedComponent === false ||
|
|
ReactElement.isValidElement(renderedComponent)));
|
|
return renderedComponent;
|
|
},
|
|
|
|
/**
|
|
* Lazily allocates the refs object and stores `component` as `ref`.
|
|
*
|
|
* @param {string} ref Reference name.
|
|
* @param {component} component Component to store as `ref`.
|
|
* @final
|
|
* @private
|
|
*/
|
|
attachRef: function(ref, component) {
|
|
var inst = this.getPublicInstance();
|
|
var refs = inst.refs === emptyObject ? (inst.refs = {}) : inst.refs;
|
|
refs[ref] = component.getPublicInstance();
|
|
},
|
|
|
|
/**
|
|
* Detaches a reference name.
|
|
*
|
|
* @param {string} ref Name to dereference.
|
|
* @final
|
|
* @private
|
|
*/
|
|
detachRef: function(ref) {
|
|
var refs = this.getPublicInstance().refs;
|
|
delete refs[ref];
|
|
},
|
|
|
|
/**
|
|
* Get a text description of the component that can be used to identify it
|
|
* in error messages.
|
|
* @return {string} The name or null.
|
|
* @internal
|
|
*/
|
|
getName: function() {
|
|
var type = this._currentElement.type;
|
|
var constructor = this._instance && this._instance.constructor;
|
|
return (
|
|
type.displayName || (constructor && constructor.displayName) ||
|
|
type.name || (constructor && constructor.name) ||
|
|
null
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get the publicly accessible representation of this component - i.e. what
|
|
* is exposed by refs and returned by React.render. Can be null for stateless
|
|
* components.
|
|
*
|
|
* @return {ReactComponent} the public component instance.
|
|
* @internal
|
|
*/
|
|
getPublicInstance: function() {
|
|
return this._instance;
|
|
},
|
|
|
|
// Stub
|
|
_instantiateReactComponent: null
|
|
|
|
};
|
|
|
|
ReactPerf.measureMethods(
|
|
ReactCompositeComponentMixin,
|
|
'ReactCompositeComponent',
|
|
{
|
|
mountComponent: 'mountComponent',
|
|
updateComponent: 'updateComponent',
|
|
_renderValidatedComponent: '_renderValidatedComponent'
|
|
}
|
|
);
|
|
|
|
var ReactCompositeComponent = {
|
|
|
|
Mixin: ReactCompositeComponentMixin
|
|
|
|
};
|
|
|
|
module.exports = ReactCompositeComponent;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./Object.assign":76,"./ReactComponentEnvironment":86,"./ReactContext":88,"./ReactCurrentOwner":89,"./ReactElement":107,"./ReactElementValidator":108,"./ReactInstanceMap":117,"./ReactLifeCycle":118,"./ReactNativeComponent":123,"./ReactPerf":125,"./ReactPropTypeLocationNames":126,"./ReactPropTypeLocations":127,"./ReactReconciler":131,"./ReactUpdates":137,"./emptyObject":165,"./invariant":185,"./shouldUpdateReactComponent":201,"./warning":204,"_process":1}],88:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactContext
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var assign = require("./Object.assign");
|
|
var emptyObject = require("./emptyObject");
|
|
var warning = require("./warning");
|
|
|
|
var didWarn = false;
|
|
|
|
/**
|
|
* Keeps track of the current context.
|
|
*
|
|
* The context is automatically passed down the component ownership hierarchy
|
|
* and is accessible via `this.context` on ReactCompositeComponents.
|
|
*/
|
|
var ReactContext = {
|
|
|
|
/**
|
|
* @internal
|
|
* @type {object}
|
|
*/
|
|
current: emptyObject,
|
|
|
|
/**
|
|
* Temporarily extends the current context while executing scopedCallback.
|
|
*
|
|
* A typical use case might look like
|
|
*
|
|
* render: function() {
|
|
* var children = ReactContext.withContext({foo: 'foo'}, () => (
|
|
*
|
|
* ));
|
|
* return <div>{children}</div>;
|
|
* }
|
|
*
|
|
* @param {object} newContext New context to merge into the existing context
|
|
* @param {function} scopedCallback Callback to run with the new context
|
|
* @return {ReactComponent|array<ReactComponent>}
|
|
*/
|
|
withContext: function(newContext, scopedCallback) {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
didWarn,
|
|
'withContext is deprecated and will be removed in a future version. ' +
|
|
'Use a wrapper component with getChildContext instead.'
|
|
) : null);
|
|
|
|
didWarn = true;
|
|
}
|
|
|
|
var result;
|
|
var previousContext = ReactContext.current;
|
|
ReactContext.current = assign({}, previousContext, newContext);
|
|
try {
|
|
result = scopedCallback();
|
|
} finally {
|
|
ReactContext.current = previousContext;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = ReactContext;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./Object.assign":76,"./emptyObject":165,"./warning":204,"_process":1}],89:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactCurrentOwner
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* Keeps track of the current owner.
|
|
*
|
|
* The current owner is the component who should own any components that are
|
|
* currently being constructed.
|
|
*
|
|
* The depth indicate how many composite components are above this render level.
|
|
*/
|
|
var ReactCurrentOwner = {
|
|
|
|
/**
|
|
* @internal
|
|
* @type {ReactComponent}
|
|
*/
|
|
current: null
|
|
|
|
};
|
|
|
|
module.exports = ReactCurrentOwner;
|
|
|
|
},{}],90:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactDOM
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactElement = require("./ReactElement");
|
|
var ReactElementValidator = require("./ReactElementValidator");
|
|
|
|
var mapObject = require("./mapObject");
|
|
|
|
/**
|
|
* Create a factory that creates HTML tag elements.
|
|
*
|
|
* @param {string} tag Tag name (e.g. `div`).
|
|
* @private
|
|
*/
|
|
function createDOMFactory(tag) {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
return ReactElementValidator.createFactory(tag);
|
|
}
|
|
return ReactElement.createFactory(tag);
|
|
}
|
|
|
|
/**
|
|
* Creates a mapping from supported HTML tags to `ReactDOMComponent` classes.
|
|
* This is also accessible via `React.DOM`.
|
|
*
|
|
* @public
|
|
*/
|
|
var ReactDOM = mapObject({
|
|
a: 'a',
|
|
abbr: 'abbr',
|
|
address: 'address',
|
|
area: 'area',
|
|
article: 'article',
|
|
aside: 'aside',
|
|
audio: 'audio',
|
|
b: 'b',
|
|
base: 'base',
|
|
bdi: 'bdi',
|
|
bdo: 'bdo',
|
|
big: 'big',
|
|
blockquote: 'blockquote',
|
|
body: 'body',
|
|
br: 'br',
|
|
button: 'button',
|
|
canvas: 'canvas',
|
|
caption: 'caption',
|
|
cite: 'cite',
|
|
code: 'code',
|
|
col: 'col',
|
|
colgroup: 'colgroup',
|
|
data: 'data',
|
|
datalist: 'datalist',
|
|
dd: 'dd',
|
|
del: 'del',
|
|
details: 'details',
|
|
dfn: 'dfn',
|
|
dialog: 'dialog',
|
|
div: 'div',
|
|
dl: 'dl',
|
|
dt: 'dt',
|
|
em: 'em',
|
|
embed: 'embed',
|
|
fieldset: 'fieldset',
|
|
figcaption: 'figcaption',
|
|
figure: 'figure',
|
|
footer: 'footer',
|
|
form: 'form',
|
|
h1: 'h1',
|
|
h2: 'h2',
|
|
h3: 'h3',
|
|
h4: 'h4',
|
|
h5: 'h5',
|
|
h6: 'h6',
|
|
head: 'head',
|
|
header: 'header',
|
|
hr: 'hr',
|
|
html: 'html',
|
|
i: 'i',
|
|
iframe: 'iframe',
|
|
img: 'img',
|
|
input: 'input',
|
|
ins: 'ins',
|
|
kbd: 'kbd',
|
|
keygen: 'keygen',
|
|
label: 'label',
|
|
legend: 'legend',
|
|
li: 'li',
|
|
link: 'link',
|
|
main: 'main',
|
|
map: 'map',
|
|
mark: 'mark',
|
|
menu: 'menu',
|
|
menuitem: 'menuitem',
|
|
meta: 'meta',
|
|
meter: 'meter',
|
|
nav: 'nav',
|
|
noscript: 'noscript',
|
|
object: 'object',
|
|
ol: 'ol',
|
|
optgroup: 'optgroup',
|
|
option: 'option',
|
|
output: 'output',
|
|
p: 'p',
|
|
param: 'param',
|
|
picture: 'picture',
|
|
pre: 'pre',
|
|
progress: 'progress',
|
|
q: 'q',
|
|
rp: 'rp',
|
|
rt: 'rt',
|
|
ruby: 'ruby',
|
|
s: 's',
|
|
samp: 'samp',
|
|
script: 'script',
|
|
section: 'section',
|
|
select: 'select',
|
|
small: 'small',
|
|
source: 'source',
|
|
span: 'span',
|
|
strong: 'strong',
|
|
style: 'style',
|
|
sub: 'sub',
|
|
summary: 'summary',
|
|
sup: 'sup',
|
|
table: 'table',
|
|
tbody: 'tbody',
|
|
td: 'td',
|
|
textarea: 'textarea',
|
|
tfoot: 'tfoot',
|
|
th: 'th',
|
|
thead: 'thead',
|
|
time: 'time',
|
|
title: 'title',
|
|
tr: 'tr',
|
|
track: 'track',
|
|
u: 'u',
|
|
ul: 'ul',
|
|
'var': 'var',
|
|
video: 'video',
|
|
wbr: 'wbr',
|
|
|
|
// SVG
|
|
circle: 'circle',
|
|
clipPath: 'clipPath',
|
|
defs: 'defs',
|
|
ellipse: 'ellipse',
|
|
g: 'g',
|
|
line: 'line',
|
|
linearGradient: 'linearGradient',
|
|
mask: 'mask',
|
|
path: 'path',
|
|
pattern: 'pattern',
|
|
polygon: 'polygon',
|
|
polyline: 'polyline',
|
|
radialGradient: 'radialGradient',
|
|
rect: 'rect',
|
|
stop: 'stop',
|
|
svg: 'svg',
|
|
text: 'text',
|
|
tspan: 'tspan'
|
|
|
|
}, createDOMFactory);
|
|
|
|
module.exports = ReactDOM;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./ReactElement":107,"./ReactElementValidator":108,"./mapObject":192,"_process":1}],91:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactDOMButton
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var AutoFocusMixin = require("./AutoFocusMixin");
|
|
var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
|
|
var ReactClass = require("./ReactClass");
|
|
var ReactElement = require("./ReactElement");
|
|
|
|
var keyMirror = require("./keyMirror");
|
|
|
|
var button = ReactElement.createFactory('button');
|
|
|
|
var mouseListenerNames = keyMirror({
|
|
onClick: true,
|
|
onDoubleClick: true,
|
|
onMouseDown: true,
|
|
onMouseMove: true,
|
|
onMouseUp: true,
|
|
onClickCapture: true,
|
|
onDoubleClickCapture: true,
|
|
onMouseDownCapture: true,
|
|
onMouseMoveCapture: true,
|
|
onMouseUpCapture: true
|
|
});
|
|
|
|
/**
|
|
* Implements a <button> native component that does not receive mouse events
|
|
* when `disabled` is set.
|
|
*/
|
|
var ReactDOMButton = ReactClass.createClass({
|
|
displayName: 'ReactDOMButton',
|
|
tagName: 'BUTTON',
|
|
|
|
mixins: [AutoFocusMixin, ReactBrowserComponentMixin],
|
|
|
|
render: function() {
|
|
var props = {};
|
|
|
|
// Copy the props; except the mouse listeners if we're disabled
|
|
for (var key in this.props) {
|
|
if (this.props.hasOwnProperty(key) &&
|
|
(!this.props.disabled || !mouseListenerNames[key])) {
|
|
props[key] = this.props[key];
|
|
}
|
|
}
|
|
|
|
return button(props, this.props.children);
|
|
}
|
|
|
|
});
|
|
|
|
module.exports = ReactDOMButton;
|
|
|
|
},{"./AutoFocusMixin":51,"./ReactBrowserComponentMixin":79,"./ReactClass":83,"./ReactElement":107,"./keyMirror":190}],92:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactDOMComponent
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
/* global hasOwnProperty:true */
|
|
|
|
'use strict';
|
|
|
|
var CSSPropertyOperations = require("./CSSPropertyOperations");
|
|
var DOMProperty = require("./DOMProperty");
|
|
var DOMPropertyOperations = require("./DOMPropertyOperations");
|
|
var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter");
|
|
var ReactComponentBrowserEnvironment =
|
|
require("./ReactComponentBrowserEnvironment");
|
|
var ReactMount = require("./ReactMount");
|
|
var ReactMultiChild = require("./ReactMultiChild");
|
|
var ReactPerf = require("./ReactPerf");
|
|
|
|
var assign = require("./Object.assign");
|
|
var escapeTextContentForBrowser = require("./escapeTextContentForBrowser");
|
|
var invariant = require("./invariant");
|
|
var isEventSupported = require("./isEventSupported");
|
|
var keyOf = require("./keyOf");
|
|
var warning = require("./warning");
|
|
|
|
var deleteListener = ReactBrowserEventEmitter.deleteListener;
|
|
var listenTo = ReactBrowserEventEmitter.listenTo;
|
|
var registrationNameModules = ReactBrowserEventEmitter.registrationNameModules;
|
|
|
|
// For quickly matching children type, to test if can be treated as content.
|
|
var CONTENT_TYPES = {'string': true, 'number': true};
|
|
|
|
var STYLE = keyOf({style: null});
|
|
|
|
var ELEMENT_NODE_TYPE = 1;
|
|
|
|
/**
|
|
* Optionally injectable operations for mutating the DOM
|
|
*/
|
|
var BackendIDOperations = null;
|
|
|
|
/**
|
|
* @param {?object} props
|
|
*/
|
|
function assertValidProps(props) {
|
|
if (!props) {
|
|
return;
|
|
}
|
|
// Note the use of `==` which checks for null or undefined.
|
|
if (props.dangerouslySetInnerHTML != null) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
props.children == null,
|
|
'Can only set one of `children` or `props.dangerouslySetInnerHTML`.'
|
|
) : invariant(props.children == null));
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
typeof props.dangerouslySetInnerHTML === 'object' &&
|
|
'__html' in props.dangerouslySetInnerHTML,
|
|
'`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' +
|
|
'Please visit https://fb.me/react-invariant-dangerously-set-inner-html ' +
|
|
'for more information.'
|
|
) : invariant(typeof props.dangerouslySetInnerHTML === 'object' &&
|
|
'__html' in props.dangerouslySetInnerHTML));
|
|
}
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
props.innerHTML == null,
|
|
'Directly setting property `innerHTML` is not permitted. ' +
|
|
'For more information, lookup documentation on `dangerouslySetInnerHTML`.'
|
|
) : null);
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
!props.contentEditable || props.children == null,
|
|
'A component is `contentEditable` and contains `children` managed by ' +
|
|
'React. It is now your responsibility to guarantee that none of ' +
|
|
'those nodes are unexpectedly modified or duplicated. This is ' +
|
|
'probably not intentional.'
|
|
) : null);
|
|
}
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
props.style == null || typeof props.style === 'object',
|
|
'The `style` prop expects a mapping from style properties to values, ' +
|
|
'not a string. For example, style={{marginRight: spacing + \'em\'}} when ' +
|
|
'using JSX.'
|
|
) : invariant(props.style == null || typeof props.style === 'object'));
|
|
}
|
|
|
|
function putListener(id, registrationName, listener, transaction) {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
// IE8 has no API for event capturing and the `onScroll` event doesn't
|
|
// bubble.
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
registrationName !== 'onScroll' || isEventSupported('scroll', true),
|
|
'This browser doesn\'t support the `onScroll` event'
|
|
) : null);
|
|
}
|
|
var container = ReactMount.findReactContainerForID(id);
|
|
if (container) {
|
|
var doc = container.nodeType === ELEMENT_NODE_TYPE ?
|
|
container.ownerDocument :
|
|
container;
|
|
listenTo(registrationName, doc);
|
|
}
|
|
transaction.getPutListenerQueue().enqueuePutListener(
|
|
id,
|
|
registrationName,
|
|
listener
|
|
);
|
|
}
|
|
|
|
// For HTML, certain tags should omit their close tag. We keep a whitelist for
|
|
// those special cased tags.
|
|
|
|
var omittedCloseTags = {
|
|
'area': true,
|
|
'base': true,
|
|
'br': true,
|
|
'col': true,
|
|
'embed': true,
|
|
'hr': true,
|
|
'img': true,
|
|
'input': true,
|
|
'keygen': true,
|
|
'link': true,
|
|
'meta': true,
|
|
'param': true,
|
|
'source': true,
|
|
'track': true,
|
|
'wbr': true
|
|
// NOTE: menuitem's close tag should be omitted, but that causes problems.
|
|
};
|
|
|
|
// We accept any tag to be rendered but since this gets injected into abitrary
|
|
// HTML, we want to make sure that it's a safe tag.
|
|
// http://www.w3.org/TR/REC-xml/#NT-Name
|
|
|
|
var VALID_TAG_REGEX = /^[a-zA-Z][a-zA-Z:_\.\-\d]*$/; // Simplified subset
|
|
var validatedTagCache = {};
|
|
var hasOwnProperty = {}.hasOwnProperty;
|
|
|
|
function validateDangerousTag(tag) {
|
|
if (!hasOwnProperty.call(validatedTagCache, tag)) {
|
|
("production" !== process.env.NODE_ENV ? invariant(VALID_TAG_REGEX.test(tag), 'Invalid tag: %s', tag) : invariant(VALID_TAG_REGEX.test(tag)));
|
|
validatedTagCache[tag] = true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates a new React class that is idempotent and capable of containing other
|
|
* React components. It accepts event listeners and DOM properties that are
|
|
* valid according to `DOMProperty`.
|
|
*
|
|
* - Event listeners: `onClick`, `onMouseDown`, etc.
|
|
* - DOM properties: `className`, `name`, `title`, etc.
|
|
*
|
|
* The `style` property functions differently from the DOM API. It accepts an
|
|
* object mapping of style properties to values.
|
|
*
|
|
* @constructor ReactDOMComponent
|
|
* @extends ReactMultiChild
|
|
*/
|
|
function ReactDOMComponent(tag) {
|
|
validateDangerousTag(tag);
|
|
this._tag = tag;
|
|
this._renderedChildren = null;
|
|
this._previousStyleCopy = null;
|
|
this._rootNodeID = null;
|
|
}
|
|
|
|
ReactDOMComponent.displayName = 'ReactDOMComponent';
|
|
|
|
ReactDOMComponent.Mixin = {
|
|
|
|
construct: function(element) {
|
|
this._currentElement = element;
|
|
},
|
|
|
|
/**
|
|
* Generates root tag markup then recurses. This method has side effects and
|
|
* is not idempotent.
|
|
*
|
|
* @internal
|
|
* @param {string} rootID The root DOM ID for this node.
|
|
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
|
|
* @return {string} The computed markup.
|
|
*/
|
|
mountComponent: function(rootID, transaction, context) {
|
|
this._rootNodeID = rootID;
|
|
assertValidProps(this._currentElement.props);
|
|
var closeTag = omittedCloseTags[this._tag] ? '' : '</' + this._tag + '>';
|
|
return (
|
|
this._createOpenTagMarkupAndPutListeners(transaction) +
|
|
this._createContentMarkup(transaction, context) +
|
|
closeTag
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Creates markup for the open tag and all attributes.
|
|
*
|
|
* This method has side effects because events get registered.
|
|
*
|
|
* Iterating over object properties is faster than iterating over arrays.
|
|
* @see http://jsperf.com/obj-vs-arr-iteration
|
|
*
|
|
* @private
|
|
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
|
|
* @return {string} Markup of opening tag.
|
|
*/
|
|
_createOpenTagMarkupAndPutListeners: function(transaction) {
|
|
var props = this._currentElement.props;
|
|
var ret = '<' + this._tag;
|
|
|
|
for (var propKey in props) {
|
|
if (!props.hasOwnProperty(propKey)) {
|
|
continue;
|
|
}
|
|
var propValue = props[propKey];
|
|
if (propValue == null) {
|
|
continue;
|
|
}
|
|
if (registrationNameModules.hasOwnProperty(propKey)) {
|
|
putListener(this._rootNodeID, propKey, propValue, transaction);
|
|
} else {
|
|
if (propKey === STYLE) {
|
|
if (propValue) {
|
|
propValue = this._previousStyleCopy = assign({}, props.style);
|
|
}
|
|
propValue = CSSPropertyOperations.createMarkupForStyles(propValue);
|
|
}
|
|
var markup =
|
|
DOMPropertyOperations.createMarkupForProperty(propKey, propValue);
|
|
if (markup) {
|
|
ret += ' ' + markup;
|
|
}
|
|
}
|
|
}
|
|
|
|
// For static pages, no need to put React ID and checksum. Saves lots of
|
|
// bytes.
|
|
if (transaction.renderToStaticMarkup) {
|
|
return ret + '>';
|
|
}
|
|
|
|
var markupForID = DOMPropertyOperations.createMarkupForID(this._rootNodeID);
|
|
return ret + ' ' + markupForID + '>';
|
|
},
|
|
|
|
/**
|
|
* Creates markup for the content between the tags.
|
|
*
|
|
* @private
|
|
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
|
|
* @param {object} context
|
|
* @return {string} Content markup.
|
|
*/
|
|
_createContentMarkup: function(transaction, context) {
|
|
var prefix = '';
|
|
if (this._tag === 'listing' ||
|
|
this._tag === 'pre' ||
|
|
this._tag === 'textarea') {
|
|
// Add an initial newline because browsers ignore the first newline in
|
|
// a <listing>, <pre>, or <textarea> as an "authoring convenience" -- see
|
|
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody.
|
|
prefix = '\n';
|
|
}
|
|
|
|
var props = this._currentElement.props;
|
|
|
|
// Intentional use of != to avoid catching zero/false.
|
|
var innerHTML = props.dangerouslySetInnerHTML;
|
|
if (innerHTML != null) {
|
|
if (innerHTML.__html != null) {
|
|
return prefix + innerHTML.__html;
|
|
}
|
|
} else {
|
|
var contentToUse =
|
|
CONTENT_TYPES[typeof props.children] ? props.children : null;
|
|
var childrenToUse = contentToUse != null ? null : props.children;
|
|
if (contentToUse != null) {
|
|
return prefix + escapeTextContentForBrowser(contentToUse);
|
|
} else if (childrenToUse != null) {
|
|
var mountImages = this.mountChildren(
|
|
childrenToUse,
|
|
transaction,
|
|
context
|
|
);
|
|
return prefix + mountImages.join('');
|
|
}
|
|
}
|
|
return prefix;
|
|
},
|
|
|
|
receiveComponent: function(nextElement, transaction, context) {
|
|
var prevElement = this._currentElement;
|
|
this._currentElement = nextElement;
|
|
this.updateComponent(transaction, prevElement, nextElement, context);
|
|
},
|
|
|
|
/**
|
|
* Updates a native DOM component after it has already been allocated and
|
|
* attached to the DOM. Reconciles the root DOM node, then recurses.
|
|
*
|
|
* @param {ReactReconcileTransaction} transaction
|
|
* @param {ReactElement} prevElement
|
|
* @param {ReactElement} nextElement
|
|
* @internal
|
|
* @overridable
|
|
*/
|
|
updateComponent: function(transaction, prevElement, nextElement, context) {
|
|
assertValidProps(this._currentElement.props);
|
|
this._updateDOMProperties(prevElement.props, transaction);
|
|
this._updateDOMChildren(prevElement.props, transaction, context);
|
|
},
|
|
|
|
/**
|
|
* Reconciles the properties by detecting differences in property values and
|
|
* updating the DOM as necessary. This function is probably the single most
|
|
* critical path for performance optimization.
|
|
*
|
|
* TODO: Benchmark whether checking for changed values in memory actually
|
|
* improves performance (especially statically positioned elements).
|
|
* TODO: Benchmark the effects of putting this at the top since 99% of props
|
|
* do not change for a given reconciliation.
|
|
* TODO: Benchmark areas that can be improved with caching.
|
|
*
|
|
* @private
|
|
* @param {object} lastProps
|
|
* @param {ReactReconcileTransaction} transaction
|
|
*/
|
|
_updateDOMProperties: function(lastProps, transaction) {
|
|
var nextProps = this._currentElement.props;
|
|
var propKey;
|
|
var styleName;
|
|
var styleUpdates;
|
|
for (propKey in lastProps) {
|
|
if (nextProps.hasOwnProperty(propKey) ||
|
|
!lastProps.hasOwnProperty(propKey)) {
|
|
continue;
|
|
}
|
|
if (propKey === STYLE) {
|
|
var lastStyle = this._previousStyleCopy;
|
|
for (styleName in lastStyle) {
|
|
if (lastStyle.hasOwnProperty(styleName)) {
|
|
styleUpdates = styleUpdates || {};
|
|
styleUpdates[styleName] = '';
|
|
}
|
|
}
|
|
this._previousStyleCopy = null;
|
|
} else if (registrationNameModules.hasOwnProperty(propKey)) {
|
|
deleteListener(this._rootNodeID, propKey);
|
|
} else if (
|
|
DOMProperty.isStandardName[propKey] ||
|
|
DOMProperty.isCustomAttribute(propKey)) {
|
|
BackendIDOperations.deletePropertyByID(
|
|
this._rootNodeID,
|
|
propKey
|
|
);
|
|
}
|
|
}
|
|
for (propKey in nextProps) {
|
|
var nextProp = nextProps[propKey];
|
|
var lastProp = propKey === STYLE ?
|
|
this._previousStyleCopy :
|
|
lastProps[propKey];
|
|
if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp) {
|
|
continue;
|
|
}
|
|
if (propKey === STYLE) {
|
|
if (nextProp) {
|
|
nextProp = this._previousStyleCopy = assign({}, nextProp);
|
|
} else {
|
|
this._previousStyleCopy = null;
|
|
}
|
|
if (lastProp) {
|
|
// Unset styles on `lastProp` but not on `nextProp`.
|
|
for (styleName in lastProp) {
|
|
if (lastProp.hasOwnProperty(styleName) &&
|
|
(!nextProp || !nextProp.hasOwnProperty(styleName))) {
|
|
styleUpdates = styleUpdates || {};
|
|
styleUpdates[styleName] = '';
|
|
}
|
|
}
|
|
// Update styles that changed since `lastProp`.
|
|
for (styleName in nextProp) {
|
|
if (nextProp.hasOwnProperty(styleName) &&
|
|
lastProp[styleName] !== nextProp[styleName]) {
|
|
styleUpdates = styleUpdates || {};
|
|
styleUpdates[styleName] = nextProp[styleName];
|
|
}
|
|
}
|
|
} else {
|
|
// Relies on `updateStylesByID` not mutating `styleUpdates`.
|
|
styleUpdates = nextProp;
|
|
}
|
|
} else if (registrationNameModules.hasOwnProperty(propKey)) {
|
|
putListener(this._rootNodeID, propKey, nextProp, transaction);
|
|
} else if (
|
|
DOMProperty.isStandardName[propKey] ||
|
|
DOMProperty.isCustomAttribute(propKey)) {
|
|
BackendIDOperations.updatePropertyByID(
|
|
this._rootNodeID,
|
|
propKey,
|
|
nextProp
|
|
);
|
|
}
|
|
}
|
|
if (styleUpdates) {
|
|
BackendIDOperations.updateStylesByID(
|
|
this._rootNodeID,
|
|
styleUpdates
|
|
);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Reconciles the children with the various properties that affect the
|
|
* children content.
|
|
*
|
|
* @param {object} lastProps
|
|
* @param {ReactReconcileTransaction} transaction
|
|
*/
|
|
_updateDOMChildren: function(lastProps, transaction, context) {
|
|
var nextProps = this._currentElement.props;
|
|
|
|
var lastContent =
|
|
CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null;
|
|
var nextContent =
|
|
CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null;
|
|
|
|
var lastHtml =
|
|
lastProps.dangerouslySetInnerHTML &&
|
|
lastProps.dangerouslySetInnerHTML.__html;
|
|
var nextHtml =
|
|
nextProps.dangerouslySetInnerHTML &&
|
|
nextProps.dangerouslySetInnerHTML.__html;
|
|
|
|
// Note the use of `!=` which checks for null or undefined.
|
|
var lastChildren = lastContent != null ? null : lastProps.children;
|
|
var nextChildren = nextContent != null ? null : nextProps.children;
|
|
|
|
// If we're switching from children to content/html or vice versa, remove
|
|
// the old content
|
|
var lastHasContentOrHtml = lastContent != null || lastHtml != null;
|
|
var nextHasContentOrHtml = nextContent != null || nextHtml != null;
|
|
if (lastChildren != null && nextChildren == null) {
|
|
this.updateChildren(null, transaction, context);
|
|
} else if (lastHasContentOrHtml && !nextHasContentOrHtml) {
|
|
this.updateTextContent('');
|
|
}
|
|
|
|
if (nextContent != null) {
|
|
if (lastContent !== nextContent) {
|
|
this.updateTextContent('' + nextContent);
|
|
}
|
|
} else if (nextHtml != null) {
|
|
if (lastHtml !== nextHtml) {
|
|
BackendIDOperations.updateInnerHTMLByID(
|
|
this._rootNodeID,
|
|
nextHtml
|
|
);
|
|
}
|
|
} else if (nextChildren != null) {
|
|
this.updateChildren(nextChildren, transaction, context);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Destroys all event registrations for this instance. Does not remove from
|
|
* the DOM. That must be done by the parent.
|
|
*
|
|
* @internal
|
|
*/
|
|
unmountComponent: function() {
|
|
this.unmountChildren();
|
|
ReactBrowserEventEmitter.deleteAllListeners(this._rootNodeID);
|
|
ReactComponentBrowserEnvironment.unmountIDFromEnvironment(this._rootNodeID);
|
|
this._rootNodeID = null;
|
|
}
|
|
|
|
};
|
|
|
|
ReactPerf.measureMethods(ReactDOMComponent, 'ReactDOMComponent', {
|
|
mountComponent: 'mountComponent',
|
|
updateComponent: 'updateComponent'
|
|
});
|
|
|
|
assign(
|
|
ReactDOMComponent.prototype,
|
|
ReactDOMComponent.Mixin,
|
|
ReactMultiChild.Mixin
|
|
);
|
|
|
|
ReactDOMComponent.injection = {
|
|
injectIDOperations: function(IDOperations) {
|
|
ReactDOMComponent.BackendIDOperations = BackendIDOperations = IDOperations;
|
|
}
|
|
};
|
|
|
|
module.exports = ReactDOMComponent;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./CSSPropertyOperations":54,"./DOMProperty":59,"./DOMPropertyOperations":60,"./Object.assign":76,"./ReactBrowserEventEmitter":80,"./ReactComponentBrowserEnvironment":85,"./ReactMount":120,"./ReactMultiChild":121,"./ReactPerf":125,"./escapeTextContentForBrowser":166,"./invariant":185,"./isEventSupported":186,"./keyOf":191,"./warning":204,"_process":1}],93:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactDOMForm
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var EventConstants = require("./EventConstants");
|
|
var LocalEventTrapMixin = require("./LocalEventTrapMixin");
|
|
var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
|
|
var ReactClass = require("./ReactClass");
|
|
var ReactElement = require("./ReactElement");
|
|
|
|
var form = ReactElement.createFactory('form');
|
|
|
|
/**
|
|
* Since onSubmit doesn't bubble OR capture on the top level in IE8, we need
|
|
* to capture it on the <form> element itself. There are lots of hacks we could
|
|
* do to accomplish this, but the most reliable is to make <form> a
|
|
* composite component and use `componentDidMount` to attach the event handlers.
|
|
*/
|
|
var ReactDOMForm = ReactClass.createClass({
|
|
displayName: 'ReactDOMForm',
|
|
tagName: 'FORM',
|
|
|
|
mixins: [ReactBrowserComponentMixin, LocalEventTrapMixin],
|
|
|
|
render: function() {
|
|
// TODO: Instead of using `ReactDOM` directly, we should use JSX. However,
|
|
// `jshint` fails to parse JSX so in order for linting to work in the open
|
|
// source repo, we need to just use `ReactDOM.form`.
|
|
return form(this.props);
|
|
},
|
|
|
|
componentDidMount: function() {
|
|
this.trapBubbledEvent(EventConstants.topLevelTypes.topReset, 'reset');
|
|
this.trapBubbledEvent(EventConstants.topLevelTypes.topSubmit, 'submit');
|
|
}
|
|
});
|
|
|
|
module.exports = ReactDOMForm;
|
|
|
|
},{"./EventConstants":64,"./LocalEventTrapMixin":74,"./ReactBrowserComponentMixin":79,"./ReactClass":83,"./ReactElement":107}],94:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactDOMIDOperations
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
/*jslint evil: true */
|
|
|
|
'use strict';
|
|
|
|
var CSSPropertyOperations = require("./CSSPropertyOperations");
|
|
var DOMChildrenOperations = require("./DOMChildrenOperations");
|
|
var DOMPropertyOperations = require("./DOMPropertyOperations");
|
|
var ReactMount = require("./ReactMount");
|
|
var ReactPerf = require("./ReactPerf");
|
|
|
|
var invariant = require("./invariant");
|
|
var setInnerHTML = require("./setInnerHTML");
|
|
|
|
/**
|
|
* Errors for properties that should not be updated with `updatePropertyById()`.
|
|
*
|
|
* @type {object}
|
|
* @private
|
|
*/
|
|
var INVALID_PROPERTY_ERRORS = {
|
|
dangerouslySetInnerHTML:
|
|
'`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.',
|
|
style: '`style` must be set using `updateStylesByID()`.'
|
|
};
|
|
|
|
/**
|
|
* Operations used to process updates to DOM nodes. This is made injectable via
|
|
* `ReactDOMComponent.BackendIDOperations`.
|
|
*/
|
|
var ReactDOMIDOperations = {
|
|
|
|
/**
|
|
* Updates a DOM node with new property values. This should only be used to
|
|
* update DOM properties in `DOMProperty`.
|
|
*
|
|
* @param {string} id ID of the node to update.
|
|
* @param {string} name A valid property name, see `DOMProperty`.
|
|
* @param {*} value New value of the property.
|
|
* @internal
|
|
*/
|
|
updatePropertyByID: function(id, name, value) {
|
|
var node = ReactMount.getNode(id);
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
!INVALID_PROPERTY_ERRORS.hasOwnProperty(name),
|
|
'updatePropertyByID(...): %s',
|
|
INVALID_PROPERTY_ERRORS[name]
|
|
) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name)));
|
|
|
|
// If we're updating to null or undefined, we should remove the property
|
|
// from the DOM node instead of inadvertantly setting to a string. This
|
|
// brings us in line with the same behavior we have on initial render.
|
|
if (value != null) {
|
|
DOMPropertyOperations.setValueForProperty(node, name, value);
|
|
} else {
|
|
DOMPropertyOperations.deleteValueForProperty(node, name);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Updates a DOM node to remove a property. This should only be used to remove
|
|
* DOM properties in `DOMProperty`.
|
|
*
|
|
* @param {string} id ID of the node to update.
|
|
* @param {string} name A property name to remove, see `DOMProperty`.
|
|
* @internal
|
|
*/
|
|
deletePropertyByID: function(id, name, value) {
|
|
var node = ReactMount.getNode(id);
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
!INVALID_PROPERTY_ERRORS.hasOwnProperty(name),
|
|
'updatePropertyByID(...): %s',
|
|
INVALID_PROPERTY_ERRORS[name]
|
|
) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name)));
|
|
DOMPropertyOperations.deleteValueForProperty(node, name, value);
|
|
},
|
|
|
|
/**
|
|
* Updates a DOM node with new style values. If a value is specified as '',
|
|
* the corresponding style property will be unset.
|
|
*
|
|
* @param {string} id ID of the node to update.
|
|
* @param {object} styles Mapping from styles to values.
|
|
* @internal
|
|
*/
|
|
updateStylesByID: function(id, styles) {
|
|
var node = ReactMount.getNode(id);
|
|
CSSPropertyOperations.setValueForStyles(node, styles);
|
|
},
|
|
|
|
/**
|
|
* Updates a DOM node's innerHTML.
|
|
*
|
|
* @param {string} id ID of the node to update.
|
|
* @param {string} html An HTML string.
|
|
* @internal
|
|
*/
|
|
updateInnerHTMLByID: function(id, html) {
|
|
var node = ReactMount.getNode(id);
|
|
setInnerHTML(node, html);
|
|
},
|
|
|
|
/**
|
|
* Updates a DOM node's text content set by `props.content`.
|
|
*
|
|
* @param {string} id ID of the node to update.
|
|
* @param {string} content Text content.
|
|
* @internal
|
|
*/
|
|
updateTextContentByID: function(id, content) {
|
|
var node = ReactMount.getNode(id);
|
|
DOMChildrenOperations.updateTextContent(node, content);
|
|
},
|
|
|
|
/**
|
|
* Replaces a DOM node that exists in the document with markup.
|
|
*
|
|
* @param {string} id ID of child to be replaced.
|
|
* @param {string} markup Dangerous markup to inject in place of child.
|
|
* @internal
|
|
* @see {Danger.dangerouslyReplaceNodeWithMarkup}
|
|
*/
|
|
dangerouslyReplaceNodeWithMarkupByID: function(id, markup) {
|
|
var node = ReactMount.getNode(id);
|
|
DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup(node, markup);
|
|
},
|
|
|
|
/**
|
|
* Updates a component's children by processing a series of updates.
|
|
*
|
|
* @param {array<object>} updates List of update configurations.
|
|
* @param {array<string>} markup List of markup strings.
|
|
* @internal
|
|
*/
|
|
dangerouslyProcessChildrenUpdates: function(updates, markup) {
|
|
for (var i = 0; i < updates.length; i++) {
|
|
updates[i].parentNode = ReactMount.getNode(updates[i].parentID);
|
|
}
|
|
DOMChildrenOperations.processUpdates(updates, markup);
|
|
}
|
|
};
|
|
|
|
ReactPerf.measureMethods(ReactDOMIDOperations, 'ReactDOMIDOperations', {
|
|
updatePropertyByID: 'updatePropertyByID',
|
|
deletePropertyByID: 'deletePropertyByID',
|
|
updateStylesByID: 'updateStylesByID',
|
|
updateInnerHTMLByID: 'updateInnerHTMLByID',
|
|
updateTextContentByID: 'updateTextContentByID',
|
|
dangerouslyReplaceNodeWithMarkupByID: 'dangerouslyReplaceNodeWithMarkupByID',
|
|
dangerouslyProcessChildrenUpdates: 'dangerouslyProcessChildrenUpdates'
|
|
});
|
|
|
|
module.exports = ReactDOMIDOperations;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./CSSPropertyOperations":54,"./DOMChildrenOperations":58,"./DOMPropertyOperations":60,"./ReactMount":120,"./ReactPerf":125,"./invariant":185,"./setInnerHTML":198,"_process":1}],95:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactDOMIframe
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var EventConstants = require("./EventConstants");
|
|
var LocalEventTrapMixin = require("./LocalEventTrapMixin");
|
|
var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
|
|
var ReactClass = require("./ReactClass");
|
|
var ReactElement = require("./ReactElement");
|
|
|
|
var iframe = ReactElement.createFactory('iframe');
|
|
|
|
/**
|
|
* Since onLoad doesn't bubble OR capture on the top level in IE8, we need to
|
|
* capture it on the <iframe> element itself. There are lots of hacks we could
|
|
* do to accomplish this, but the most reliable is to make <iframe> a composite
|
|
* component and use `componentDidMount` to attach the event handlers.
|
|
*/
|
|
var ReactDOMIframe = ReactClass.createClass({
|
|
displayName: 'ReactDOMIframe',
|
|
tagName: 'IFRAME',
|
|
|
|
mixins: [ReactBrowserComponentMixin, LocalEventTrapMixin],
|
|
|
|
render: function() {
|
|
return iframe(this.props);
|
|
},
|
|
|
|
componentDidMount: function() {
|
|
this.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load');
|
|
}
|
|
});
|
|
|
|
module.exports = ReactDOMIframe;
|
|
|
|
},{"./EventConstants":64,"./LocalEventTrapMixin":74,"./ReactBrowserComponentMixin":79,"./ReactClass":83,"./ReactElement":107}],96:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactDOMImg
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var EventConstants = require("./EventConstants");
|
|
var LocalEventTrapMixin = require("./LocalEventTrapMixin");
|
|
var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
|
|
var ReactClass = require("./ReactClass");
|
|
var ReactElement = require("./ReactElement");
|
|
|
|
var img = ReactElement.createFactory('img');
|
|
|
|
/**
|
|
* Since onLoad doesn't bubble OR capture on the top level in IE8, we need to
|
|
* capture it on the <img> element itself. There are lots of hacks we could do
|
|
* to accomplish this, but the most reliable is to make <img> a composite
|
|
* component and use `componentDidMount` to attach the event handlers.
|
|
*/
|
|
var ReactDOMImg = ReactClass.createClass({
|
|
displayName: 'ReactDOMImg',
|
|
tagName: 'IMG',
|
|
|
|
mixins: [ReactBrowserComponentMixin, LocalEventTrapMixin],
|
|
|
|
render: function() {
|
|
return img(this.props);
|
|
},
|
|
|
|
componentDidMount: function() {
|
|
this.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load');
|
|
this.trapBubbledEvent(EventConstants.topLevelTypes.topError, 'error');
|
|
}
|
|
});
|
|
|
|
module.exports = ReactDOMImg;
|
|
|
|
},{"./EventConstants":64,"./LocalEventTrapMixin":74,"./ReactBrowserComponentMixin":79,"./ReactClass":83,"./ReactElement":107}],97:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactDOMInput
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var AutoFocusMixin = require("./AutoFocusMixin");
|
|
var DOMPropertyOperations = require("./DOMPropertyOperations");
|
|
var LinkedValueUtils = require("./LinkedValueUtils");
|
|
var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
|
|
var ReactClass = require("./ReactClass");
|
|
var ReactElement = require("./ReactElement");
|
|
var ReactMount = require("./ReactMount");
|
|
var ReactUpdates = require("./ReactUpdates");
|
|
|
|
var assign = require("./Object.assign");
|
|
var invariant = require("./invariant");
|
|
|
|
var input = ReactElement.createFactory('input');
|
|
|
|
var instancesByReactID = {};
|
|
|
|
function forceUpdateIfMounted() {
|
|
/*jshint validthis:true */
|
|
if (this.isMounted()) {
|
|
this.forceUpdate();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Implements an <input> native component that allows setting these optional
|
|
* props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
|
|
*
|
|
* If `checked` or `value` are not supplied (or null/undefined), user actions
|
|
* that affect the checked state or value will trigger updates to the element.
|
|
*
|
|
* If they are supplied (and not null/undefined), the rendered element will not
|
|
* trigger updates to the element. Instead, the props must change in order for
|
|
* the rendered element to be updated.
|
|
*
|
|
* The rendered element will be initialized as unchecked (or `defaultChecked`)
|
|
* with an empty value (or `defaultValue`).
|
|
*
|
|
* @see http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
|
|
*/
|
|
var ReactDOMInput = ReactClass.createClass({
|
|
displayName: 'ReactDOMInput',
|
|
tagName: 'INPUT',
|
|
|
|
mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin],
|
|
|
|
getInitialState: function() {
|
|
var defaultValue = this.props.defaultValue;
|
|
return {
|
|
initialChecked: this.props.defaultChecked || false,
|
|
initialValue: defaultValue != null ? defaultValue : null
|
|
};
|
|
},
|
|
|
|
render: function() {
|
|
// Clone `this.props` so we don't mutate the input.
|
|
var props = assign({}, this.props);
|
|
|
|
props.defaultChecked = null;
|
|
props.defaultValue = null;
|
|
|
|
var value = LinkedValueUtils.getValue(this);
|
|
props.value = value != null ? value : this.state.initialValue;
|
|
|
|
var checked = LinkedValueUtils.getChecked(this);
|
|
props.checked = checked != null ? checked : this.state.initialChecked;
|
|
|
|
props.onChange = this._handleChange;
|
|
|
|
return input(props, this.props.children);
|
|
},
|
|
|
|
componentDidMount: function() {
|
|
var id = ReactMount.getID(this.getDOMNode());
|
|
instancesByReactID[id] = this;
|
|
},
|
|
|
|
componentWillUnmount: function() {
|
|
var rootNode = this.getDOMNode();
|
|
var id = ReactMount.getID(rootNode);
|
|
delete instancesByReactID[id];
|
|
},
|
|
|
|
componentDidUpdate: function(prevProps, prevState, prevContext) {
|
|
var rootNode = this.getDOMNode();
|
|
if (this.props.checked != null) {
|
|
DOMPropertyOperations.setValueForProperty(
|
|
rootNode,
|
|
'checked',
|
|
this.props.checked || false
|
|
);
|
|
}
|
|
|
|
var value = LinkedValueUtils.getValue(this);
|
|
if (value != null) {
|
|
// Cast `value` to a string to ensure the value is set correctly. While
|
|
// browsers typically do this as necessary, jsdom doesn't.
|
|
DOMPropertyOperations.setValueForProperty(rootNode, 'value', '' + value);
|
|
}
|
|
},
|
|
|
|
_handleChange: function(event) {
|
|
var returnValue;
|
|
var onChange = LinkedValueUtils.getOnChange(this);
|
|
if (onChange) {
|
|
returnValue = onChange.call(this, event);
|
|
}
|
|
// Here we use asap to wait until all updates have propagated, which
|
|
// is important when using controlled components within layers:
|
|
// https://github.com/facebook/react/issues/1698
|
|
ReactUpdates.asap(forceUpdateIfMounted, this);
|
|
|
|
var name = this.props.name;
|
|
if (this.props.type === 'radio' && name != null) {
|
|
var rootNode = this.getDOMNode();
|
|
var queryRoot = rootNode;
|
|
|
|
while (queryRoot.parentNode) {
|
|
queryRoot = queryRoot.parentNode;
|
|
}
|
|
|
|
// If `rootNode.form` was non-null, then we could try `form.elements`,
|
|
// but that sometimes behaves strangely in IE8. We could also try using
|
|
// `form.getElementsByName`, but that will only return direct children
|
|
// and won't include inputs that use the HTML5 `form=` attribute. Since
|
|
// the input might not even be in a form, let's just use the global
|
|
// `querySelectorAll` to ensure we don't miss anything.
|
|
var group = queryRoot.querySelectorAll(
|
|
'input[name=' + JSON.stringify('' + name) + '][type="radio"]');
|
|
|
|
for (var i = 0, groupLen = group.length; i < groupLen; i++) {
|
|
var otherNode = group[i];
|
|
if (otherNode === rootNode ||
|
|
otherNode.form !== rootNode.form) {
|
|
continue;
|
|
}
|
|
var otherID = ReactMount.getID(otherNode);
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
otherID,
|
|
'ReactDOMInput: Mixing React and non-React radio inputs with the ' +
|
|
'same `name` is not supported.'
|
|
) : invariant(otherID));
|
|
var otherInstance = instancesByReactID[otherID];
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
otherInstance,
|
|
'ReactDOMInput: Unknown radio button ID %s.',
|
|
otherID
|
|
) : invariant(otherInstance));
|
|
// If this is a controlled radio button group, forcing the input that
|
|
// was previously checked to update will cause it to be come re-checked
|
|
// as appropriate.
|
|
ReactUpdates.asap(forceUpdateIfMounted, otherInstance);
|
|
}
|
|
}
|
|
|
|
return returnValue;
|
|
}
|
|
|
|
});
|
|
|
|
module.exports = ReactDOMInput;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./AutoFocusMixin":51,"./DOMPropertyOperations":60,"./LinkedValueUtils":73,"./Object.assign":76,"./ReactBrowserComponentMixin":79,"./ReactClass":83,"./ReactElement":107,"./ReactMount":120,"./ReactUpdates":137,"./invariant":185,"_process":1}],98:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactDOMOption
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
|
|
var ReactClass = require("./ReactClass");
|
|
var ReactElement = require("./ReactElement");
|
|
|
|
var warning = require("./warning");
|
|
|
|
var option = ReactElement.createFactory('option');
|
|
|
|
/**
|
|
* Implements an <option> native component that warns when `selected` is set.
|
|
*/
|
|
var ReactDOMOption = ReactClass.createClass({
|
|
displayName: 'ReactDOMOption',
|
|
tagName: 'OPTION',
|
|
|
|
mixins: [ReactBrowserComponentMixin],
|
|
|
|
componentWillMount: function() {
|
|
// TODO (yungsters): Remove support for `selected` in <option>.
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
this.props.selected == null,
|
|
'Use the `defaultValue` or `value` props on <select> instead of ' +
|
|
'setting `selected` on <option>.'
|
|
) : null);
|
|
}
|
|
},
|
|
|
|
render: function() {
|
|
return option(this.props, this.props.children);
|
|
}
|
|
|
|
});
|
|
|
|
module.exports = ReactDOMOption;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./ReactBrowserComponentMixin":79,"./ReactClass":83,"./ReactElement":107,"./warning":204,"_process":1}],99:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactDOMSelect
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var AutoFocusMixin = require("./AutoFocusMixin");
|
|
var LinkedValueUtils = require("./LinkedValueUtils");
|
|
var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
|
|
var ReactClass = require("./ReactClass");
|
|
var ReactElement = require("./ReactElement");
|
|
var ReactUpdates = require("./ReactUpdates");
|
|
|
|
var assign = require("./Object.assign");
|
|
|
|
var select = ReactElement.createFactory('select');
|
|
|
|
function updateOptionsIfPendingUpdateAndMounted() {
|
|
/*jshint validthis:true */
|
|
if (this._pendingUpdate) {
|
|
this._pendingUpdate = false;
|
|
var value = LinkedValueUtils.getValue(this);
|
|
if (value != null && this.isMounted()) {
|
|
updateOptions(this, value);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Validation function for `value` and `defaultValue`.
|
|
* @private
|
|
*/
|
|
function selectValueType(props, propName, componentName) {
|
|
if (props[propName] == null) {
|
|
return null;
|
|
}
|
|
if (props.multiple) {
|
|
if (!Array.isArray(props[propName])) {
|
|
return new Error(
|
|
("The `" + propName + "` prop supplied to <select> must be an array if ") +
|
|
("`multiple` is true.")
|
|
);
|
|
}
|
|
} else {
|
|
if (Array.isArray(props[propName])) {
|
|
return new Error(
|
|
("The `" + propName + "` prop supplied to <select> must be a scalar ") +
|
|
("value if `multiple` is false.")
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {ReactComponent} component Instance of ReactDOMSelect
|
|
* @param {*} propValue A stringable (with `multiple`, a list of stringables).
|
|
* @private
|
|
*/
|
|
function updateOptions(component, propValue) {
|
|
var selectedValue, i, l;
|
|
var options = component.getDOMNode().options;
|
|
|
|
if (component.props.multiple) {
|
|
selectedValue = {};
|
|
for (i = 0, l = propValue.length; i < l; i++) {
|
|
selectedValue['' + propValue[i]] = true;
|
|
}
|
|
for (i = 0, l = options.length; i < l; i++) {
|
|
var selected = selectedValue.hasOwnProperty(options[i].value);
|
|
if (options[i].selected !== selected) {
|
|
options[i].selected = selected;
|
|
}
|
|
}
|
|
} else {
|
|
// Do not set `select.value` as exact behavior isn't consistent across all
|
|
// browsers for all cases.
|
|
selectedValue = '' + propValue;
|
|
for (i = 0, l = options.length; i < l; i++) {
|
|
if (options[i].value === selectedValue) {
|
|
options[i].selected = true;
|
|
return;
|
|
}
|
|
}
|
|
if (options.length) {
|
|
options[0].selected = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Implements a <select> native component that allows optionally setting the
|
|
* props `value` and `defaultValue`. If `multiple` is false, the prop must be a
|
|
* stringable. If `multiple` is true, the prop must be an array of stringables.
|
|
*
|
|
* If `value` is not supplied (or null/undefined), user actions that change the
|
|
* selected option will trigger updates to the rendered options.
|
|
*
|
|
* If it is supplied (and not null/undefined), the rendered options will not
|
|
* update in response to user actions. Instead, the `value` prop must change in
|
|
* order for the rendered options to update.
|
|
*
|
|
* If `defaultValue` is provided, any options with the supplied values will be
|
|
* selected.
|
|
*/
|
|
var ReactDOMSelect = ReactClass.createClass({
|
|
displayName: 'ReactDOMSelect',
|
|
tagName: 'SELECT',
|
|
|
|
mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin],
|
|
|
|
propTypes: {
|
|
defaultValue: selectValueType,
|
|
value: selectValueType
|
|
},
|
|
|
|
render: function() {
|
|
// Clone `this.props` so we don't mutate the input.
|
|
var props = assign({}, this.props);
|
|
|
|
props.onChange = this._handleChange;
|
|
props.value = null;
|
|
|
|
return select(props, this.props.children);
|
|
},
|
|
|
|
componentWillMount: function() {
|
|
this._pendingUpdate = false;
|
|
},
|
|
|
|
componentDidMount: function() {
|
|
var value = LinkedValueUtils.getValue(this);
|
|
if (value != null) {
|
|
updateOptions(this, value);
|
|
} else if (this.props.defaultValue != null) {
|
|
updateOptions(this, this.props.defaultValue);
|
|
}
|
|
},
|
|
|
|
componentDidUpdate: function(prevProps) {
|
|
var value = LinkedValueUtils.getValue(this);
|
|
if (value != null) {
|
|
this._pendingUpdate = false;
|
|
updateOptions(this, value);
|
|
} else if (!prevProps.multiple !== !this.props.multiple) {
|
|
// For simplicity, reapply `defaultValue` if `multiple` is toggled.
|
|
if (this.props.defaultValue != null) {
|
|
updateOptions(this, this.props.defaultValue);
|
|
} else {
|
|
// Revert the select back to its default unselected state.
|
|
updateOptions(this, this.props.multiple ? [] : '');
|
|
}
|
|
}
|
|
},
|
|
|
|
_handleChange: function(event) {
|
|
var returnValue;
|
|
var onChange = LinkedValueUtils.getOnChange(this);
|
|
if (onChange) {
|
|
returnValue = onChange.call(this, event);
|
|
}
|
|
|
|
this._pendingUpdate = true;
|
|
ReactUpdates.asap(updateOptionsIfPendingUpdateAndMounted, this);
|
|
return returnValue;
|
|
}
|
|
|
|
});
|
|
|
|
module.exports = ReactDOMSelect;
|
|
|
|
},{"./AutoFocusMixin":51,"./LinkedValueUtils":73,"./Object.assign":76,"./ReactBrowserComponentMixin":79,"./ReactClass":83,"./ReactElement":107,"./ReactUpdates":137}],100:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactDOMSelection
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ExecutionEnvironment = require("./ExecutionEnvironment");
|
|
|
|
var getNodeForCharacterOffset = require("./getNodeForCharacterOffset");
|
|
var getTextContentAccessor = require("./getTextContentAccessor");
|
|
|
|
/**
|
|
* While `isCollapsed` is available on the Selection object and `collapsed`
|
|
* is available on the Range object, IE11 sometimes gets them wrong.
|
|
* If the anchor/focus nodes and offsets are the same, the range is collapsed.
|
|
*/
|
|
function isCollapsed(anchorNode, anchorOffset, focusNode, focusOffset) {
|
|
return anchorNode === focusNode && anchorOffset === focusOffset;
|
|
}
|
|
|
|
/**
|
|
* Get the appropriate anchor and focus node/offset pairs for IE.
|
|
*
|
|
* The catch here is that IE's selection API doesn't provide information
|
|
* about whether the selection is forward or backward, so we have to
|
|
* behave as though it's always forward.
|
|
*
|
|
* IE text differs from modern selection in that it behaves as though
|
|
* block elements end with a new line. This means character offsets will
|
|
* differ between the two APIs.
|
|
*
|
|
* @param {DOMElement} node
|
|
* @return {object}
|
|
*/
|
|
function getIEOffsets(node) {
|
|
var selection = document.selection;
|
|
var selectedRange = selection.createRange();
|
|
var selectedLength = selectedRange.text.length;
|
|
|
|
// Duplicate selection so we can move range without breaking user selection.
|
|
var fromStart = selectedRange.duplicate();
|
|
fromStart.moveToElementText(node);
|
|
fromStart.setEndPoint('EndToStart', selectedRange);
|
|
|
|
var startOffset = fromStart.text.length;
|
|
var endOffset = startOffset + selectedLength;
|
|
|
|
return {
|
|
start: startOffset,
|
|
end: endOffset
|
|
};
|
|
}
|
|
|
|
/**
|
|
* @param {DOMElement} node
|
|
* @return {?object}
|
|
*/
|
|
function getModernOffsets(node) {
|
|
var selection = window.getSelection && window.getSelection();
|
|
|
|
if (!selection || selection.rangeCount === 0) {
|
|
return null;
|
|
}
|
|
|
|
var anchorNode = selection.anchorNode;
|
|
var anchorOffset = selection.anchorOffset;
|
|
var focusNode = selection.focusNode;
|
|
var focusOffset = selection.focusOffset;
|
|
|
|
var currentRange = selection.getRangeAt(0);
|
|
|
|
// If the node and offset values are the same, the selection is collapsed.
|
|
// `Selection.isCollapsed` is available natively, but IE sometimes gets
|
|
// this value wrong.
|
|
var isSelectionCollapsed = isCollapsed(
|
|
selection.anchorNode,
|
|
selection.anchorOffset,
|
|
selection.focusNode,
|
|
selection.focusOffset
|
|
);
|
|
|
|
var rangeLength = isSelectionCollapsed ? 0 : currentRange.toString().length;
|
|
|
|
var tempRange = currentRange.cloneRange();
|
|
tempRange.selectNodeContents(node);
|
|
tempRange.setEnd(currentRange.startContainer, currentRange.startOffset);
|
|
|
|
var isTempRangeCollapsed = isCollapsed(
|
|
tempRange.startContainer,
|
|
tempRange.startOffset,
|
|
tempRange.endContainer,
|
|
tempRange.endOffset
|
|
);
|
|
|
|
var start = isTempRangeCollapsed ? 0 : tempRange.toString().length;
|
|
var end = start + rangeLength;
|
|
|
|
// Detect whether the selection is backward.
|
|
var detectionRange = document.createRange();
|
|
detectionRange.setStart(anchorNode, anchorOffset);
|
|
detectionRange.setEnd(focusNode, focusOffset);
|
|
var isBackward = detectionRange.collapsed;
|
|
|
|
return {
|
|
start: isBackward ? end : start,
|
|
end: isBackward ? start : end
|
|
};
|
|
}
|
|
|
|
/**
|
|
* @param {DOMElement|DOMTextNode} node
|
|
* @param {object} offsets
|
|
*/
|
|
function setIEOffsets(node, offsets) {
|
|
var range = document.selection.createRange().duplicate();
|
|
var start, end;
|
|
|
|
if (typeof offsets.end === 'undefined') {
|
|
start = offsets.start;
|
|
end = start;
|
|
} else if (offsets.start > offsets.end) {
|
|
start = offsets.end;
|
|
end = offsets.start;
|
|
} else {
|
|
start = offsets.start;
|
|
end = offsets.end;
|
|
}
|
|
|
|
range.moveToElementText(node);
|
|
range.moveStart('character', start);
|
|
range.setEndPoint('EndToStart', range);
|
|
range.moveEnd('character', end - start);
|
|
range.select();
|
|
}
|
|
|
|
/**
|
|
* In modern non-IE browsers, we can support both forward and backward
|
|
* selections.
|
|
*
|
|
* Note: IE10+ supports the Selection object, but it does not support
|
|
* the `extend` method, which means that even in modern IE, it's not possible
|
|
* to programatically create a backward selection. Thus, for all IE
|
|
* versions, we use the old IE API to create our selections.
|
|
*
|
|
* @param {DOMElement|DOMTextNode} node
|
|
* @param {object} offsets
|
|
*/
|
|
function setModernOffsets(node, offsets) {
|
|
if (!window.getSelection) {
|
|
return;
|
|
}
|
|
|
|
var selection = window.getSelection();
|
|
var length = node[getTextContentAccessor()].length;
|
|
var start = Math.min(offsets.start, length);
|
|
var end = typeof offsets.end === 'undefined' ?
|
|
start : Math.min(offsets.end, length);
|
|
|
|
// IE 11 uses modern selection, but doesn't support the extend method.
|
|
// Flip backward selections, so we can set with a single range.
|
|
if (!selection.extend && start > end) {
|
|
var temp = end;
|
|
end = start;
|
|
start = temp;
|
|
}
|
|
|
|
var startMarker = getNodeForCharacterOffset(node, start);
|
|
var endMarker = getNodeForCharacterOffset(node, end);
|
|
|
|
if (startMarker && endMarker) {
|
|
var range = document.createRange();
|
|
range.setStart(startMarker.node, startMarker.offset);
|
|
selection.removeAllRanges();
|
|
|
|
if (start > end) {
|
|
selection.addRange(range);
|
|
selection.extend(endMarker.node, endMarker.offset);
|
|
} else {
|
|
range.setEnd(endMarker.node, endMarker.offset);
|
|
selection.addRange(range);
|
|
}
|
|
}
|
|
}
|
|
|
|
var useIEOffsets = (
|
|
ExecutionEnvironment.canUseDOM &&
|
|
'selection' in document &&
|
|
!('getSelection' in window)
|
|
);
|
|
|
|
var ReactDOMSelection = {
|
|
/**
|
|
* @param {DOMElement} node
|
|
*/
|
|
getOffsets: useIEOffsets ? getIEOffsets : getModernOffsets,
|
|
|
|
/**
|
|
* @param {DOMElement|DOMTextNode} node
|
|
* @param {object} offsets
|
|
*/
|
|
setOffsets: useIEOffsets ? setIEOffsets : setModernOffsets
|
|
};
|
|
|
|
module.exports = ReactDOMSelection;
|
|
|
|
},{"./ExecutionEnvironment":70,"./getNodeForCharacterOffset":178,"./getTextContentAccessor":180}],101:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactDOMTextComponent
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var DOMPropertyOperations = require("./DOMPropertyOperations");
|
|
var ReactComponentBrowserEnvironment =
|
|
require("./ReactComponentBrowserEnvironment");
|
|
var ReactDOMComponent = require("./ReactDOMComponent");
|
|
|
|
var assign = require("./Object.assign");
|
|
var escapeTextContentForBrowser = require("./escapeTextContentForBrowser");
|
|
|
|
/**
|
|
* Text nodes violate a couple assumptions that React makes about components:
|
|
*
|
|
* - When mounting text into the DOM, adjacent text nodes are merged.
|
|
* - Text nodes cannot be assigned a React root ID.
|
|
*
|
|
* This component is used to wrap strings in elements so that they can undergo
|
|
* the same reconciliation that is applied to elements.
|
|
*
|
|
* TODO: Investigate representing React components in the DOM with text nodes.
|
|
*
|
|
* @class ReactDOMTextComponent
|
|
* @extends ReactComponent
|
|
* @internal
|
|
*/
|
|
var ReactDOMTextComponent = function(props) {
|
|
// This constructor and its argument is currently used by mocks.
|
|
};
|
|
|
|
assign(ReactDOMTextComponent.prototype, {
|
|
|
|
/**
|
|
* @param {ReactText} text
|
|
* @internal
|
|
*/
|
|
construct: function(text) {
|
|
// TODO: This is really a ReactText (ReactNode), not a ReactElement
|
|
this._currentElement = text;
|
|
this._stringText = '' + text;
|
|
|
|
// Properties
|
|
this._rootNodeID = null;
|
|
this._mountIndex = 0;
|
|
},
|
|
|
|
/**
|
|
* Creates the markup for this text node. This node is not intended to have
|
|
* any features besides containing text content.
|
|
*
|
|
* @param {string} rootID DOM ID of the root node.
|
|
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
|
|
* @return {string} Markup for this text node.
|
|
* @internal
|
|
*/
|
|
mountComponent: function(rootID, transaction, context) {
|
|
this._rootNodeID = rootID;
|
|
var escapedText = escapeTextContentForBrowser(this._stringText);
|
|
|
|
if (transaction.renderToStaticMarkup) {
|
|
// Normally we'd wrap this in a `span` for the reasons stated above, but
|
|
// since this is a situation where React won't take over (static pages),
|
|
// we can simply return the text as it is.
|
|
return escapedText;
|
|
}
|
|
|
|
return (
|
|
'<span ' + DOMPropertyOperations.createMarkupForID(rootID) + '>' +
|
|
escapedText +
|
|
'</span>'
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Updates this component by updating the text content.
|
|
*
|
|
* @param {ReactText} nextText The next text content
|
|
* @param {ReactReconcileTransaction} transaction
|
|
* @internal
|
|
*/
|
|
receiveComponent: function(nextText, transaction) {
|
|
if (nextText !== this._currentElement) {
|
|
this._currentElement = nextText;
|
|
var nextStringText = '' + nextText;
|
|
if (nextStringText !== this._stringText) {
|
|
// TODO: Save this as pending props and use performUpdateIfNecessary
|
|
// and/or updateComponent to do the actual update for consistency with
|
|
// other component types?
|
|
this._stringText = nextStringText;
|
|
ReactDOMComponent.BackendIDOperations.updateTextContentByID(
|
|
this._rootNodeID,
|
|
nextStringText
|
|
);
|
|
}
|
|
}
|
|
},
|
|
|
|
unmountComponent: function() {
|
|
ReactComponentBrowserEnvironment.unmountIDFromEnvironment(this._rootNodeID);
|
|
}
|
|
|
|
});
|
|
|
|
module.exports = ReactDOMTextComponent;
|
|
|
|
},{"./DOMPropertyOperations":60,"./Object.assign":76,"./ReactComponentBrowserEnvironment":85,"./ReactDOMComponent":92,"./escapeTextContentForBrowser":166}],102:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactDOMTextarea
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var AutoFocusMixin = require("./AutoFocusMixin");
|
|
var DOMPropertyOperations = require("./DOMPropertyOperations");
|
|
var LinkedValueUtils = require("./LinkedValueUtils");
|
|
var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
|
|
var ReactClass = require("./ReactClass");
|
|
var ReactElement = require("./ReactElement");
|
|
var ReactUpdates = require("./ReactUpdates");
|
|
|
|
var assign = require("./Object.assign");
|
|
var invariant = require("./invariant");
|
|
|
|
var warning = require("./warning");
|
|
|
|
var textarea = ReactElement.createFactory('textarea');
|
|
|
|
function forceUpdateIfMounted() {
|
|
/*jshint validthis:true */
|
|
if (this.isMounted()) {
|
|
this.forceUpdate();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Implements a <textarea> native component that allows setting `value`, and
|
|
* `defaultValue`. This differs from the traditional DOM API because value is
|
|
* usually set as PCDATA children.
|
|
*
|
|
* If `value` is not supplied (or null/undefined), user actions that affect the
|
|
* value will trigger updates to the element.
|
|
*
|
|
* If `value` is supplied (and not null/undefined), the rendered element will
|
|
* not trigger updates to the element. Instead, the `value` prop must change in
|
|
* order for the rendered element to be updated.
|
|
*
|
|
* The rendered element will be initialized with an empty value, the prop
|
|
* `defaultValue` if specified, or the children content (deprecated).
|
|
*/
|
|
var ReactDOMTextarea = ReactClass.createClass({
|
|
displayName: 'ReactDOMTextarea',
|
|
tagName: 'TEXTAREA',
|
|
|
|
mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin],
|
|
|
|
getInitialState: function() {
|
|
var defaultValue = this.props.defaultValue;
|
|
// TODO (yungsters): Remove support for children content in <textarea>.
|
|
var children = this.props.children;
|
|
if (children != null) {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
false,
|
|
'Use the `defaultValue` or `value` props instead of setting ' +
|
|
'children on <textarea>.'
|
|
) : null);
|
|
}
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
defaultValue == null,
|
|
'If you supply `defaultValue` on a <textarea>, do not pass children.'
|
|
) : invariant(defaultValue == null));
|
|
if (Array.isArray(children)) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
children.length <= 1,
|
|
'<textarea> can only have at most one child.'
|
|
) : invariant(children.length <= 1));
|
|
children = children[0];
|
|
}
|
|
|
|
defaultValue = '' + children;
|
|
}
|
|
if (defaultValue == null) {
|
|
defaultValue = '';
|
|
}
|
|
var value = LinkedValueUtils.getValue(this);
|
|
return {
|
|
// We save the initial value so that `ReactDOMComponent` doesn't update
|
|
// `textContent` (unnecessary since we update value).
|
|
// The initial value can be a boolean or object so that's why it's
|
|
// forced to be a string.
|
|
initialValue: '' + (value != null ? value : defaultValue)
|
|
};
|
|
},
|
|
|
|
render: function() {
|
|
// Clone `this.props` so we don't mutate the input.
|
|
var props = assign({}, this.props);
|
|
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
props.dangerouslySetInnerHTML == null,
|
|
'`dangerouslySetInnerHTML` does not make sense on <textarea>.'
|
|
) : invariant(props.dangerouslySetInnerHTML == null));
|
|
|
|
props.defaultValue = null;
|
|
props.value = null;
|
|
props.onChange = this._handleChange;
|
|
|
|
// Always set children to the same thing. In IE9, the selection range will
|
|
// get reset if `textContent` is mutated.
|
|
return textarea(props, this.state.initialValue);
|
|
},
|
|
|
|
componentDidUpdate: function(prevProps, prevState, prevContext) {
|
|
var value = LinkedValueUtils.getValue(this);
|
|
if (value != null) {
|
|
var rootNode = this.getDOMNode();
|
|
// Cast `value` to a string to ensure the value is set correctly. While
|
|
// browsers typically do this as necessary, jsdom doesn't.
|
|
DOMPropertyOperations.setValueForProperty(rootNode, 'value', '' + value);
|
|
}
|
|
},
|
|
|
|
_handleChange: function(event) {
|
|
var returnValue;
|
|
var onChange = LinkedValueUtils.getOnChange(this);
|
|
if (onChange) {
|
|
returnValue = onChange.call(this, event);
|
|
}
|
|
ReactUpdates.asap(forceUpdateIfMounted, this);
|
|
return returnValue;
|
|
}
|
|
|
|
});
|
|
|
|
module.exports = ReactDOMTextarea;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./AutoFocusMixin":51,"./DOMPropertyOperations":60,"./LinkedValueUtils":73,"./Object.assign":76,"./ReactBrowserComponentMixin":79,"./ReactClass":83,"./ReactElement":107,"./ReactUpdates":137,"./invariant":185,"./warning":204,"_process":1}],103:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactDefaultBatchingStrategy
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactUpdates = require("./ReactUpdates");
|
|
var Transaction = require("./Transaction");
|
|
|
|
var assign = require("./Object.assign");
|
|
var emptyFunction = require("./emptyFunction");
|
|
|
|
var RESET_BATCHED_UPDATES = {
|
|
initialize: emptyFunction,
|
|
close: function() {
|
|
ReactDefaultBatchingStrategy.isBatchingUpdates = false;
|
|
}
|
|
};
|
|
|
|
var FLUSH_BATCHED_UPDATES = {
|
|
initialize: emptyFunction,
|
|
close: ReactUpdates.flushBatchedUpdates.bind(ReactUpdates)
|
|
};
|
|
|
|
var TRANSACTION_WRAPPERS = [FLUSH_BATCHED_UPDATES, RESET_BATCHED_UPDATES];
|
|
|
|
function ReactDefaultBatchingStrategyTransaction() {
|
|
this.reinitializeTransaction();
|
|
}
|
|
|
|
assign(
|
|
ReactDefaultBatchingStrategyTransaction.prototype,
|
|
Transaction.Mixin,
|
|
{
|
|
getTransactionWrappers: function() {
|
|
return TRANSACTION_WRAPPERS;
|
|
}
|
|
}
|
|
);
|
|
|
|
var transaction = new ReactDefaultBatchingStrategyTransaction();
|
|
|
|
var ReactDefaultBatchingStrategy = {
|
|
isBatchingUpdates: false,
|
|
|
|
/**
|
|
* Call the provided function in a context within which calls to `setState`
|
|
* and friends are batched such that components aren't updated unnecessarily.
|
|
*/
|
|
batchedUpdates: function(callback, a, b, c, d) {
|
|
var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates;
|
|
|
|
ReactDefaultBatchingStrategy.isBatchingUpdates = true;
|
|
|
|
// The code is written this way to avoid extra allocations
|
|
if (alreadyBatchingUpdates) {
|
|
callback(a, b, c, d);
|
|
} else {
|
|
transaction.perform(callback, null, a, b, c, d);
|
|
}
|
|
}
|
|
};
|
|
|
|
module.exports = ReactDefaultBatchingStrategy;
|
|
|
|
},{"./Object.assign":76,"./ReactUpdates":137,"./Transaction":153,"./emptyFunction":164}],104:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactDefaultInjection
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var BeforeInputEventPlugin = require("./BeforeInputEventPlugin");
|
|
var ChangeEventPlugin = require("./ChangeEventPlugin");
|
|
var ClientReactRootIndex = require("./ClientReactRootIndex");
|
|
var DefaultEventPluginOrder = require("./DefaultEventPluginOrder");
|
|
var EnterLeaveEventPlugin = require("./EnterLeaveEventPlugin");
|
|
var ExecutionEnvironment = require("./ExecutionEnvironment");
|
|
var HTMLDOMPropertyConfig = require("./HTMLDOMPropertyConfig");
|
|
var MobileSafariClickEventPlugin = require("./MobileSafariClickEventPlugin");
|
|
var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
|
|
var ReactClass = require("./ReactClass");
|
|
var ReactComponentBrowserEnvironment =
|
|
require("./ReactComponentBrowserEnvironment");
|
|
var ReactDefaultBatchingStrategy = require("./ReactDefaultBatchingStrategy");
|
|
var ReactDOMComponent = require("./ReactDOMComponent");
|
|
var ReactDOMButton = require("./ReactDOMButton");
|
|
var ReactDOMForm = require("./ReactDOMForm");
|
|
var ReactDOMImg = require("./ReactDOMImg");
|
|
var ReactDOMIDOperations = require("./ReactDOMIDOperations");
|
|
var ReactDOMIframe = require("./ReactDOMIframe");
|
|
var ReactDOMInput = require("./ReactDOMInput");
|
|
var ReactDOMOption = require("./ReactDOMOption");
|
|
var ReactDOMSelect = require("./ReactDOMSelect");
|
|
var ReactDOMTextarea = require("./ReactDOMTextarea");
|
|
var ReactDOMTextComponent = require("./ReactDOMTextComponent");
|
|
var ReactElement = require("./ReactElement");
|
|
var ReactEventListener = require("./ReactEventListener");
|
|
var ReactInjection = require("./ReactInjection");
|
|
var ReactInstanceHandles = require("./ReactInstanceHandles");
|
|
var ReactMount = require("./ReactMount");
|
|
var ReactReconcileTransaction = require("./ReactReconcileTransaction");
|
|
var SelectEventPlugin = require("./SelectEventPlugin");
|
|
var ServerReactRootIndex = require("./ServerReactRootIndex");
|
|
var SimpleEventPlugin = require("./SimpleEventPlugin");
|
|
var SVGDOMPropertyConfig = require("./SVGDOMPropertyConfig");
|
|
|
|
var createFullPageComponent = require("./createFullPageComponent");
|
|
|
|
function autoGenerateWrapperClass(type) {
|
|
return ReactClass.createClass({
|
|
tagName: type.toUpperCase(),
|
|
render: function() {
|
|
return new ReactElement(
|
|
type,
|
|
null,
|
|
null,
|
|
null,
|
|
null,
|
|
this.props
|
|
);
|
|
}
|
|
});
|
|
}
|
|
|
|
function inject() {
|
|
ReactInjection.EventEmitter.injectReactEventListener(
|
|
ReactEventListener
|
|
);
|
|
|
|
/**
|
|
* Inject modules for resolving DOM hierarchy and plugin ordering.
|
|
*/
|
|
ReactInjection.EventPluginHub.injectEventPluginOrder(DefaultEventPluginOrder);
|
|
ReactInjection.EventPluginHub.injectInstanceHandle(ReactInstanceHandles);
|
|
ReactInjection.EventPluginHub.injectMount(ReactMount);
|
|
|
|
/**
|
|
* Some important event plugins included by default (without having to require
|
|
* them).
|
|
*/
|
|
ReactInjection.EventPluginHub.injectEventPluginsByName({
|
|
SimpleEventPlugin: SimpleEventPlugin,
|
|
EnterLeaveEventPlugin: EnterLeaveEventPlugin,
|
|
ChangeEventPlugin: ChangeEventPlugin,
|
|
MobileSafariClickEventPlugin: MobileSafariClickEventPlugin,
|
|
SelectEventPlugin: SelectEventPlugin,
|
|
BeforeInputEventPlugin: BeforeInputEventPlugin
|
|
});
|
|
|
|
ReactInjection.NativeComponent.injectGenericComponentClass(
|
|
ReactDOMComponent
|
|
);
|
|
|
|
ReactInjection.NativeComponent.injectTextComponentClass(
|
|
ReactDOMTextComponent
|
|
);
|
|
|
|
ReactInjection.NativeComponent.injectAutoWrapper(
|
|
autoGenerateWrapperClass
|
|
);
|
|
|
|
// This needs to happen before createFullPageComponent() otherwise the mixin
|
|
// won't be included.
|
|
ReactInjection.Class.injectMixin(ReactBrowserComponentMixin);
|
|
|
|
ReactInjection.NativeComponent.injectComponentClasses({
|
|
'button': ReactDOMButton,
|
|
'form': ReactDOMForm,
|
|
'iframe': ReactDOMIframe,
|
|
'img': ReactDOMImg,
|
|
'input': ReactDOMInput,
|
|
'option': ReactDOMOption,
|
|
'select': ReactDOMSelect,
|
|
'textarea': ReactDOMTextarea,
|
|
|
|
'html': createFullPageComponent('html'),
|
|
'head': createFullPageComponent('head'),
|
|
'body': createFullPageComponent('body')
|
|
});
|
|
|
|
ReactInjection.DOMProperty.injectDOMPropertyConfig(HTMLDOMPropertyConfig);
|
|
ReactInjection.DOMProperty.injectDOMPropertyConfig(SVGDOMPropertyConfig);
|
|
|
|
ReactInjection.EmptyComponent.injectEmptyComponent('noscript');
|
|
|
|
ReactInjection.Updates.injectReconcileTransaction(
|
|
ReactReconcileTransaction
|
|
);
|
|
ReactInjection.Updates.injectBatchingStrategy(
|
|
ReactDefaultBatchingStrategy
|
|
);
|
|
|
|
ReactInjection.RootIndex.injectCreateReactRootIndex(
|
|
ExecutionEnvironment.canUseDOM ?
|
|
ClientReactRootIndex.createReactRootIndex :
|
|
ServerReactRootIndex.createReactRootIndex
|
|
);
|
|
|
|
ReactInjection.Component.injectEnvironment(ReactComponentBrowserEnvironment);
|
|
ReactInjection.DOMComponent.injectIDOperations(ReactDOMIDOperations);
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
var url = (ExecutionEnvironment.canUseDOM && window.location.href) || '';
|
|
if ((/[?&]react_perf\b/).test(url)) {
|
|
var ReactDefaultPerf = require("./ReactDefaultPerf");
|
|
ReactDefaultPerf.start();
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
inject: inject
|
|
};
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./BeforeInputEventPlugin":52,"./ChangeEventPlugin":56,"./ClientReactRootIndex":57,"./DefaultEventPluginOrder":62,"./EnterLeaveEventPlugin":63,"./ExecutionEnvironment":70,"./HTMLDOMPropertyConfig":72,"./MobileSafariClickEventPlugin":75,"./ReactBrowserComponentMixin":79,"./ReactClass":83,"./ReactComponentBrowserEnvironment":85,"./ReactDOMButton":91,"./ReactDOMComponent":92,"./ReactDOMForm":93,"./ReactDOMIDOperations":94,"./ReactDOMIframe":95,"./ReactDOMImg":96,"./ReactDOMInput":97,"./ReactDOMOption":98,"./ReactDOMSelect":99,"./ReactDOMTextComponent":101,"./ReactDOMTextarea":102,"./ReactDefaultBatchingStrategy":103,"./ReactDefaultPerf":105,"./ReactElement":107,"./ReactEventListener":112,"./ReactInjection":114,"./ReactInstanceHandles":116,"./ReactMount":120,"./ReactReconcileTransaction":130,"./SVGDOMPropertyConfig":138,"./SelectEventPlugin":139,"./ServerReactRootIndex":140,"./SimpleEventPlugin":141,"./createFullPageComponent":161,"_process":1}],105:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactDefaultPerf
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var DOMProperty = require("./DOMProperty");
|
|
var ReactDefaultPerfAnalysis = require("./ReactDefaultPerfAnalysis");
|
|
var ReactMount = require("./ReactMount");
|
|
var ReactPerf = require("./ReactPerf");
|
|
|
|
var performanceNow = require("./performanceNow");
|
|
|
|
function roundFloat(val) {
|
|
return Math.floor(val * 100) / 100;
|
|
}
|
|
|
|
function addValue(obj, key, val) {
|
|
obj[key] = (obj[key] || 0) + val;
|
|
}
|
|
|
|
var ReactDefaultPerf = {
|
|
_allMeasurements: [], // last item in the list is the current one
|
|
_mountStack: [0],
|
|
_injected: false,
|
|
|
|
start: function() {
|
|
if (!ReactDefaultPerf._injected) {
|
|
ReactPerf.injection.injectMeasure(ReactDefaultPerf.measure);
|
|
}
|
|
|
|
ReactDefaultPerf._allMeasurements.length = 0;
|
|
ReactPerf.enableMeasure = true;
|
|
},
|
|
|
|
stop: function() {
|
|
ReactPerf.enableMeasure = false;
|
|
},
|
|
|
|
getLastMeasurements: function() {
|
|
return ReactDefaultPerf._allMeasurements;
|
|
},
|
|
|
|
printExclusive: function(measurements) {
|
|
measurements = measurements || ReactDefaultPerf._allMeasurements;
|
|
var summary = ReactDefaultPerfAnalysis.getExclusiveSummary(measurements);
|
|
console.table(summary.map(function(item) {
|
|
return {
|
|
'Component class name': item.componentName,
|
|
'Total inclusive time (ms)': roundFloat(item.inclusive),
|
|
'Exclusive mount time (ms)': roundFloat(item.exclusive),
|
|
'Exclusive render time (ms)': roundFloat(item.render),
|
|
'Mount time per instance (ms)': roundFloat(item.exclusive / item.count),
|
|
'Render time per instance (ms)': roundFloat(item.render / item.count),
|
|
'Instances': item.count
|
|
};
|
|
}));
|
|
// TODO: ReactDefaultPerfAnalysis.getTotalTime() does not return the correct
|
|
// number.
|
|
},
|
|
|
|
printInclusive: function(measurements) {
|
|
measurements = measurements || ReactDefaultPerf._allMeasurements;
|
|
var summary = ReactDefaultPerfAnalysis.getInclusiveSummary(measurements);
|
|
console.table(summary.map(function(item) {
|
|
return {
|
|
'Owner > component': item.componentName,
|
|
'Inclusive time (ms)': roundFloat(item.time),
|
|
'Instances': item.count
|
|
};
|
|
}));
|
|
console.log(
|
|
'Total time:',
|
|
ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms'
|
|
);
|
|
},
|
|
|
|
getMeasurementsSummaryMap: function(measurements) {
|
|
var summary = ReactDefaultPerfAnalysis.getInclusiveSummary(
|
|
measurements,
|
|
true
|
|
);
|
|
return summary.map(function(item) {
|
|
return {
|
|
'Owner > component': item.componentName,
|
|
'Wasted time (ms)': item.time,
|
|
'Instances': item.count
|
|
};
|
|
});
|
|
},
|
|
|
|
printWasted: function(measurements) {
|
|
measurements = measurements || ReactDefaultPerf._allMeasurements;
|
|
console.table(ReactDefaultPerf.getMeasurementsSummaryMap(measurements));
|
|
console.log(
|
|
'Total time:',
|
|
ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms'
|
|
);
|
|
},
|
|
|
|
printDOM: function(measurements) {
|
|
measurements = measurements || ReactDefaultPerf._allMeasurements;
|
|
var summary = ReactDefaultPerfAnalysis.getDOMSummary(measurements);
|
|
console.table(summary.map(function(item) {
|
|
var result = {};
|
|
result[DOMProperty.ID_ATTRIBUTE_NAME] = item.id;
|
|
result['type'] = item.type;
|
|
result['args'] = JSON.stringify(item.args);
|
|
return result;
|
|
}));
|
|
console.log(
|
|
'Total time:',
|
|
ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms'
|
|
);
|
|
},
|
|
|
|
_recordWrite: function(id, fnName, totalTime, args) {
|
|
// TODO: totalTime isn't that useful since it doesn't count paints/reflows
|
|
var writes =
|
|
ReactDefaultPerf
|
|
._allMeasurements[ReactDefaultPerf._allMeasurements.length - 1]
|
|
.writes;
|
|
writes[id] = writes[id] || [];
|
|
writes[id].push({
|
|
type: fnName,
|
|
time: totalTime,
|
|
args: args
|
|
});
|
|
},
|
|
|
|
measure: function(moduleName, fnName, func) {
|
|
return function() {for (var args=[],$__0=0,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]);
|
|
var totalTime;
|
|
var rv;
|
|
var start;
|
|
|
|
if (fnName === '_renderNewRootComponent' ||
|
|
fnName === 'flushBatchedUpdates') {
|
|
// A "measurement" is a set of metrics recorded for each flush. We want
|
|
// to group the metrics for a given flush together so we can look at the
|
|
// components that rendered and the DOM operations that actually
|
|
// happened to determine the amount of "wasted work" performed.
|
|
ReactDefaultPerf._allMeasurements.push({
|
|
exclusive: {},
|
|
inclusive: {},
|
|
render: {},
|
|
counts: {},
|
|
writes: {},
|
|
displayNames: {},
|
|
totalTime: 0
|
|
});
|
|
start = performanceNow();
|
|
rv = func.apply(this, args);
|
|
ReactDefaultPerf._allMeasurements[
|
|
ReactDefaultPerf._allMeasurements.length - 1
|
|
].totalTime = performanceNow() - start;
|
|
return rv;
|
|
} else if (fnName === '_mountImageIntoNode' ||
|
|
moduleName === 'ReactDOMIDOperations') {
|
|
start = performanceNow();
|
|
rv = func.apply(this, args);
|
|
totalTime = performanceNow() - start;
|
|
|
|
if (fnName === '_mountImageIntoNode') {
|
|
var mountID = ReactMount.getID(args[1]);
|
|
ReactDefaultPerf._recordWrite(mountID, fnName, totalTime, args[0]);
|
|
} else if (fnName === 'dangerouslyProcessChildrenUpdates') {
|
|
// special format
|
|
args[0].forEach(function(update) {
|
|
var writeArgs = {};
|
|
if (update.fromIndex !== null) {
|
|
writeArgs.fromIndex = update.fromIndex;
|
|
}
|
|
if (update.toIndex !== null) {
|
|
writeArgs.toIndex = update.toIndex;
|
|
}
|
|
if (update.textContent !== null) {
|
|
writeArgs.textContent = update.textContent;
|
|
}
|
|
if (update.markupIndex !== null) {
|
|
writeArgs.markup = args[1][update.markupIndex];
|
|
}
|
|
ReactDefaultPerf._recordWrite(
|
|
update.parentID,
|
|
update.type,
|
|
totalTime,
|
|
writeArgs
|
|
);
|
|
});
|
|
} else {
|
|
// basic format
|
|
ReactDefaultPerf._recordWrite(
|
|
args[0],
|
|
fnName,
|
|
totalTime,
|
|
Array.prototype.slice.call(args, 1)
|
|
);
|
|
}
|
|
return rv;
|
|
} else if (moduleName === 'ReactCompositeComponent' && (
|
|
(// TODO: receiveComponent()?
|
|
(fnName === 'mountComponent' ||
|
|
fnName === 'updateComponent' || fnName === '_renderValidatedComponent')))) {
|
|
|
|
if (typeof this._currentElement.type === 'string') {
|
|
return func.apply(this, args);
|
|
}
|
|
|
|
var rootNodeID = fnName === 'mountComponent' ?
|
|
args[0] :
|
|
this._rootNodeID;
|
|
var isRender = fnName === '_renderValidatedComponent';
|
|
var isMount = fnName === 'mountComponent';
|
|
|
|
var mountStack = ReactDefaultPerf._mountStack;
|
|
var entry = ReactDefaultPerf._allMeasurements[
|
|
ReactDefaultPerf._allMeasurements.length - 1
|
|
];
|
|
|
|
if (isRender) {
|
|
addValue(entry.counts, rootNodeID, 1);
|
|
} else if (isMount) {
|
|
mountStack.push(0);
|
|
}
|
|
|
|
start = performanceNow();
|
|
rv = func.apply(this, args);
|
|
totalTime = performanceNow() - start;
|
|
|
|
if (isRender) {
|
|
addValue(entry.render, rootNodeID, totalTime);
|
|
} else if (isMount) {
|
|
var subMountTime = mountStack.pop();
|
|
mountStack[mountStack.length - 1] += totalTime;
|
|
addValue(entry.exclusive, rootNodeID, totalTime - subMountTime);
|
|
addValue(entry.inclusive, rootNodeID, totalTime);
|
|
} else {
|
|
addValue(entry.inclusive, rootNodeID, totalTime);
|
|
}
|
|
|
|
entry.displayNames[rootNodeID] = {
|
|
current: this.getName(),
|
|
owner: this._currentElement._owner ?
|
|
this._currentElement._owner.getName() :
|
|
'<root>'
|
|
};
|
|
|
|
return rv;
|
|
} else {
|
|
return func.apply(this, args);
|
|
}
|
|
};
|
|
}
|
|
};
|
|
|
|
module.exports = ReactDefaultPerf;
|
|
|
|
},{"./DOMProperty":59,"./ReactDefaultPerfAnalysis":106,"./ReactMount":120,"./ReactPerf":125,"./performanceNow":196}],106:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactDefaultPerfAnalysis
|
|
*/
|
|
|
|
var assign = require("./Object.assign");
|
|
|
|
// Don't try to save users less than 1.2ms (a number I made up)
|
|
var DONT_CARE_THRESHOLD = 1.2;
|
|
var DOM_OPERATION_TYPES = {
|
|
'_mountImageIntoNode': 'set innerHTML',
|
|
INSERT_MARKUP: 'set innerHTML',
|
|
MOVE_EXISTING: 'move',
|
|
REMOVE_NODE: 'remove',
|
|
TEXT_CONTENT: 'set textContent',
|
|
'updatePropertyByID': 'update attribute',
|
|
'deletePropertyByID': 'delete attribute',
|
|
'updateStylesByID': 'update styles',
|
|
'updateInnerHTMLByID': 'set innerHTML',
|
|
'dangerouslyReplaceNodeWithMarkupByID': 'replace'
|
|
};
|
|
|
|
function getTotalTime(measurements) {
|
|
// TODO: return number of DOM ops? could be misleading.
|
|
// TODO: measure dropped frames after reconcile?
|
|
// TODO: log total time of each reconcile and the top-level component
|
|
// class that triggered it.
|
|
var totalTime = 0;
|
|
for (var i = 0; i < measurements.length; i++) {
|
|
var measurement = measurements[i];
|
|
totalTime += measurement.totalTime;
|
|
}
|
|
return totalTime;
|
|
}
|
|
|
|
function getDOMSummary(measurements) {
|
|
var items = [];
|
|
for (var i = 0; i < measurements.length; i++) {
|
|
var measurement = measurements[i];
|
|
var id;
|
|
|
|
for (id in measurement.writes) {
|
|
measurement.writes[id].forEach(function(write) {
|
|
items.push({
|
|
id: id,
|
|
type: DOM_OPERATION_TYPES[write.type] || write.type,
|
|
args: write.args
|
|
});
|
|
});
|
|
}
|
|
}
|
|
return items;
|
|
}
|
|
|
|
function getExclusiveSummary(measurements) {
|
|
var candidates = {};
|
|
var displayName;
|
|
|
|
for (var i = 0; i < measurements.length; i++) {
|
|
var measurement = measurements[i];
|
|
var allIDs = assign(
|
|
{},
|
|
measurement.exclusive,
|
|
measurement.inclusive
|
|
);
|
|
|
|
for (var id in allIDs) {
|
|
displayName = measurement.displayNames[id].current;
|
|
|
|
candidates[displayName] = candidates[displayName] || {
|
|
componentName: displayName,
|
|
inclusive: 0,
|
|
exclusive: 0,
|
|
render: 0,
|
|
count: 0
|
|
};
|
|
if (measurement.render[id]) {
|
|
candidates[displayName].render += measurement.render[id];
|
|
}
|
|
if (measurement.exclusive[id]) {
|
|
candidates[displayName].exclusive += measurement.exclusive[id];
|
|
}
|
|
if (measurement.inclusive[id]) {
|
|
candidates[displayName].inclusive += measurement.inclusive[id];
|
|
}
|
|
if (measurement.counts[id]) {
|
|
candidates[displayName].count += measurement.counts[id];
|
|
}
|
|
}
|
|
}
|
|
|
|
// Now make a sorted array with the results.
|
|
var arr = [];
|
|
for (displayName in candidates) {
|
|
if (candidates[displayName].exclusive >= DONT_CARE_THRESHOLD) {
|
|
arr.push(candidates[displayName]);
|
|
}
|
|
}
|
|
|
|
arr.sort(function(a, b) {
|
|
return b.exclusive - a.exclusive;
|
|
});
|
|
|
|
return arr;
|
|
}
|
|
|
|
function getInclusiveSummary(measurements, onlyClean) {
|
|
var candidates = {};
|
|
var inclusiveKey;
|
|
|
|
for (var i = 0; i < measurements.length; i++) {
|
|
var measurement = measurements[i];
|
|
var allIDs = assign(
|
|
{},
|
|
measurement.exclusive,
|
|
measurement.inclusive
|
|
);
|
|
var cleanComponents;
|
|
|
|
if (onlyClean) {
|
|
cleanComponents = getUnchangedComponents(measurement);
|
|
}
|
|
|
|
for (var id in allIDs) {
|
|
if (onlyClean && !cleanComponents[id]) {
|
|
continue;
|
|
}
|
|
|
|
var displayName = measurement.displayNames[id];
|
|
|
|
// Inclusive time is not useful for many components without knowing where
|
|
// they are instantiated. So we aggregate inclusive time with both the
|
|
// owner and current displayName as the key.
|
|
inclusiveKey = displayName.owner + ' > ' + displayName.current;
|
|
|
|
candidates[inclusiveKey] = candidates[inclusiveKey] || {
|
|
componentName: inclusiveKey,
|
|
time: 0,
|
|
count: 0
|
|
};
|
|
|
|
if (measurement.inclusive[id]) {
|
|
candidates[inclusiveKey].time += measurement.inclusive[id];
|
|
}
|
|
if (measurement.counts[id]) {
|
|
candidates[inclusiveKey].count += measurement.counts[id];
|
|
}
|
|
}
|
|
}
|
|
|
|
// Now make a sorted array with the results.
|
|
var arr = [];
|
|
for (inclusiveKey in candidates) {
|
|
if (candidates[inclusiveKey].time >= DONT_CARE_THRESHOLD) {
|
|
arr.push(candidates[inclusiveKey]);
|
|
}
|
|
}
|
|
|
|
arr.sort(function(a, b) {
|
|
return b.time - a.time;
|
|
});
|
|
|
|
return arr;
|
|
}
|
|
|
|
function getUnchangedComponents(measurement) {
|
|
// For a given reconcile, look at which components did not actually
|
|
// render anything to the DOM and return a mapping of their ID to
|
|
// the amount of time it took to render the entire subtree.
|
|
var cleanComponents = {};
|
|
var dirtyLeafIDs = Object.keys(measurement.writes);
|
|
var allIDs = assign({}, measurement.exclusive, measurement.inclusive);
|
|
|
|
for (var id in allIDs) {
|
|
var isDirty = false;
|
|
// For each component that rendered, see if a component that triggered
|
|
// a DOM op is in its subtree.
|
|
for (var i = 0; i < dirtyLeafIDs.length; i++) {
|
|
if (dirtyLeafIDs[i].indexOf(id) === 0) {
|
|
isDirty = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!isDirty && measurement.counts[id] > 0) {
|
|
cleanComponents[id] = true;
|
|
}
|
|
}
|
|
return cleanComponents;
|
|
}
|
|
|
|
var ReactDefaultPerfAnalysis = {
|
|
getExclusiveSummary: getExclusiveSummary,
|
|
getInclusiveSummary: getInclusiveSummary,
|
|
getDOMSummary: getDOMSummary,
|
|
getTotalTime: getTotalTime
|
|
};
|
|
|
|
module.exports = ReactDefaultPerfAnalysis;
|
|
|
|
},{"./Object.assign":76}],107:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2014-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactElement
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactContext = require("./ReactContext");
|
|
var ReactCurrentOwner = require("./ReactCurrentOwner");
|
|
|
|
var assign = require("./Object.assign");
|
|
var warning = require("./warning");
|
|
|
|
var RESERVED_PROPS = {
|
|
key: true,
|
|
ref: true
|
|
};
|
|
|
|
/**
|
|
* Warn for mutations.
|
|
*
|
|
* @internal
|
|
* @param {object} object
|
|
* @param {string} key
|
|
*/
|
|
function defineWarningProperty(object, key) {
|
|
Object.defineProperty(object, key, {
|
|
|
|
configurable: false,
|
|
enumerable: true,
|
|
|
|
get: function() {
|
|
if (!this._store) {
|
|
return null;
|
|
}
|
|
return this._store[key];
|
|
},
|
|
|
|
set: function(value) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
false,
|
|
'Don\'t set the %s property of the React element. Instead, ' +
|
|
'specify the correct value when initially creating the element.',
|
|
key
|
|
) : null);
|
|
this._store[key] = value;
|
|
}
|
|
|
|
});
|
|
}
|
|
|
|
/**
|
|
* This is updated to true if the membrane is successfully created.
|
|
*/
|
|
var useMutationMembrane = false;
|
|
|
|
/**
|
|
* Warn for mutations.
|
|
*
|
|
* @internal
|
|
* @param {object} element
|
|
*/
|
|
function defineMutationMembrane(prototype) {
|
|
try {
|
|
var pseudoFrozenProperties = {
|
|
props: true
|
|
};
|
|
for (var key in pseudoFrozenProperties) {
|
|
defineWarningProperty(prototype, key);
|
|
}
|
|
useMutationMembrane = true;
|
|
} catch (x) {
|
|
// IE will fail on defineProperty
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Base constructor for all React elements. This is only used to make this
|
|
* work with a dynamic instanceof check. Nothing should live on this prototype.
|
|
*
|
|
* @param {*} type
|
|
* @param {string|object} ref
|
|
* @param {*} key
|
|
* @param {*} props
|
|
* @internal
|
|
*/
|
|
var ReactElement = function(type, key, ref, owner, context, props) {
|
|
// Built-in properties that belong on the element
|
|
this.type = type;
|
|
this.key = key;
|
|
this.ref = ref;
|
|
|
|
// Record the component responsible for creating this element.
|
|
this._owner = owner;
|
|
|
|
// TODO: Deprecate withContext, and then the context becomes accessible
|
|
// through the owner.
|
|
this._context = context;
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
// The validation flag and props are currently mutative. We put them on
|
|
// an external backing store so that we can freeze the whole object.
|
|
// This can be replaced with a WeakMap once they are implemented in
|
|
// commonly used development environments.
|
|
this._store = {props: props, originalProps: assign({}, props)};
|
|
|
|
// To make comparing ReactElements easier for testing purposes, we make
|
|
// the validation flag non-enumerable (where possible, which should
|
|
// include every environment we run tests in), so the test framework
|
|
// ignores it.
|
|
try {
|
|
Object.defineProperty(this._store, 'validated', {
|
|
configurable: false,
|
|
enumerable: false,
|
|
writable: true
|
|
});
|
|
} catch (x) {
|
|
}
|
|
this._store.validated = false;
|
|
|
|
// We're not allowed to set props directly on the object so we early
|
|
// return and rely on the prototype membrane to forward to the backing
|
|
// store.
|
|
if (useMutationMembrane) {
|
|
Object.freeze(this);
|
|
return;
|
|
}
|
|
}
|
|
|
|
this.props = props;
|
|
};
|
|
|
|
// We intentionally don't expose the function on the constructor property.
|
|
// ReactElement should be indistinguishable from a plain object.
|
|
ReactElement.prototype = {
|
|
_isReactElement: true
|
|
};
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
defineMutationMembrane(ReactElement.prototype);
|
|
}
|
|
|
|
ReactElement.createElement = function(type, config, children) {
|
|
var propName;
|
|
|
|
// Reserved names are extracted
|
|
var props = {};
|
|
|
|
var key = null;
|
|
var ref = null;
|
|
|
|
if (config != null) {
|
|
ref = config.ref === undefined ? null : config.ref;
|
|
key = config.key === undefined ? null : '' + config.key;
|
|
// Remaining properties are added to a new props object
|
|
for (propName in config) {
|
|
if (config.hasOwnProperty(propName) &&
|
|
!RESERVED_PROPS.hasOwnProperty(propName)) {
|
|
props[propName] = config[propName];
|
|
}
|
|
}
|
|
}
|
|
|
|
// Children can be more than one argument, and those are transferred onto
|
|
// the newly allocated props object.
|
|
var childrenLength = arguments.length - 2;
|
|
if (childrenLength === 1) {
|
|
props.children = children;
|
|
} else if (childrenLength > 1) {
|
|
var childArray = Array(childrenLength);
|
|
for (var i = 0; i < childrenLength; i++) {
|
|
childArray[i] = arguments[i + 2];
|
|
}
|
|
props.children = childArray;
|
|
}
|
|
|
|
// Resolve default props
|
|
if (type && type.defaultProps) {
|
|
var defaultProps = type.defaultProps;
|
|
for (propName in defaultProps) {
|
|
if (typeof props[propName] === 'undefined') {
|
|
props[propName] = defaultProps[propName];
|
|
}
|
|
}
|
|
}
|
|
|
|
return new ReactElement(
|
|
type,
|
|
key,
|
|
ref,
|
|
ReactCurrentOwner.current,
|
|
ReactContext.current,
|
|
props
|
|
);
|
|
};
|
|
|
|
ReactElement.createFactory = function(type) {
|
|
var factory = ReactElement.createElement.bind(null, type);
|
|
// Expose the type on the factory and the prototype so that it can be
|
|
// easily accessed on elements. E.g. <Foo />.type === Foo.type.
|
|
// This should not be named `constructor` since this may not be the function
|
|
// that created the element, and it may not even be a constructor.
|
|
// Legacy hook TODO: Warn if this is accessed
|
|
factory.type = type;
|
|
return factory;
|
|
};
|
|
|
|
ReactElement.cloneAndReplaceProps = function(oldElement, newProps) {
|
|
var newElement = new ReactElement(
|
|
oldElement.type,
|
|
oldElement.key,
|
|
oldElement.ref,
|
|
oldElement._owner,
|
|
oldElement._context,
|
|
newProps
|
|
);
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
// If the key on the original is valid, then the clone is valid
|
|
newElement._store.validated = oldElement._store.validated;
|
|
}
|
|
return newElement;
|
|
};
|
|
|
|
ReactElement.cloneElement = function(element, config, children) {
|
|
var propName;
|
|
|
|
// Original props are copied
|
|
var props = assign({}, element.props);
|
|
|
|
// Reserved names are extracted
|
|
var key = element.key;
|
|
var ref = element.ref;
|
|
|
|
// Owner will be preserved, unless ref is overridden
|
|
var owner = element._owner;
|
|
|
|
if (config != null) {
|
|
if (config.ref !== undefined) {
|
|
// Silently steal the ref from the parent.
|
|
ref = config.ref;
|
|
owner = ReactCurrentOwner.current;
|
|
}
|
|
if (config.key !== undefined) {
|
|
key = '' + config.key;
|
|
}
|
|
// Remaining properties override existing props
|
|
for (propName in config) {
|
|
if (config.hasOwnProperty(propName) &&
|
|
!RESERVED_PROPS.hasOwnProperty(propName)) {
|
|
props[propName] = config[propName];
|
|
}
|
|
}
|
|
}
|
|
|
|
// Children can be more than one argument, and those are transferred onto
|
|
// the newly allocated props object.
|
|
var childrenLength = arguments.length - 2;
|
|
if (childrenLength === 1) {
|
|
props.children = children;
|
|
} else if (childrenLength > 1) {
|
|
var childArray = Array(childrenLength);
|
|
for (var i = 0; i < childrenLength; i++) {
|
|
childArray[i] = arguments[i + 2];
|
|
}
|
|
props.children = childArray;
|
|
}
|
|
|
|
return new ReactElement(
|
|
element.type,
|
|
key,
|
|
ref,
|
|
owner,
|
|
element._context,
|
|
props
|
|
);
|
|
};
|
|
|
|
/**
|
|
* @param {?object} object
|
|
* @return {boolean} True if `object` is a valid component.
|
|
* @final
|
|
*/
|
|
ReactElement.isValidElement = function(object) {
|
|
// ReactTestUtils is often used outside of beforeEach where as React is
|
|
// within it. This leads to two different instances of React on the same
|
|
// page. To identify a element from a different React instance we use
|
|
// a flag instead of an instanceof check.
|
|
var isElement = !!(object && object._isReactElement);
|
|
// if (isElement && !(object instanceof ReactElement)) {
|
|
// This is an indicator that you're using multiple versions of React at the
|
|
// same time. This will screw with ownership and stuff. Fix it, please.
|
|
// TODO: We could possibly warn here.
|
|
// }
|
|
return isElement;
|
|
};
|
|
|
|
module.exports = ReactElement;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./Object.assign":76,"./ReactContext":88,"./ReactCurrentOwner":89,"./warning":204,"_process":1}],108:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2014-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactElementValidator
|
|
*/
|
|
|
|
/**
|
|
* ReactElementValidator provides a wrapper around a element factory
|
|
* which validates the props passed to the element. This is intended to be
|
|
* used only in DEV and could be replaced by a static type checker for languages
|
|
* that support it.
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactElement = require("./ReactElement");
|
|
var ReactFragment = require("./ReactFragment");
|
|
var ReactPropTypeLocations = require("./ReactPropTypeLocations");
|
|
var ReactPropTypeLocationNames = require("./ReactPropTypeLocationNames");
|
|
var ReactCurrentOwner = require("./ReactCurrentOwner");
|
|
var ReactNativeComponent = require("./ReactNativeComponent");
|
|
|
|
var getIteratorFn = require("./getIteratorFn");
|
|
var invariant = require("./invariant");
|
|
var warning = require("./warning");
|
|
|
|
function getDeclarationErrorAddendum() {
|
|
if (ReactCurrentOwner.current) {
|
|
var name = ReactCurrentOwner.current.getName();
|
|
if (name) {
|
|
return ' Check the render method of `' + name + '`.';
|
|
}
|
|
}
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* Warn if there's no key explicitly set on dynamic arrays of children or
|
|
* object keys are not valid. This allows us to keep track of children between
|
|
* updates.
|
|
*/
|
|
var ownerHasKeyUseWarning = {};
|
|
|
|
var loggedTypeFailures = {};
|
|
|
|
var NUMERIC_PROPERTY_REGEX = /^\d+$/;
|
|
|
|
/**
|
|
* Gets the instance's name for use in warnings.
|
|
*
|
|
* @internal
|
|
* @return {?string} Display name or undefined
|
|
*/
|
|
function getName(instance) {
|
|
var publicInstance = instance && instance.getPublicInstance();
|
|
if (!publicInstance) {
|
|
return undefined;
|
|
}
|
|
var constructor = publicInstance.constructor;
|
|
if (!constructor) {
|
|
return undefined;
|
|
}
|
|
return constructor.displayName || constructor.name || undefined;
|
|
}
|
|
|
|
/**
|
|
* Gets the current owner's displayName for use in warnings.
|
|
*
|
|
* @internal
|
|
* @return {?string} Display name or undefined
|
|
*/
|
|
function getCurrentOwnerDisplayName() {
|
|
var current = ReactCurrentOwner.current;
|
|
return (
|
|
current && getName(current) || undefined
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Warn if the element doesn't have an explicit key assigned to it.
|
|
* This element is in an array. The array could grow and shrink or be
|
|
* reordered. All children that haven't already been validated are required to
|
|
* have a "key" property assigned to it.
|
|
*
|
|
* @internal
|
|
* @param {ReactElement} element Element that requires a key.
|
|
* @param {*} parentType element's parent's type.
|
|
*/
|
|
function validateExplicitKey(element, parentType) {
|
|
if (element._store.validated || element.key != null) {
|
|
return;
|
|
}
|
|
element._store.validated = true;
|
|
|
|
warnAndMonitorForKeyUse(
|
|
'Each child in an array or iterator should have a unique "key" prop.',
|
|
element,
|
|
parentType
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Warn if the key is being defined as an object property but has an incorrect
|
|
* value.
|
|
*
|
|
* @internal
|
|
* @param {string} name Property name of the key.
|
|
* @param {ReactElement} element Component that requires a key.
|
|
* @param {*} parentType element's parent's type.
|
|
*/
|
|
function validatePropertyKey(name, element, parentType) {
|
|
if (!NUMERIC_PROPERTY_REGEX.test(name)) {
|
|
return;
|
|
}
|
|
warnAndMonitorForKeyUse(
|
|
'Child objects should have non-numeric keys so ordering is preserved.',
|
|
element,
|
|
parentType
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Shared warning and monitoring code for the key warnings.
|
|
*
|
|
* @internal
|
|
* @param {string} message The base warning that gets output.
|
|
* @param {ReactElement} element Component that requires a key.
|
|
* @param {*} parentType element's parent's type.
|
|
*/
|
|
function warnAndMonitorForKeyUse(message, element, parentType) {
|
|
var ownerName = getCurrentOwnerDisplayName();
|
|
var parentName = typeof parentType === 'string' ?
|
|
parentType : parentType.displayName || parentType.name;
|
|
|
|
var useName = ownerName || parentName;
|
|
var memoizer = ownerHasKeyUseWarning[message] || (
|
|
(ownerHasKeyUseWarning[message] = {})
|
|
);
|
|
if (memoizer.hasOwnProperty(useName)) {
|
|
return;
|
|
}
|
|
memoizer[useName] = true;
|
|
|
|
var parentOrOwnerAddendum =
|
|
ownerName ? (" Check the render method of " + ownerName + ".") :
|
|
parentName ? (" Check the React.render call using <" + parentName + ">.") :
|
|
'';
|
|
|
|
// Usually the current owner is the offender, but if it accepts children as a
|
|
// property, it may be the creator of the child that's responsible for
|
|
// assigning it a key.
|
|
var childOwnerAddendum = '';
|
|
if (element &&
|
|
element._owner &&
|
|
element._owner !== ReactCurrentOwner.current) {
|
|
// Name of the component that originally created this child.
|
|
var childOwnerName = getName(element._owner);
|
|
|
|
childOwnerAddendum = (" It was passed a child from " + childOwnerName + ".");
|
|
}
|
|
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
false,
|
|
message + '%s%s See https://fb.me/react-warning-keys for more information.',
|
|
parentOrOwnerAddendum,
|
|
childOwnerAddendum
|
|
) : null);
|
|
}
|
|
|
|
/**
|
|
* Ensure that every element either is passed in a static location, in an
|
|
* array with an explicit keys property defined, or in an object literal
|
|
* with valid key property.
|
|
*
|
|
* @internal
|
|
* @param {ReactNode} node Statically passed child of any type.
|
|
* @param {*} parentType node's parent's type.
|
|
*/
|
|
function validateChildKeys(node, parentType) {
|
|
if (Array.isArray(node)) {
|
|
for (var i = 0; i < node.length; i++) {
|
|
var child = node[i];
|
|
if (ReactElement.isValidElement(child)) {
|
|
validateExplicitKey(child, parentType);
|
|
}
|
|
}
|
|
} else if (ReactElement.isValidElement(node)) {
|
|
// This element was passed in a valid location.
|
|
node._store.validated = true;
|
|
} else if (node) {
|
|
var iteratorFn = getIteratorFn(node);
|
|
// Entry iterators provide implicit keys.
|
|
if (iteratorFn) {
|
|
if (iteratorFn !== node.entries) {
|
|
var iterator = iteratorFn.call(node);
|
|
var step;
|
|
while (!(step = iterator.next()).done) {
|
|
if (ReactElement.isValidElement(step.value)) {
|
|
validateExplicitKey(step.value, parentType);
|
|
}
|
|
}
|
|
}
|
|
} else if (typeof node === 'object') {
|
|
var fragment = ReactFragment.extractIfFragment(node);
|
|
for (var key in fragment) {
|
|
if (fragment.hasOwnProperty(key)) {
|
|
validatePropertyKey(key, fragment[key], parentType);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Assert that the props are valid
|
|
*
|
|
* @param {string} componentName Name of the component for error messages.
|
|
* @param {object} propTypes Map of prop name to a ReactPropType
|
|
* @param {object} props
|
|
* @param {string} location e.g. "prop", "context", "child context"
|
|
* @private
|
|
*/
|
|
function checkPropTypes(componentName, propTypes, props, location) {
|
|
for (var propName in propTypes) {
|
|
if (propTypes.hasOwnProperty(propName)) {
|
|
var error;
|
|
// Prop type validation may throw. In case they do, we don't want to
|
|
// fail the render phase where it didn't fail before. So we log it.
|
|
// After these have been cleaned up, we'll let them throw.
|
|
try {
|
|
// This is intentionally an invariant that gets caught. It's the same
|
|
// behavior as without this statement except with a better message.
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
typeof propTypes[propName] === 'function',
|
|
'%s: %s type `%s` is invalid; it must be a function, usually from ' +
|
|
'React.PropTypes.',
|
|
componentName || 'React class',
|
|
ReactPropTypeLocationNames[location],
|
|
propName
|
|
) : invariant(typeof propTypes[propName] === 'function'));
|
|
error = propTypes[propName](props, propName, componentName, location);
|
|
} catch (ex) {
|
|
error = ex;
|
|
}
|
|
if (error instanceof Error && !(error.message in loggedTypeFailures)) {
|
|
// Only monitor this failure once because there tends to be a lot of the
|
|
// same error.
|
|
loggedTypeFailures[error.message] = true;
|
|
|
|
var addendum = getDeclarationErrorAddendum(this);
|
|
("production" !== process.env.NODE_ENV ? warning(false, 'Failed propType: %s%s', error.message, addendum) : null);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var warnedPropsMutations = {};
|
|
|
|
/**
|
|
* Warn about mutating props when setting `propName` on `element`.
|
|
*
|
|
* @param {string} propName The string key within props that was set
|
|
* @param {ReactElement} element
|
|
*/
|
|
function warnForPropsMutation(propName, element) {
|
|
var type = element.type;
|
|
var elementName = typeof type === 'string' ? type : type.displayName;
|
|
var ownerName = element._owner ?
|
|
element._owner.getPublicInstance().constructor.displayName : null;
|
|
|
|
var warningKey = propName + '|' + elementName + '|' + ownerName;
|
|
if (warnedPropsMutations.hasOwnProperty(warningKey)) {
|
|
return;
|
|
}
|
|
warnedPropsMutations[warningKey] = true;
|
|
|
|
var elementInfo = '';
|
|
if (elementName) {
|
|
elementInfo = ' <' + elementName + ' />';
|
|
}
|
|
var ownerInfo = '';
|
|
if (ownerName) {
|
|
ownerInfo = ' The element was created by ' + ownerName + '.';
|
|
}
|
|
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
false,
|
|
'Don\'t set .props.%s of the React component%s. Instead, specify the ' +
|
|
'correct value when initially creating the element or use ' +
|
|
'React.cloneElement to make a new element with updated props.%s',
|
|
propName,
|
|
elementInfo,
|
|
ownerInfo
|
|
) : null);
|
|
}
|
|
|
|
// Inline Object.is polyfill
|
|
function is(a, b) {
|
|
if (a !== a) {
|
|
// NaN
|
|
return b !== b;
|
|
}
|
|
if (a === 0 && b === 0) {
|
|
// +-0
|
|
return 1 / a === 1 / b;
|
|
}
|
|
return a === b;
|
|
}
|
|
|
|
/**
|
|
* Given an element, check if its props have been mutated since element
|
|
* creation (or the last call to this function). In particular, check if any
|
|
* new props have been added, which we can't directly catch by defining warning
|
|
* properties on the props object.
|
|
*
|
|
* @param {ReactElement} element
|
|
*/
|
|
function checkAndWarnForMutatedProps(element) {
|
|
if (!element._store) {
|
|
// Element was created using `new ReactElement` directly or with
|
|
// `ReactElement.createElement`; skip mutation checking
|
|
return;
|
|
}
|
|
|
|
var originalProps = element._store.originalProps;
|
|
var props = element.props;
|
|
|
|
for (var propName in props) {
|
|
if (props.hasOwnProperty(propName)) {
|
|
if (!originalProps.hasOwnProperty(propName) ||
|
|
!is(originalProps[propName], props[propName])) {
|
|
warnForPropsMutation(propName, element);
|
|
|
|
// Copy over the new value so that the two props objects match again
|
|
originalProps[propName] = props[propName];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Given an element, validate that its props follow the propTypes definition,
|
|
* provided by the type.
|
|
*
|
|
* @param {ReactElement} element
|
|
*/
|
|
function validatePropTypes(element) {
|
|
if (element.type == null) {
|
|
// This has already warned. Don't throw.
|
|
return;
|
|
}
|
|
// Extract the component class from the element. Converts string types
|
|
// to a composite class which may have propTypes.
|
|
// TODO: Validating a string's propTypes is not decoupled from the
|
|
// rendering target which is problematic.
|
|
var componentClass = ReactNativeComponent.getComponentClassForElement(
|
|
element
|
|
);
|
|
var name = componentClass.displayName || componentClass.name;
|
|
if (componentClass.propTypes) {
|
|
checkPropTypes(
|
|
name,
|
|
componentClass.propTypes,
|
|
element.props,
|
|
ReactPropTypeLocations.prop
|
|
);
|
|
}
|
|
if (typeof componentClass.getDefaultProps === 'function') {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
componentClass.getDefaultProps.isReactClassApproved,
|
|
'getDefaultProps is only used on classic React.createClass ' +
|
|
'definitions. Use a static property named `defaultProps` instead.'
|
|
) : null);
|
|
}
|
|
}
|
|
|
|
var ReactElementValidator = {
|
|
|
|
checkAndWarnForMutatedProps: checkAndWarnForMutatedProps,
|
|
|
|
createElement: function(type, props, children) {
|
|
// We warn in this case but don't throw. We expect the element creation to
|
|
// succeed and there will likely be errors in render.
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
type != null,
|
|
'React.createElement: type should not be null or undefined. It should ' +
|
|
'be a string (for DOM elements) or a ReactClass (for composite ' +
|
|
'components).'
|
|
) : null);
|
|
|
|
var element = ReactElement.createElement.apply(this, arguments);
|
|
|
|
// The result can be nullish if a mock or a custom function is used.
|
|
// TODO: Drop this when these are no longer allowed as the type argument.
|
|
if (element == null) {
|
|
return element;
|
|
}
|
|
|
|
for (var i = 2; i < arguments.length; i++) {
|
|
validateChildKeys(arguments[i], type);
|
|
}
|
|
|
|
validatePropTypes(element);
|
|
|
|
return element;
|
|
},
|
|
|
|
createFactory: function(type) {
|
|
var validatedFactory = ReactElementValidator.createElement.bind(
|
|
null,
|
|
type
|
|
);
|
|
// Legacy hook TODO: Warn if this is accessed
|
|
validatedFactory.type = type;
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
try {
|
|
Object.defineProperty(
|
|
validatedFactory,
|
|
'type',
|
|
{
|
|
enumerable: false,
|
|
get: function() {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
false,
|
|
'Factory.type is deprecated. Access the class directly ' +
|
|
'before passing it to createFactory.'
|
|
) : null);
|
|
Object.defineProperty(this, 'type', {
|
|
value: type
|
|
});
|
|
return type;
|
|
}
|
|
}
|
|
);
|
|
} catch (x) {
|
|
// IE will fail on defineProperty (es5-shim/sham too)
|
|
}
|
|
}
|
|
|
|
|
|
return validatedFactory;
|
|
},
|
|
|
|
cloneElement: function(element, props, children) {
|
|
var newElement = ReactElement.cloneElement.apply(this, arguments);
|
|
for (var i = 2; i < arguments.length; i++) {
|
|
validateChildKeys(arguments[i], newElement.type);
|
|
}
|
|
validatePropTypes(newElement);
|
|
return newElement;
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = ReactElementValidator;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./ReactCurrentOwner":89,"./ReactElement":107,"./ReactFragment":113,"./ReactNativeComponent":123,"./ReactPropTypeLocationNames":126,"./ReactPropTypeLocations":127,"./getIteratorFn":176,"./invariant":185,"./warning":204,"_process":1}],109:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2014-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactEmptyComponent
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactElement = require("./ReactElement");
|
|
var ReactInstanceMap = require("./ReactInstanceMap");
|
|
|
|
var invariant = require("./invariant");
|
|
|
|
var component;
|
|
// This registry keeps track of the React IDs of the components that rendered to
|
|
// `null` (in reality a placeholder such as `noscript`)
|
|
var nullComponentIDsRegistry = {};
|
|
|
|
var ReactEmptyComponentInjection = {
|
|
injectEmptyComponent: function(emptyComponent) {
|
|
component = ReactElement.createFactory(emptyComponent);
|
|
}
|
|
};
|
|
|
|
var ReactEmptyComponentType = function() {};
|
|
ReactEmptyComponentType.prototype.componentDidMount = function() {
|
|
var internalInstance = ReactInstanceMap.get(this);
|
|
// TODO: Make sure we run these methods in the correct order, we shouldn't
|
|
// need this check. We're going to assume if we're here it means we ran
|
|
// componentWillUnmount already so there is no internal instance (it gets
|
|
// removed as part of the unmounting process).
|
|
if (!internalInstance) {
|
|
return;
|
|
}
|
|
registerNullComponentID(internalInstance._rootNodeID);
|
|
};
|
|
ReactEmptyComponentType.prototype.componentWillUnmount = function() {
|
|
var internalInstance = ReactInstanceMap.get(this);
|
|
// TODO: Get rid of this check. See TODO in componentDidMount.
|
|
if (!internalInstance) {
|
|
return;
|
|
}
|
|
deregisterNullComponentID(internalInstance._rootNodeID);
|
|
};
|
|
ReactEmptyComponentType.prototype.render = function() {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
component,
|
|
'Trying to return null from a render, but no null placeholder component ' +
|
|
'was injected.'
|
|
) : invariant(component));
|
|
return component();
|
|
};
|
|
|
|
var emptyElement = ReactElement.createElement(ReactEmptyComponentType);
|
|
|
|
/**
|
|
* Mark the component as having rendered to null.
|
|
* @param {string} id Component's `_rootNodeID`.
|
|
*/
|
|
function registerNullComponentID(id) {
|
|
nullComponentIDsRegistry[id] = true;
|
|
}
|
|
|
|
/**
|
|
* Unmark the component as having rendered to null: it renders to something now.
|
|
* @param {string} id Component's `_rootNodeID`.
|
|
*/
|
|
function deregisterNullComponentID(id) {
|
|
delete nullComponentIDsRegistry[id];
|
|
}
|
|
|
|
/**
|
|
* @param {string} id Component's `_rootNodeID`.
|
|
* @return {boolean} True if the component is rendered to null.
|
|
*/
|
|
function isNullComponentID(id) {
|
|
return !!nullComponentIDsRegistry[id];
|
|
}
|
|
|
|
var ReactEmptyComponent = {
|
|
emptyElement: emptyElement,
|
|
injection: ReactEmptyComponentInjection,
|
|
isNullComponentID: isNullComponentID
|
|
};
|
|
|
|
module.exports = ReactEmptyComponent;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./ReactElement":107,"./ReactInstanceMap":117,"./invariant":185,"_process":1}],110:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactErrorUtils
|
|
* @typechecks
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
var ReactErrorUtils = {
|
|
/**
|
|
* Creates a guarded version of a function. This is supposed to make debugging
|
|
* of event handlers easier. To aid debugging with the browser's debugger,
|
|
* this currently simply returns the original function.
|
|
*
|
|
* @param {function} func Function to be executed
|
|
* @param {string} name The name of the guard
|
|
* @return {function}
|
|
*/
|
|
guard: function(func, name) {
|
|
return func;
|
|
}
|
|
};
|
|
|
|
module.exports = ReactErrorUtils;
|
|
|
|
},{}],111:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactEventEmitterMixin
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var EventPluginHub = require("./EventPluginHub");
|
|
|
|
function runEventQueueInBatch(events) {
|
|
EventPluginHub.enqueueEvents(events);
|
|
EventPluginHub.processEventQueue();
|
|
}
|
|
|
|
var ReactEventEmitterMixin = {
|
|
|
|
/**
|
|
* Streams a fired top-level event to `EventPluginHub` where plugins have the
|
|
* opportunity to create `ReactEvent`s to be dispatched.
|
|
*
|
|
* @param {string} topLevelType Record from `EventConstants`.
|
|
* @param {object} topLevelTarget The listening component root node.
|
|
* @param {string} topLevelTargetID ID of `topLevelTarget`.
|
|
* @param {object} nativeEvent Native environment event.
|
|
*/
|
|
handleTopLevel: function(
|
|
topLevelType,
|
|
topLevelTarget,
|
|
topLevelTargetID,
|
|
nativeEvent) {
|
|
var events = EventPluginHub.extractEvents(
|
|
topLevelType,
|
|
topLevelTarget,
|
|
topLevelTargetID,
|
|
nativeEvent
|
|
);
|
|
|
|
runEventQueueInBatch(events);
|
|
}
|
|
};
|
|
|
|
module.exports = ReactEventEmitterMixin;
|
|
|
|
},{"./EventPluginHub":66}],112:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactEventListener
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var EventListener = require("./EventListener");
|
|
var ExecutionEnvironment = require("./ExecutionEnvironment");
|
|
var PooledClass = require("./PooledClass");
|
|
var ReactInstanceHandles = require("./ReactInstanceHandles");
|
|
var ReactMount = require("./ReactMount");
|
|
var ReactUpdates = require("./ReactUpdates");
|
|
|
|
var assign = require("./Object.assign");
|
|
var getEventTarget = require("./getEventTarget");
|
|
var getUnboundedScrollPosition = require("./getUnboundedScrollPosition");
|
|
|
|
/**
|
|
* Finds the parent React component of `node`.
|
|
*
|
|
* @param {*} node
|
|
* @return {?DOMEventTarget} Parent container, or `null` if the specified node
|
|
* is not nested.
|
|
*/
|
|
function findParent(node) {
|
|
// TODO: It may be a good idea to cache this to prevent unnecessary DOM
|
|
// traversal, but caching is difficult to do correctly without using a
|
|
// mutation observer to listen for all DOM changes.
|
|
var nodeID = ReactMount.getID(node);
|
|
var rootID = ReactInstanceHandles.getReactRootIDFromNodeID(nodeID);
|
|
var container = ReactMount.findReactContainerForID(rootID);
|
|
var parent = ReactMount.getFirstReactDOM(container);
|
|
return parent;
|
|
}
|
|
|
|
// Used to store ancestor hierarchy in top level callback
|
|
function TopLevelCallbackBookKeeping(topLevelType, nativeEvent) {
|
|
this.topLevelType = topLevelType;
|
|
this.nativeEvent = nativeEvent;
|
|
this.ancestors = [];
|
|
}
|
|
assign(TopLevelCallbackBookKeeping.prototype, {
|
|
destructor: function() {
|
|
this.topLevelType = null;
|
|
this.nativeEvent = null;
|
|
this.ancestors.length = 0;
|
|
}
|
|
});
|
|
PooledClass.addPoolingTo(
|
|
TopLevelCallbackBookKeeping,
|
|
PooledClass.twoArgumentPooler
|
|
);
|
|
|
|
function handleTopLevelImpl(bookKeeping) {
|
|
var topLevelTarget = ReactMount.getFirstReactDOM(
|
|
getEventTarget(bookKeeping.nativeEvent)
|
|
) || window;
|
|
|
|
// Loop through the hierarchy, in case there's any nested components.
|
|
// It's important that we build the array of ancestors before calling any
|
|
// event handlers, because event handlers can modify the DOM, leading to
|
|
// inconsistencies with ReactMount's node cache. See #1105.
|
|
var ancestor = topLevelTarget;
|
|
while (ancestor) {
|
|
bookKeeping.ancestors.push(ancestor);
|
|
ancestor = findParent(ancestor);
|
|
}
|
|
|
|
for (var i = 0, l = bookKeeping.ancestors.length; i < l; i++) {
|
|
topLevelTarget = bookKeeping.ancestors[i];
|
|
var topLevelTargetID = ReactMount.getID(topLevelTarget) || '';
|
|
ReactEventListener._handleTopLevel(
|
|
bookKeeping.topLevelType,
|
|
topLevelTarget,
|
|
topLevelTargetID,
|
|
bookKeeping.nativeEvent
|
|
);
|
|
}
|
|
}
|
|
|
|
function scrollValueMonitor(cb) {
|
|
var scrollPosition = getUnboundedScrollPosition(window);
|
|
cb(scrollPosition);
|
|
}
|
|
|
|
var ReactEventListener = {
|
|
_enabled: true,
|
|
_handleTopLevel: null,
|
|
|
|
WINDOW_HANDLE: ExecutionEnvironment.canUseDOM ? window : null,
|
|
|
|
setHandleTopLevel: function(handleTopLevel) {
|
|
ReactEventListener._handleTopLevel = handleTopLevel;
|
|
},
|
|
|
|
setEnabled: function(enabled) {
|
|
ReactEventListener._enabled = !!enabled;
|
|
},
|
|
|
|
isEnabled: function() {
|
|
return ReactEventListener._enabled;
|
|
},
|
|
|
|
|
|
/**
|
|
* Traps top-level events by using event bubbling.
|
|
*
|
|
* @param {string} topLevelType Record from `EventConstants`.
|
|
* @param {string} handlerBaseName Event name (e.g. "click").
|
|
* @param {object} handle Element on which to attach listener.
|
|
* @return {object} An object with a remove function which will forcefully
|
|
* remove the listener.
|
|
* @internal
|
|
*/
|
|
trapBubbledEvent: function(topLevelType, handlerBaseName, handle) {
|
|
var element = handle;
|
|
if (!element) {
|
|
return null;
|
|
}
|
|
return EventListener.listen(
|
|
element,
|
|
handlerBaseName,
|
|
ReactEventListener.dispatchEvent.bind(null, topLevelType)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Traps a top-level event by using event capturing.
|
|
*
|
|
* @param {string} topLevelType Record from `EventConstants`.
|
|
* @param {string} handlerBaseName Event name (e.g. "click").
|
|
* @param {object} handle Element on which to attach listener.
|
|
* @return {object} An object with a remove function which will forcefully
|
|
* remove the listener.
|
|
* @internal
|
|
*/
|
|
trapCapturedEvent: function(topLevelType, handlerBaseName, handle) {
|
|
var element = handle;
|
|
if (!element) {
|
|
return null;
|
|
}
|
|
return EventListener.capture(
|
|
element,
|
|
handlerBaseName,
|
|
ReactEventListener.dispatchEvent.bind(null, topLevelType)
|
|
);
|
|
},
|
|
|
|
monitorScrollValue: function(refresh) {
|
|
var callback = scrollValueMonitor.bind(null, refresh);
|
|
EventListener.listen(window, 'scroll', callback);
|
|
},
|
|
|
|
dispatchEvent: function(topLevelType, nativeEvent) {
|
|
if (!ReactEventListener._enabled) {
|
|
return;
|
|
}
|
|
|
|
var bookKeeping = TopLevelCallbackBookKeeping.getPooled(
|
|
topLevelType,
|
|
nativeEvent
|
|
);
|
|
try {
|
|
// Event queue being processed in the same cycle allows
|
|
// `preventDefault`.
|
|
ReactUpdates.batchedUpdates(handleTopLevelImpl, bookKeeping);
|
|
} finally {
|
|
TopLevelCallbackBookKeeping.release(bookKeeping);
|
|
}
|
|
}
|
|
};
|
|
|
|
module.exports = ReactEventListener;
|
|
|
|
},{"./EventListener":65,"./ExecutionEnvironment":70,"./Object.assign":76,"./PooledClass":77,"./ReactInstanceHandles":116,"./ReactMount":120,"./ReactUpdates":137,"./getEventTarget":175,"./getUnboundedScrollPosition":181}],113:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactFragment
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactElement = require("./ReactElement");
|
|
|
|
var warning = require("./warning");
|
|
|
|
/**
|
|
* We used to allow keyed objects to serve as a collection of ReactElements,
|
|
* or nested sets. This allowed us a way to explicitly key a set a fragment of
|
|
* components. This is now being replaced with an opaque data structure.
|
|
* The upgrade path is to call React.addons.createFragment({ key: value }) to
|
|
* create a keyed fragment. The resulting data structure is opaque, for now.
|
|
*/
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
var fragmentKey = '_reactFragment';
|
|
var didWarnKey = '_reactDidWarn';
|
|
var canWarnForReactFragment = false;
|
|
|
|
try {
|
|
// Feature test. Don't even try to issue this warning if we can't use
|
|
// enumerable: false.
|
|
|
|
var dummy = function() {
|
|
return 1;
|
|
};
|
|
|
|
Object.defineProperty(
|
|
{},
|
|
fragmentKey,
|
|
{enumerable: false, value: true}
|
|
);
|
|
|
|
Object.defineProperty(
|
|
{},
|
|
'key',
|
|
{enumerable: true, get: dummy}
|
|
);
|
|
|
|
canWarnForReactFragment = true;
|
|
} catch (x) { }
|
|
|
|
var proxyPropertyAccessWithWarning = function(obj, key) {
|
|
Object.defineProperty(obj, key, {
|
|
enumerable: true,
|
|
get: function() {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
this[didWarnKey],
|
|
'A ReactFragment is an opaque type. Accessing any of its ' +
|
|
'properties is deprecated. Pass it to one of the React.Children ' +
|
|
'helpers.'
|
|
) : null);
|
|
this[didWarnKey] = true;
|
|
return this[fragmentKey][key];
|
|
},
|
|
set: function(value) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
this[didWarnKey],
|
|
'A ReactFragment is an immutable opaque type. Mutating its ' +
|
|
'properties is deprecated.'
|
|
) : null);
|
|
this[didWarnKey] = true;
|
|
this[fragmentKey][key] = value;
|
|
}
|
|
});
|
|
};
|
|
|
|
var issuedWarnings = {};
|
|
|
|
var didWarnForFragment = function(fragment) {
|
|
// We use the keys and the type of the value as a heuristic to dedupe the
|
|
// warning to avoid spamming too much.
|
|
var fragmentCacheKey = '';
|
|
for (var key in fragment) {
|
|
fragmentCacheKey += key + ':' + (typeof fragment[key]) + ',';
|
|
}
|
|
var alreadyWarnedOnce = !!issuedWarnings[fragmentCacheKey];
|
|
issuedWarnings[fragmentCacheKey] = true;
|
|
return alreadyWarnedOnce;
|
|
};
|
|
}
|
|
|
|
var ReactFragment = {
|
|
// Wrap a keyed object in an opaque proxy that warns you if you access any
|
|
// of its properties.
|
|
create: function(object) {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
if (typeof object !== 'object' || !object || Array.isArray(object)) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
false,
|
|
'React.addons.createFragment only accepts a single object.',
|
|
object
|
|
) : null);
|
|
return object;
|
|
}
|
|
if (ReactElement.isValidElement(object)) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
false,
|
|
'React.addons.createFragment does not accept a ReactElement ' +
|
|
'without a wrapper object.'
|
|
) : null);
|
|
return object;
|
|
}
|
|
if (canWarnForReactFragment) {
|
|
var proxy = {};
|
|
Object.defineProperty(proxy, fragmentKey, {
|
|
enumerable: false,
|
|
value: object
|
|
});
|
|
Object.defineProperty(proxy, didWarnKey, {
|
|
writable: true,
|
|
enumerable: false,
|
|
value: false
|
|
});
|
|
for (var key in object) {
|
|
proxyPropertyAccessWithWarning(proxy, key);
|
|
}
|
|
Object.preventExtensions(proxy);
|
|
return proxy;
|
|
}
|
|
}
|
|
return object;
|
|
},
|
|
// Extract the original keyed object from the fragment opaque type. Warn if
|
|
// a plain object is passed here.
|
|
extract: function(fragment) {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
if (canWarnForReactFragment) {
|
|
if (!fragment[fragmentKey]) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
didWarnForFragment(fragment),
|
|
'Any use of a keyed object should be wrapped in ' +
|
|
'React.addons.createFragment(object) before being passed as a ' +
|
|
'child.'
|
|
) : null);
|
|
return fragment;
|
|
}
|
|
return fragment[fragmentKey];
|
|
}
|
|
}
|
|
return fragment;
|
|
},
|
|
// Check if this is a fragment and if so, extract the keyed object. If it
|
|
// is a fragment-like object, warn that it should be wrapped. Ignore if we
|
|
// can't determine what kind of object this is.
|
|
extractIfFragment: function(fragment) {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
if (canWarnForReactFragment) {
|
|
// If it is the opaque type, return the keyed object.
|
|
if (fragment[fragmentKey]) {
|
|
return fragment[fragmentKey];
|
|
}
|
|
// Otherwise, check each property if it has an element, if it does
|
|
// it is probably meant as a fragment, so we can warn early. Defer,
|
|
// the warning to extract.
|
|
for (var key in fragment) {
|
|
if (fragment.hasOwnProperty(key) &&
|
|
ReactElement.isValidElement(fragment[key])) {
|
|
// This looks like a fragment object, we should provide an
|
|
// early warning.
|
|
return ReactFragment.extract(fragment);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return fragment;
|
|
}
|
|
};
|
|
|
|
module.exports = ReactFragment;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./ReactElement":107,"./warning":204,"_process":1}],114:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactInjection
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var DOMProperty = require("./DOMProperty");
|
|
var EventPluginHub = require("./EventPluginHub");
|
|
var ReactComponentEnvironment = require("./ReactComponentEnvironment");
|
|
var ReactClass = require("./ReactClass");
|
|
var ReactEmptyComponent = require("./ReactEmptyComponent");
|
|
var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter");
|
|
var ReactNativeComponent = require("./ReactNativeComponent");
|
|
var ReactDOMComponent = require("./ReactDOMComponent");
|
|
var ReactPerf = require("./ReactPerf");
|
|
var ReactRootIndex = require("./ReactRootIndex");
|
|
var ReactUpdates = require("./ReactUpdates");
|
|
|
|
var ReactInjection = {
|
|
Component: ReactComponentEnvironment.injection,
|
|
Class: ReactClass.injection,
|
|
DOMComponent: ReactDOMComponent.injection,
|
|
DOMProperty: DOMProperty.injection,
|
|
EmptyComponent: ReactEmptyComponent.injection,
|
|
EventPluginHub: EventPluginHub.injection,
|
|
EventEmitter: ReactBrowserEventEmitter.injection,
|
|
NativeComponent: ReactNativeComponent.injection,
|
|
Perf: ReactPerf.injection,
|
|
RootIndex: ReactRootIndex.injection,
|
|
Updates: ReactUpdates.injection
|
|
};
|
|
|
|
module.exports = ReactInjection;
|
|
|
|
},{"./DOMProperty":59,"./EventPluginHub":66,"./ReactBrowserEventEmitter":80,"./ReactClass":83,"./ReactComponentEnvironment":86,"./ReactDOMComponent":92,"./ReactEmptyComponent":109,"./ReactNativeComponent":123,"./ReactPerf":125,"./ReactRootIndex":133,"./ReactUpdates":137}],115:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactInputSelection
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactDOMSelection = require("./ReactDOMSelection");
|
|
|
|
var containsNode = require("./containsNode");
|
|
var focusNode = require("./focusNode");
|
|
var getActiveElement = require("./getActiveElement");
|
|
|
|
function isInDocument(node) {
|
|
return containsNode(document.documentElement, node);
|
|
}
|
|
|
|
/**
|
|
* @ReactInputSelection: React input selection module. Based on Selection.js,
|
|
* but modified to be suitable for react and has a couple of bug fixes (doesn't
|
|
* assume buttons have range selections allowed).
|
|
* Input selection module for React.
|
|
*/
|
|
var ReactInputSelection = {
|
|
|
|
hasSelectionCapabilities: function(elem) {
|
|
return elem && (
|
|
((elem.nodeName === 'INPUT' && elem.type === 'text') ||
|
|
elem.nodeName === 'TEXTAREA' || elem.contentEditable === 'true')
|
|
);
|
|
},
|
|
|
|
getSelectionInformation: function() {
|
|
var focusedElem = getActiveElement();
|
|
return {
|
|
focusedElem: focusedElem,
|
|
selectionRange:
|
|
ReactInputSelection.hasSelectionCapabilities(focusedElem) ?
|
|
ReactInputSelection.getSelection(focusedElem) :
|
|
null
|
|
};
|
|
},
|
|
|
|
/**
|
|
* @restoreSelection: If any selection information was potentially lost,
|
|
* restore it. This is useful when performing operations that could remove dom
|
|
* nodes and place them back in, resulting in focus being lost.
|
|
*/
|
|
restoreSelection: function(priorSelectionInformation) {
|
|
var curFocusedElem = getActiveElement();
|
|
var priorFocusedElem = priorSelectionInformation.focusedElem;
|
|
var priorSelectionRange = priorSelectionInformation.selectionRange;
|
|
if (curFocusedElem !== priorFocusedElem &&
|
|
isInDocument(priorFocusedElem)) {
|
|
if (ReactInputSelection.hasSelectionCapabilities(priorFocusedElem)) {
|
|
ReactInputSelection.setSelection(
|
|
priorFocusedElem,
|
|
priorSelectionRange
|
|
);
|
|
}
|
|
focusNode(priorFocusedElem);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @getSelection: Gets the selection bounds of a focused textarea, input or
|
|
* contentEditable node.
|
|
* -@input: Look up selection bounds of this input
|
|
* -@return {start: selectionStart, end: selectionEnd}
|
|
*/
|
|
getSelection: function(input) {
|
|
var selection;
|
|
|
|
if ('selectionStart' in input) {
|
|
// Modern browser with input or textarea.
|
|
selection = {
|
|
start: input.selectionStart,
|
|
end: input.selectionEnd
|
|
};
|
|
} else if (document.selection && input.nodeName === 'INPUT') {
|
|
// IE8 input.
|
|
var range = document.selection.createRange();
|
|
// There can only be one selection per document in IE, so it must
|
|
// be in our element.
|
|
if (range.parentElement() === input) {
|
|
selection = {
|
|
start: -range.moveStart('character', -input.value.length),
|
|
end: -range.moveEnd('character', -input.value.length)
|
|
};
|
|
}
|
|
} else {
|
|
// Content editable or old IE textarea.
|
|
selection = ReactDOMSelection.getOffsets(input);
|
|
}
|
|
|
|
return selection || {start: 0, end: 0};
|
|
},
|
|
|
|
/**
|
|
* @setSelection: Sets the selection bounds of a textarea or input and focuses
|
|
* the input.
|
|
* -@input Set selection bounds of this input or textarea
|
|
* -@offsets Object of same form that is returned from get*
|
|
*/
|
|
setSelection: function(input, offsets) {
|
|
var start = offsets.start;
|
|
var end = offsets.end;
|
|
if (typeof end === 'undefined') {
|
|
end = start;
|
|
}
|
|
|
|
if ('selectionStart' in input) {
|
|
input.selectionStart = start;
|
|
input.selectionEnd = Math.min(end, input.value.length);
|
|
} else if (document.selection && input.nodeName === 'INPUT') {
|
|
var range = input.createTextRange();
|
|
range.collapse(true);
|
|
range.moveStart('character', start);
|
|
range.moveEnd('character', end - start);
|
|
range.select();
|
|
} else {
|
|
ReactDOMSelection.setOffsets(input, offsets);
|
|
}
|
|
}
|
|
};
|
|
|
|
module.exports = ReactInputSelection;
|
|
|
|
},{"./ReactDOMSelection":100,"./containsNode":159,"./focusNode":169,"./getActiveElement":171}],116:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactInstanceHandles
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactRootIndex = require("./ReactRootIndex");
|
|
|
|
var invariant = require("./invariant");
|
|
|
|
var SEPARATOR = '.';
|
|
var SEPARATOR_LENGTH = SEPARATOR.length;
|
|
|
|
/**
|
|
* Maximum depth of traversals before we consider the possibility of a bad ID.
|
|
*/
|
|
var MAX_TREE_DEPTH = 100;
|
|
|
|
/**
|
|
* Creates a DOM ID prefix to use when mounting React components.
|
|
*
|
|
* @param {number} index A unique integer
|
|
* @return {string} React root ID.
|
|
* @internal
|
|
*/
|
|
function getReactRootIDString(index) {
|
|
return SEPARATOR + index.toString(36);
|
|
}
|
|
|
|
/**
|
|
* Checks if a character in the supplied ID is a separator or the end.
|
|
*
|
|
* @param {string} id A React DOM ID.
|
|
* @param {number} index Index of the character to check.
|
|
* @return {boolean} True if the character is a separator or end of the ID.
|
|
* @private
|
|
*/
|
|
function isBoundary(id, index) {
|
|
return id.charAt(index) === SEPARATOR || index === id.length;
|
|
}
|
|
|
|
/**
|
|
* Checks if the supplied string is a valid React DOM ID.
|
|
*
|
|
* @param {string} id A React DOM ID, maybe.
|
|
* @return {boolean} True if the string is a valid React DOM ID.
|
|
* @private
|
|
*/
|
|
function isValidID(id) {
|
|
return id === '' || (
|
|
id.charAt(0) === SEPARATOR && id.charAt(id.length - 1) !== SEPARATOR
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Checks if the first ID is an ancestor of or equal to the second ID.
|
|
*
|
|
* @param {string} ancestorID
|
|
* @param {string} descendantID
|
|
* @return {boolean} True if `ancestorID` is an ancestor of `descendantID`.
|
|
* @internal
|
|
*/
|
|
function isAncestorIDOf(ancestorID, descendantID) {
|
|
return (
|
|
descendantID.indexOf(ancestorID) === 0 &&
|
|
isBoundary(descendantID, ancestorID.length)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Gets the parent ID of the supplied React DOM ID, `id`.
|
|
*
|
|
* @param {string} id ID of a component.
|
|
* @return {string} ID of the parent, or an empty string.
|
|
* @private
|
|
*/
|
|
function getParentID(id) {
|
|
return id ? id.substr(0, id.lastIndexOf(SEPARATOR)) : '';
|
|
}
|
|
|
|
/**
|
|
* Gets the next DOM ID on the tree path from the supplied `ancestorID` to the
|
|
* supplied `destinationID`. If they are equal, the ID is returned.
|
|
*
|
|
* @param {string} ancestorID ID of an ancestor node of `destinationID`.
|
|
* @param {string} destinationID ID of the destination node.
|
|
* @return {string} Next ID on the path from `ancestorID` to `destinationID`.
|
|
* @private
|
|
*/
|
|
function getNextDescendantID(ancestorID, destinationID) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
isValidID(ancestorID) && isValidID(destinationID),
|
|
'getNextDescendantID(%s, %s): Received an invalid React DOM ID.',
|
|
ancestorID,
|
|
destinationID
|
|
) : invariant(isValidID(ancestorID) && isValidID(destinationID)));
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
isAncestorIDOf(ancestorID, destinationID),
|
|
'getNextDescendantID(...): React has made an invalid assumption about ' +
|
|
'the DOM hierarchy. Expected `%s` to be an ancestor of `%s`.',
|
|
ancestorID,
|
|
destinationID
|
|
) : invariant(isAncestorIDOf(ancestorID, destinationID)));
|
|
if (ancestorID === destinationID) {
|
|
return ancestorID;
|
|
}
|
|
// Skip over the ancestor and the immediate separator. Traverse until we hit
|
|
// another separator or we reach the end of `destinationID`.
|
|
var start = ancestorID.length + SEPARATOR_LENGTH;
|
|
var i;
|
|
for (i = start; i < destinationID.length; i++) {
|
|
if (isBoundary(destinationID, i)) {
|
|
break;
|
|
}
|
|
}
|
|
return destinationID.substr(0, i);
|
|
}
|
|
|
|
/**
|
|
* Gets the nearest common ancestor ID of two IDs.
|
|
*
|
|
* Using this ID scheme, the nearest common ancestor ID is the longest common
|
|
* prefix of the two IDs that immediately preceded a "marker" in both strings.
|
|
*
|
|
* @param {string} oneID
|
|
* @param {string} twoID
|
|
* @return {string} Nearest common ancestor ID, or the empty string if none.
|
|
* @private
|
|
*/
|
|
function getFirstCommonAncestorID(oneID, twoID) {
|
|
var minLength = Math.min(oneID.length, twoID.length);
|
|
if (minLength === 0) {
|
|
return '';
|
|
}
|
|
var lastCommonMarkerIndex = 0;
|
|
// Use `<=` to traverse until the "EOL" of the shorter string.
|
|
for (var i = 0; i <= minLength; i++) {
|
|
if (isBoundary(oneID, i) && isBoundary(twoID, i)) {
|
|
lastCommonMarkerIndex = i;
|
|
} else if (oneID.charAt(i) !== twoID.charAt(i)) {
|
|
break;
|
|
}
|
|
}
|
|
var longestCommonID = oneID.substr(0, lastCommonMarkerIndex);
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
isValidID(longestCommonID),
|
|
'getFirstCommonAncestorID(%s, %s): Expected a valid React DOM ID: %s',
|
|
oneID,
|
|
twoID,
|
|
longestCommonID
|
|
) : invariant(isValidID(longestCommonID)));
|
|
return longestCommonID;
|
|
}
|
|
|
|
/**
|
|
* Traverses the parent path between two IDs (either up or down). The IDs must
|
|
* not be the same, and there must exist a parent path between them. If the
|
|
* callback returns `false`, traversal is stopped.
|
|
*
|
|
* @param {?string} start ID at which to start traversal.
|
|
* @param {?string} stop ID at which to end traversal.
|
|
* @param {function} cb Callback to invoke each ID with.
|
|
* @param {?boolean} skipFirst Whether or not to skip the first node.
|
|
* @param {?boolean} skipLast Whether or not to skip the last node.
|
|
* @private
|
|
*/
|
|
function traverseParentPath(start, stop, cb, arg, skipFirst, skipLast) {
|
|
start = start || '';
|
|
stop = stop || '';
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
start !== stop,
|
|
'traverseParentPath(...): Cannot traverse from and to the same ID, `%s`.',
|
|
start
|
|
) : invariant(start !== stop));
|
|
var traverseUp = isAncestorIDOf(stop, start);
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
traverseUp || isAncestorIDOf(start, stop),
|
|
'traverseParentPath(%s, %s, ...): Cannot traverse from two IDs that do ' +
|
|
'not have a parent path.',
|
|
start,
|
|
stop
|
|
) : invariant(traverseUp || isAncestorIDOf(start, stop)));
|
|
// Traverse from `start` to `stop` one depth at a time.
|
|
var depth = 0;
|
|
var traverse = traverseUp ? getParentID : getNextDescendantID;
|
|
for (var id = start; /* until break */; id = traverse(id, stop)) {
|
|
var ret;
|
|
if ((!skipFirst || id !== start) && (!skipLast || id !== stop)) {
|
|
ret = cb(id, traverseUp, arg);
|
|
}
|
|
if (ret === false || id === stop) {
|
|
// Only break //after// visiting `stop`.
|
|
break;
|
|
}
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
depth++ < MAX_TREE_DEPTH,
|
|
'traverseParentPath(%s, %s, ...): Detected an infinite loop while ' +
|
|
'traversing the React DOM ID tree. This may be due to malformed IDs: %s',
|
|
start, stop
|
|
) : invariant(depth++ < MAX_TREE_DEPTH));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Manages the IDs assigned to DOM representations of React components. This
|
|
* uses a specific scheme in order to traverse the DOM efficiently (e.g. in
|
|
* order to simulate events).
|
|
*
|
|
* @internal
|
|
*/
|
|
var ReactInstanceHandles = {
|
|
|
|
/**
|
|
* Constructs a React root ID
|
|
* @return {string} A React root ID.
|
|
*/
|
|
createReactRootID: function() {
|
|
return getReactRootIDString(ReactRootIndex.createReactRootIndex());
|
|
},
|
|
|
|
/**
|
|
* Constructs a React ID by joining a root ID with a name.
|
|
*
|
|
* @param {string} rootID Root ID of a parent component.
|
|
* @param {string} name A component's name (as flattened children).
|
|
* @return {string} A React ID.
|
|
* @internal
|
|
*/
|
|
createReactID: function(rootID, name) {
|
|
return rootID + name;
|
|
},
|
|
|
|
/**
|
|
* Gets the DOM ID of the React component that is the root of the tree that
|
|
* contains the React component with the supplied DOM ID.
|
|
*
|
|
* @param {string} id DOM ID of a React component.
|
|
* @return {?string} DOM ID of the React component that is the root.
|
|
* @internal
|
|
*/
|
|
getReactRootIDFromNodeID: function(id) {
|
|
if (id && id.charAt(0) === SEPARATOR && id.length > 1) {
|
|
var index = id.indexOf(SEPARATOR, 1);
|
|
return index > -1 ? id.substr(0, index) : id;
|
|
}
|
|
return null;
|
|
},
|
|
|
|
/**
|
|
* Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
|
|
* should would receive a `mouseEnter` or `mouseLeave` event.
|
|
*
|
|
* NOTE: Does not invoke the callback on the nearest common ancestor because
|
|
* nothing "entered" or "left" that element.
|
|
*
|
|
* @param {string} leaveID ID being left.
|
|
* @param {string} enterID ID being entered.
|
|
* @param {function} cb Callback to invoke on each entered/left ID.
|
|
* @param {*} upArg Argument to invoke the callback with on left IDs.
|
|
* @param {*} downArg Argument to invoke the callback with on entered IDs.
|
|
* @internal
|
|
*/
|
|
traverseEnterLeave: function(leaveID, enterID, cb, upArg, downArg) {
|
|
var ancestorID = getFirstCommonAncestorID(leaveID, enterID);
|
|
if (ancestorID !== leaveID) {
|
|
traverseParentPath(leaveID, ancestorID, cb, upArg, false, true);
|
|
}
|
|
if (ancestorID !== enterID) {
|
|
traverseParentPath(ancestorID, enterID, cb, downArg, true, false);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Simulates the traversal of a two-phase, capture/bubble event dispatch.
|
|
*
|
|
* NOTE: This traversal happens on IDs without touching the DOM.
|
|
*
|
|
* @param {string} targetID ID of the target node.
|
|
* @param {function} cb Callback to invoke.
|
|
* @param {*} arg Argument to invoke the callback with.
|
|
* @internal
|
|
*/
|
|
traverseTwoPhase: function(targetID, cb, arg) {
|
|
if (targetID) {
|
|
traverseParentPath('', targetID, cb, arg, true, false);
|
|
traverseParentPath(targetID, '', cb, arg, false, true);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Traverse a node ID, calling the supplied `cb` for each ancestor ID. For
|
|
* example, passing `.0.$row-0.1` would result in `cb` getting called
|
|
* with `.0`, `.0.$row-0`, and `.0.$row-0.1`.
|
|
*
|
|
* NOTE: This traversal happens on IDs without touching the DOM.
|
|
*
|
|
* @param {string} targetID ID of the target node.
|
|
* @param {function} cb Callback to invoke.
|
|
* @param {*} arg Argument to invoke the callback with.
|
|
* @internal
|
|
*/
|
|
traverseAncestors: function(targetID, cb, arg) {
|
|
traverseParentPath('', targetID, cb, arg, true, false);
|
|
},
|
|
|
|
/**
|
|
* Exposed for unit testing.
|
|
* @private
|
|
*/
|
|
_getFirstCommonAncestorID: getFirstCommonAncestorID,
|
|
|
|
/**
|
|
* Exposed for unit testing.
|
|
* @private
|
|
*/
|
|
_getNextDescendantID: getNextDescendantID,
|
|
|
|
isAncestorIDOf: isAncestorIDOf,
|
|
|
|
SEPARATOR: SEPARATOR
|
|
|
|
};
|
|
|
|
module.exports = ReactInstanceHandles;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./ReactRootIndex":133,"./invariant":185,"_process":1}],117:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactInstanceMap
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* `ReactInstanceMap` maintains a mapping from a public facing stateful
|
|
* instance (key) and the internal representation (value). This allows public
|
|
* methods to accept the user facing instance as an argument and map them back
|
|
* to internal methods.
|
|
*/
|
|
|
|
// TODO: Replace this with ES6: var ReactInstanceMap = new Map();
|
|
var ReactInstanceMap = {
|
|
|
|
/**
|
|
* This API should be called `delete` but we'd have to make sure to always
|
|
* transform these to strings for IE support. When this transform is fully
|
|
* supported we can rename it.
|
|
*/
|
|
remove: function(key) {
|
|
key._reactInternalInstance = undefined;
|
|
},
|
|
|
|
get: function(key) {
|
|
return key._reactInternalInstance;
|
|
},
|
|
|
|
has: function(key) {
|
|
return key._reactInternalInstance !== undefined;
|
|
},
|
|
|
|
set: function(key, value) {
|
|
key._reactInternalInstance = value;
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = ReactInstanceMap;
|
|
|
|
},{}],118:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactLifeCycle
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* This module manages the bookkeeping when a component is in the process
|
|
* of being mounted or being unmounted. This is used as a way to enforce
|
|
* invariants (or warnings) when it is not recommended to call
|
|
* setState/forceUpdate.
|
|
*
|
|
* currentlyMountingInstance: During the construction phase, it is not possible
|
|
* to trigger an update since the instance is not fully mounted yet. However, we
|
|
* currently allow this as a convenience for mutating the initial state.
|
|
*
|
|
* currentlyUnmountingInstance: During the unmounting phase, the instance is
|
|
* still mounted and can therefore schedule an update. However, this is not
|
|
* recommended and probably an error since it's about to be unmounted.
|
|
* Therefore we still want to trigger in an error for that case.
|
|
*/
|
|
|
|
var ReactLifeCycle = {
|
|
currentlyMountingInstance: null,
|
|
currentlyUnmountingInstance: null
|
|
};
|
|
|
|
module.exports = ReactLifeCycle;
|
|
|
|
},{}],119:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactMarkupChecksum
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var adler32 = require("./adler32");
|
|
|
|
var ReactMarkupChecksum = {
|
|
CHECKSUM_ATTR_NAME: 'data-react-checksum',
|
|
|
|
/**
|
|
* @param {string} markup Markup string
|
|
* @return {string} Markup string with checksum attribute attached
|
|
*/
|
|
addChecksumToMarkup: function(markup) {
|
|
var checksum = adler32(markup);
|
|
return markup.replace(
|
|
'>',
|
|
' ' + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + '="' + checksum + '">'
|
|
);
|
|
},
|
|
|
|
/**
|
|
* @param {string} markup to use
|
|
* @param {DOMElement} element root React element
|
|
* @returns {boolean} whether or not the markup is the same
|
|
*/
|
|
canReuseMarkup: function(markup, element) {
|
|
var existingChecksum = element.getAttribute(
|
|
ReactMarkupChecksum.CHECKSUM_ATTR_NAME
|
|
);
|
|
existingChecksum = existingChecksum && parseInt(existingChecksum, 10);
|
|
var markupChecksum = adler32(markup);
|
|
return markupChecksum === existingChecksum;
|
|
}
|
|
};
|
|
|
|
module.exports = ReactMarkupChecksum;
|
|
|
|
},{"./adler32":156}],120:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactMount
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var DOMProperty = require("./DOMProperty");
|
|
var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter");
|
|
var ReactCurrentOwner = require("./ReactCurrentOwner");
|
|
var ReactElement = require("./ReactElement");
|
|
var ReactElementValidator = require("./ReactElementValidator");
|
|
var ReactEmptyComponent = require("./ReactEmptyComponent");
|
|
var ReactInstanceHandles = require("./ReactInstanceHandles");
|
|
var ReactInstanceMap = require("./ReactInstanceMap");
|
|
var ReactMarkupChecksum = require("./ReactMarkupChecksum");
|
|
var ReactPerf = require("./ReactPerf");
|
|
var ReactReconciler = require("./ReactReconciler");
|
|
var ReactUpdateQueue = require("./ReactUpdateQueue");
|
|
var ReactUpdates = require("./ReactUpdates");
|
|
|
|
var emptyObject = require("./emptyObject");
|
|
var containsNode = require("./containsNode");
|
|
var getReactRootElementInContainer = require("./getReactRootElementInContainer");
|
|
var instantiateReactComponent = require("./instantiateReactComponent");
|
|
var invariant = require("./invariant");
|
|
var setInnerHTML = require("./setInnerHTML");
|
|
var shouldUpdateReactComponent = require("./shouldUpdateReactComponent");
|
|
var warning = require("./warning");
|
|
|
|
var SEPARATOR = ReactInstanceHandles.SEPARATOR;
|
|
|
|
var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME;
|
|
var nodeCache = {};
|
|
|
|
var ELEMENT_NODE_TYPE = 1;
|
|
var DOC_NODE_TYPE = 9;
|
|
|
|
/** Mapping from reactRootID to React component instance. */
|
|
var instancesByReactRootID = {};
|
|
|
|
/** Mapping from reactRootID to `container` nodes. */
|
|
var containersByReactRootID = {};
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
/** __DEV__-only mapping from reactRootID to root elements. */
|
|
var rootElementsByReactRootID = {};
|
|
}
|
|
|
|
// Used to store breadth-first search state in findComponentRoot.
|
|
var findComponentRootReusableArray = [];
|
|
|
|
/**
|
|
* Finds the index of the first character
|
|
* that's not common between the two given strings.
|
|
*
|
|
* @return {number} the index of the character where the strings diverge
|
|
*/
|
|
function firstDifferenceIndex(string1, string2) {
|
|
var minLen = Math.min(string1.length, string2.length);
|
|
for (var i = 0; i < minLen; i++) {
|
|
if (string1.charAt(i) !== string2.charAt(i)) {
|
|
return i;
|
|
}
|
|
}
|
|
return string1.length === string2.length ? -1 : minLen;
|
|
}
|
|
|
|
/**
|
|
* @param {DOMElement} container DOM element that may contain a React component.
|
|
* @return {?string} A "reactRoot" ID, if a React component is rendered.
|
|
*/
|
|
function getReactRootID(container) {
|
|
var rootElement = getReactRootElementInContainer(container);
|
|
return rootElement && ReactMount.getID(rootElement);
|
|
}
|
|
|
|
/**
|
|
* Accessing node[ATTR_NAME] or calling getAttribute(ATTR_NAME) on a form
|
|
* element can return its control whose name or ID equals ATTR_NAME. All
|
|
* DOM nodes support `getAttributeNode` but this can also get called on
|
|
* other objects so just return '' if we're given something other than a
|
|
* DOM node (such as window).
|
|
*
|
|
* @param {?DOMElement|DOMWindow|DOMDocument|DOMTextNode} node DOM node.
|
|
* @return {string} ID of the supplied `domNode`.
|
|
*/
|
|
function getID(node) {
|
|
var id = internalGetID(node);
|
|
if (id) {
|
|
if (nodeCache.hasOwnProperty(id)) {
|
|
var cached = nodeCache[id];
|
|
if (cached !== node) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
!isValid(cached, id),
|
|
'ReactMount: Two valid but unequal nodes with the same `%s`: %s',
|
|
ATTR_NAME, id
|
|
) : invariant(!isValid(cached, id)));
|
|
|
|
nodeCache[id] = node;
|
|
}
|
|
} else {
|
|
nodeCache[id] = node;
|
|
}
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
function internalGetID(node) {
|
|
// If node is something like a window, document, or text node, none of
|
|
// which support attributes or a .getAttribute method, gracefully return
|
|
// the empty string, as if the attribute were missing.
|
|
return node && node.getAttribute && node.getAttribute(ATTR_NAME) || '';
|
|
}
|
|
|
|
/**
|
|
* Sets the React-specific ID of the given node.
|
|
*
|
|
* @param {DOMElement} node The DOM node whose ID will be set.
|
|
* @param {string} id The value of the ID attribute.
|
|
*/
|
|
function setID(node, id) {
|
|
var oldID = internalGetID(node);
|
|
if (oldID !== id) {
|
|
delete nodeCache[oldID];
|
|
}
|
|
node.setAttribute(ATTR_NAME, id);
|
|
nodeCache[id] = node;
|
|
}
|
|
|
|
/**
|
|
* Finds the node with the supplied React-generated DOM ID.
|
|
*
|
|
* @param {string} id A React-generated DOM ID.
|
|
* @return {DOMElement} DOM node with the suppled `id`.
|
|
* @internal
|
|
*/
|
|
function getNode(id) {
|
|
if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) {
|
|
nodeCache[id] = ReactMount.findReactNodeByID(id);
|
|
}
|
|
return nodeCache[id];
|
|
}
|
|
|
|
/**
|
|
* Finds the node with the supplied public React instance.
|
|
*
|
|
* @param {*} instance A public React instance.
|
|
* @return {?DOMElement} DOM node with the suppled `id`.
|
|
* @internal
|
|
*/
|
|
function getNodeFromInstance(instance) {
|
|
var id = ReactInstanceMap.get(instance)._rootNodeID;
|
|
if (ReactEmptyComponent.isNullComponentID(id)) {
|
|
return null;
|
|
}
|
|
if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) {
|
|
nodeCache[id] = ReactMount.findReactNodeByID(id);
|
|
}
|
|
return nodeCache[id];
|
|
}
|
|
|
|
/**
|
|
* A node is "valid" if it is contained by a currently mounted container.
|
|
*
|
|
* This means that the node does not have to be contained by a document in
|
|
* order to be considered valid.
|
|
*
|
|
* @param {?DOMElement} node The candidate DOM node.
|
|
* @param {string} id The expected ID of the node.
|
|
* @return {boolean} Whether the node is contained by a mounted container.
|
|
*/
|
|
function isValid(node, id) {
|
|
if (node) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
internalGetID(node) === id,
|
|
'ReactMount: Unexpected modification of `%s`',
|
|
ATTR_NAME
|
|
) : invariant(internalGetID(node) === id));
|
|
|
|
var container = ReactMount.findReactContainerForID(id);
|
|
if (container && containsNode(container, node)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Causes the cache to forget about one React-specific ID.
|
|
*
|
|
* @param {string} id The ID to forget.
|
|
*/
|
|
function purgeID(id) {
|
|
delete nodeCache[id];
|
|
}
|
|
|
|
var deepestNodeSoFar = null;
|
|
function findDeepestCachedAncestorImpl(ancestorID) {
|
|
var ancestor = nodeCache[ancestorID];
|
|
if (ancestor && isValid(ancestor, ancestorID)) {
|
|
deepestNodeSoFar = ancestor;
|
|
} else {
|
|
// This node isn't populated in the cache, so presumably none of its
|
|
// descendants are. Break out of the loop.
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return the deepest cached node whose ID is a prefix of `targetID`.
|
|
*/
|
|
function findDeepestCachedAncestor(targetID) {
|
|
deepestNodeSoFar = null;
|
|
ReactInstanceHandles.traverseAncestors(
|
|
targetID,
|
|
findDeepestCachedAncestorImpl
|
|
);
|
|
|
|
var foundNode = deepestNodeSoFar;
|
|
deepestNodeSoFar = null;
|
|
return foundNode;
|
|
}
|
|
|
|
/**
|
|
* Mounts this component and inserts it into the DOM.
|
|
*
|
|
* @param {ReactComponent} componentInstance The instance to mount.
|
|
* @param {string} rootID DOM ID of the root node.
|
|
* @param {DOMElement} container DOM element to mount into.
|
|
* @param {ReactReconcileTransaction} transaction
|
|
* @param {boolean} shouldReuseMarkup If true, do not insert markup
|
|
*/
|
|
function mountComponentIntoNode(
|
|
componentInstance,
|
|
rootID,
|
|
container,
|
|
transaction,
|
|
shouldReuseMarkup) {
|
|
var markup = ReactReconciler.mountComponent(
|
|
componentInstance, rootID, transaction, emptyObject
|
|
);
|
|
componentInstance._isTopLevel = true;
|
|
ReactMount._mountImageIntoNode(markup, container, shouldReuseMarkup);
|
|
}
|
|
|
|
/**
|
|
* Batched mount.
|
|
*
|
|
* @param {ReactComponent} componentInstance The instance to mount.
|
|
* @param {string} rootID DOM ID of the root node.
|
|
* @param {DOMElement} container DOM element to mount into.
|
|
* @param {boolean} shouldReuseMarkup If true, do not insert markup
|
|
*/
|
|
function batchedMountComponentIntoNode(
|
|
componentInstance,
|
|
rootID,
|
|
container,
|
|
shouldReuseMarkup) {
|
|
var transaction = ReactUpdates.ReactReconcileTransaction.getPooled();
|
|
transaction.perform(
|
|
mountComponentIntoNode,
|
|
null,
|
|
componentInstance,
|
|
rootID,
|
|
container,
|
|
transaction,
|
|
shouldReuseMarkup
|
|
);
|
|
ReactUpdates.ReactReconcileTransaction.release(transaction);
|
|
}
|
|
|
|
/**
|
|
* Mounting is the process of initializing a React component by creating its
|
|
* representative DOM elements and inserting them into a supplied `container`.
|
|
* Any prior content inside `container` is destroyed in the process.
|
|
*
|
|
* ReactMount.render(
|
|
* component,
|
|
* document.getElementById('container')
|
|
* );
|
|
*
|
|
* <div id="container"> <-- Supplied `container`.
|
|
* <div data-reactid=".3"> <-- Rendered reactRoot of React
|
|
* // ... component.
|
|
* </div>
|
|
* </div>
|
|
*
|
|
* Inside of `container`, the first element rendered is the "reactRoot".
|
|
*/
|
|
var ReactMount = {
|
|
/** Exposed for debugging purposes **/
|
|
_instancesByReactRootID: instancesByReactRootID,
|
|
|
|
/**
|
|
* This is a hook provided to support rendering React components while
|
|
* ensuring that the apparent scroll position of its `container` does not
|
|
* change.
|
|
*
|
|
* @param {DOMElement} container The `container` being rendered into.
|
|
* @param {function} renderCallback This must be called once to do the render.
|
|
*/
|
|
scrollMonitor: function(container, renderCallback) {
|
|
renderCallback();
|
|
},
|
|
|
|
/**
|
|
* Take a component that's already mounted into the DOM and replace its props
|
|
* @param {ReactComponent} prevComponent component instance already in the DOM
|
|
* @param {ReactElement} nextElement component instance to render
|
|
* @param {DOMElement} container container to render into
|
|
* @param {?function} callback function triggered on completion
|
|
*/
|
|
_updateRootComponent: function(
|
|
prevComponent,
|
|
nextElement,
|
|
container,
|
|
callback) {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
ReactElementValidator.checkAndWarnForMutatedProps(nextElement);
|
|
}
|
|
|
|
ReactMount.scrollMonitor(container, function() {
|
|
ReactUpdateQueue.enqueueElementInternal(prevComponent, nextElement);
|
|
if (callback) {
|
|
ReactUpdateQueue.enqueueCallbackInternal(prevComponent, callback);
|
|
}
|
|
});
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
// Record the root element in case it later gets transplanted.
|
|
rootElementsByReactRootID[getReactRootID(container)] =
|
|
getReactRootElementInContainer(container);
|
|
}
|
|
|
|
return prevComponent;
|
|
},
|
|
|
|
/**
|
|
* Register a component into the instance map and starts scroll value
|
|
* monitoring
|
|
* @param {ReactComponent} nextComponent component instance to render
|
|
* @param {DOMElement} container container to render into
|
|
* @return {string} reactRoot ID prefix
|
|
*/
|
|
_registerComponent: function(nextComponent, container) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
container && (
|
|
(container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE)
|
|
),
|
|
'_registerComponent(...): Target container is not a DOM element.'
|
|
) : invariant(container && (
|
|
(container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE)
|
|
)));
|
|
|
|
ReactBrowserEventEmitter.ensureScrollValueMonitoring();
|
|
|
|
var reactRootID = ReactMount.registerContainer(container);
|
|
instancesByReactRootID[reactRootID] = nextComponent;
|
|
return reactRootID;
|
|
},
|
|
|
|
/**
|
|
* Render a new component into the DOM.
|
|
* @param {ReactElement} nextElement element to render
|
|
* @param {DOMElement} container container to render into
|
|
* @param {boolean} shouldReuseMarkup if we should skip the markup insertion
|
|
* @return {ReactComponent} nextComponent
|
|
*/
|
|
_renderNewRootComponent: function(
|
|
nextElement,
|
|
container,
|
|
shouldReuseMarkup
|
|
) {
|
|
// Various parts of our code (such as ReactCompositeComponent's
|
|
// _renderValidatedComponent) assume that calls to render aren't nested;
|
|
// verify that that's the case.
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
ReactCurrentOwner.current == null,
|
|
'_renderNewRootComponent(): Render methods should be a pure function ' +
|
|
'of props and state; triggering nested component updates from ' +
|
|
'render is not allowed. If necessary, trigger nested updates in ' +
|
|
'componentDidUpdate.'
|
|
) : null);
|
|
|
|
var componentInstance = instantiateReactComponent(nextElement, null);
|
|
var reactRootID = ReactMount._registerComponent(
|
|
componentInstance,
|
|
container
|
|
);
|
|
|
|
// The initial render is synchronous but any updates that happen during
|
|
// rendering, in componentWillMount or componentDidMount, will be batched
|
|
// according to the current batching strategy.
|
|
|
|
ReactUpdates.batchedUpdates(
|
|
batchedMountComponentIntoNode,
|
|
componentInstance,
|
|
reactRootID,
|
|
container,
|
|
shouldReuseMarkup
|
|
);
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
// Record the root element in case it later gets transplanted.
|
|
rootElementsByReactRootID[reactRootID] =
|
|
getReactRootElementInContainer(container);
|
|
}
|
|
|
|
return componentInstance;
|
|
},
|
|
|
|
/**
|
|
* Renders a React component into the DOM in the supplied `container`.
|
|
*
|
|
* If the React component was previously rendered into `container`, this will
|
|
* perform an update on it and only mutate the DOM as necessary to reflect the
|
|
* latest React component.
|
|
*
|
|
* @param {ReactElement} nextElement Component element to render.
|
|
* @param {DOMElement} container DOM element to render into.
|
|
* @param {?function} callback function triggered on completion
|
|
* @return {ReactComponent} Component instance rendered in `container`.
|
|
*/
|
|
render: function(nextElement, container, callback) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
ReactElement.isValidElement(nextElement),
|
|
'React.render(): Invalid component element.%s',
|
|
(
|
|
typeof nextElement === 'string' ?
|
|
' Instead of passing an element string, make sure to instantiate ' +
|
|
'it by passing it to React.createElement.' :
|
|
typeof nextElement === 'function' ?
|
|
' Instead of passing a component class, make sure to instantiate ' +
|
|
'it by passing it to React.createElement.' :
|
|
// Check if it quacks like an element
|
|
nextElement != null && nextElement.props !== undefined ?
|
|
' This may be caused by unintentionally loading two independent ' +
|
|
'copies of React.' :
|
|
''
|
|
)
|
|
) : invariant(ReactElement.isValidElement(nextElement)));
|
|
|
|
var prevComponent = instancesByReactRootID[getReactRootID(container)];
|
|
|
|
if (prevComponent) {
|
|
var prevElement = prevComponent._currentElement;
|
|
if (shouldUpdateReactComponent(prevElement, nextElement)) {
|
|
return ReactMount._updateRootComponent(
|
|
prevComponent,
|
|
nextElement,
|
|
container,
|
|
callback
|
|
).getPublicInstance();
|
|
} else {
|
|
ReactMount.unmountComponentAtNode(container);
|
|
}
|
|
}
|
|
|
|
var reactRootElement = getReactRootElementInContainer(container);
|
|
var containerHasReactMarkup =
|
|
reactRootElement && ReactMount.isRenderedByReact(reactRootElement);
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
if (!containerHasReactMarkup || reactRootElement.nextSibling) {
|
|
var rootElementSibling = reactRootElement;
|
|
while (rootElementSibling) {
|
|
if (ReactMount.isRenderedByReact(rootElementSibling)) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
false,
|
|
'render(): Target node has markup rendered by React, but there ' +
|
|
'are unrelated nodes as well. This is most commonly caused by ' +
|
|
'white-space inserted around server-rendered markup.'
|
|
) : null);
|
|
break;
|
|
}
|
|
|
|
rootElementSibling = rootElementSibling.nextSibling;
|
|
}
|
|
}
|
|
}
|
|
|
|
var shouldReuseMarkup = containerHasReactMarkup && !prevComponent;
|
|
|
|
var component = ReactMount._renderNewRootComponent(
|
|
nextElement,
|
|
container,
|
|
shouldReuseMarkup
|
|
).getPublicInstance();
|
|
if (callback) {
|
|
callback.call(component);
|
|
}
|
|
return component;
|
|
},
|
|
|
|
/**
|
|
* Constructs a component instance of `constructor` with `initialProps` and
|
|
* renders it into the supplied `container`.
|
|
*
|
|
* @param {function} constructor React component constructor.
|
|
* @param {?object} props Initial props of the component instance.
|
|
* @param {DOMElement} container DOM element to render into.
|
|
* @return {ReactComponent} Component instance rendered in `container`.
|
|
*/
|
|
constructAndRenderComponent: function(constructor, props, container) {
|
|
var element = ReactElement.createElement(constructor, props);
|
|
return ReactMount.render(element, container);
|
|
},
|
|
|
|
/**
|
|
* Constructs a component instance of `constructor` with `initialProps` and
|
|
* renders it into a container node identified by supplied `id`.
|
|
*
|
|
* @param {function} componentConstructor React component constructor
|
|
* @param {?object} props Initial props of the component instance.
|
|
* @param {string} id ID of the DOM element to render into.
|
|
* @return {ReactComponent} Component instance rendered in the container node.
|
|
*/
|
|
constructAndRenderComponentByID: function(constructor, props, id) {
|
|
var domNode = document.getElementById(id);
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
domNode,
|
|
'Tried to get element with id of "%s" but it is not present on the page.',
|
|
id
|
|
) : invariant(domNode));
|
|
return ReactMount.constructAndRenderComponent(constructor, props, domNode);
|
|
},
|
|
|
|
/**
|
|
* Registers a container node into which React components will be rendered.
|
|
* This also creates the "reactRoot" ID that will be assigned to the element
|
|
* rendered within.
|
|
*
|
|
* @param {DOMElement} container DOM element to register as a container.
|
|
* @return {string} The "reactRoot" ID of elements rendered within.
|
|
*/
|
|
registerContainer: function(container) {
|
|
var reactRootID = getReactRootID(container);
|
|
if (reactRootID) {
|
|
// If one exists, make sure it is a valid "reactRoot" ID.
|
|
reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(reactRootID);
|
|
}
|
|
if (!reactRootID) {
|
|
// No valid "reactRoot" ID found, create one.
|
|
reactRootID = ReactInstanceHandles.createReactRootID();
|
|
}
|
|
containersByReactRootID[reactRootID] = container;
|
|
return reactRootID;
|
|
},
|
|
|
|
/**
|
|
* Unmounts and destroys the React component rendered in the `container`.
|
|
*
|
|
* @param {DOMElement} container DOM element containing a React component.
|
|
* @return {boolean} True if a component was found in and unmounted from
|
|
* `container`
|
|
*/
|
|
unmountComponentAtNode: function(container) {
|
|
// Various parts of our code (such as ReactCompositeComponent's
|
|
// _renderValidatedComponent) assume that calls to render aren't nested;
|
|
// verify that that's the case. (Strictly speaking, unmounting won't cause a
|
|
// render but we still don't expect to be in a render call here.)
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
ReactCurrentOwner.current == null,
|
|
'unmountComponentAtNode(): Render methods should be a pure function of ' +
|
|
'props and state; triggering nested component updates from render is ' +
|
|
'not allowed. If necessary, trigger nested updates in ' +
|
|
'componentDidUpdate.'
|
|
) : null);
|
|
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
container && (
|
|
(container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE)
|
|
),
|
|
'unmountComponentAtNode(...): Target container is not a DOM element.'
|
|
) : invariant(container && (
|
|
(container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE)
|
|
)));
|
|
|
|
var reactRootID = getReactRootID(container);
|
|
var component = instancesByReactRootID[reactRootID];
|
|
if (!component) {
|
|
return false;
|
|
}
|
|
ReactMount.unmountComponentFromNode(component, container);
|
|
delete instancesByReactRootID[reactRootID];
|
|
delete containersByReactRootID[reactRootID];
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
delete rootElementsByReactRootID[reactRootID];
|
|
}
|
|
return true;
|
|
},
|
|
|
|
/**
|
|
* Unmounts a component and removes it from the DOM.
|
|
*
|
|
* @param {ReactComponent} instance React component instance.
|
|
* @param {DOMElement} container DOM element to unmount from.
|
|
* @final
|
|
* @internal
|
|
* @see {ReactMount.unmountComponentAtNode}
|
|
*/
|
|
unmountComponentFromNode: function(instance, container) {
|
|
ReactReconciler.unmountComponent(instance);
|
|
|
|
if (container.nodeType === DOC_NODE_TYPE) {
|
|
container = container.documentElement;
|
|
}
|
|
|
|
// http://jsperf.com/emptying-a-node
|
|
while (container.lastChild) {
|
|
container.removeChild(container.lastChild);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Finds the container DOM element that contains React component to which the
|
|
* supplied DOM `id` belongs.
|
|
*
|
|
* @param {string} id The ID of an element rendered by a React component.
|
|
* @return {?DOMElement} DOM element that contains the `id`.
|
|
*/
|
|
findReactContainerForID: function(id) {
|
|
var reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(id);
|
|
var container = containersByReactRootID[reactRootID];
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
var rootElement = rootElementsByReactRootID[reactRootID];
|
|
if (rootElement && rootElement.parentNode !== container) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
// Call internalGetID here because getID calls isValid which calls
|
|
// findReactContainerForID (this function).
|
|
internalGetID(rootElement) === reactRootID,
|
|
'ReactMount: Root element ID differed from reactRootID.'
|
|
) : invariant(// Call internalGetID here because getID calls isValid which calls
|
|
// findReactContainerForID (this function).
|
|
internalGetID(rootElement) === reactRootID));
|
|
|
|
var containerChild = container.firstChild;
|
|
if (containerChild &&
|
|
reactRootID === internalGetID(containerChild)) {
|
|
// If the container has a new child with the same ID as the old
|
|
// root element, then rootElementsByReactRootID[reactRootID] is
|
|
// just stale and needs to be updated. The case that deserves a
|
|
// warning is when the container is empty.
|
|
rootElementsByReactRootID[reactRootID] = containerChild;
|
|
} else {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
false,
|
|
'ReactMount: Root element has been removed from its original ' +
|
|
'container. New container:', rootElement.parentNode
|
|
) : null);
|
|
}
|
|
}
|
|
}
|
|
|
|
return container;
|
|
},
|
|
|
|
/**
|
|
* Finds an element rendered by React with the supplied ID.
|
|
*
|
|
* @param {string} id ID of a DOM node in the React component.
|
|
* @return {DOMElement} Root DOM node of the React component.
|
|
*/
|
|
findReactNodeByID: function(id) {
|
|
var reactRoot = ReactMount.findReactContainerForID(id);
|
|
return ReactMount.findComponentRoot(reactRoot, id);
|
|
},
|
|
|
|
/**
|
|
* True if the supplied `node` is rendered by React.
|
|
*
|
|
* @param {*} node DOM Element to check.
|
|
* @return {boolean} True if the DOM Element appears to be rendered by React.
|
|
* @internal
|
|
*/
|
|
isRenderedByReact: function(node) {
|
|
if (node.nodeType !== 1) {
|
|
// Not a DOMElement, therefore not a React component
|
|
return false;
|
|
}
|
|
var id = ReactMount.getID(node);
|
|
return id ? id.charAt(0) === SEPARATOR : false;
|
|
},
|
|
|
|
/**
|
|
* Traverses up the ancestors of the supplied node to find a node that is a
|
|
* DOM representation of a React component.
|
|
*
|
|
* @param {*} node
|
|
* @return {?DOMEventTarget}
|
|
* @internal
|
|
*/
|
|
getFirstReactDOM: function(node) {
|
|
var current = node;
|
|
while (current && current.parentNode !== current) {
|
|
if (ReactMount.isRenderedByReact(current)) {
|
|
return current;
|
|
}
|
|
current = current.parentNode;
|
|
}
|
|
return null;
|
|
},
|
|
|
|
/**
|
|
* Finds a node with the supplied `targetID` inside of the supplied
|
|
* `ancestorNode`. Exploits the ID naming scheme to perform the search
|
|
* quickly.
|
|
*
|
|
* @param {DOMEventTarget} ancestorNode Search from this root.
|
|
* @pararm {string} targetID ID of the DOM representation of the component.
|
|
* @return {DOMEventTarget} DOM node with the supplied `targetID`.
|
|
* @internal
|
|
*/
|
|
findComponentRoot: function(ancestorNode, targetID) {
|
|
var firstChildren = findComponentRootReusableArray;
|
|
var childIndex = 0;
|
|
|
|
var deepestAncestor = findDeepestCachedAncestor(targetID) || ancestorNode;
|
|
|
|
firstChildren[0] = deepestAncestor.firstChild;
|
|
firstChildren.length = 1;
|
|
|
|
while (childIndex < firstChildren.length) {
|
|
var child = firstChildren[childIndex++];
|
|
var targetChild;
|
|
|
|
while (child) {
|
|
var childID = ReactMount.getID(child);
|
|
if (childID) {
|
|
// Even if we find the node we're looking for, we finish looping
|
|
// through its siblings to ensure they're cached so that we don't have
|
|
// to revisit this node again. Otherwise, we make n^2 calls to getID
|
|
// when visiting the many children of a single node in order.
|
|
|
|
if (targetID === childID) {
|
|
targetChild = child;
|
|
} else if (ReactInstanceHandles.isAncestorIDOf(childID, targetID)) {
|
|
// If we find a child whose ID is an ancestor of the given ID,
|
|
// then we can be sure that we only want to search the subtree
|
|
// rooted at this child, so we can throw out the rest of the
|
|
// search state.
|
|
firstChildren.length = childIndex = 0;
|
|
firstChildren.push(child.firstChild);
|
|
}
|
|
|
|
} else {
|
|
// If this child had no ID, then there's a chance that it was
|
|
// injected automatically by the browser, as when a `<table>`
|
|
// element sprouts an extra `<tbody>` child as a side effect of
|
|
// `.innerHTML` parsing. Optimistically continue down this
|
|
// branch, but not before examining the other siblings.
|
|
firstChildren.push(child.firstChild);
|
|
}
|
|
|
|
child = child.nextSibling;
|
|
}
|
|
|
|
if (targetChild) {
|
|
// Emptying firstChildren/findComponentRootReusableArray is
|
|
// not necessary for correctness, but it helps the GC reclaim
|
|
// any nodes that were left at the end of the search.
|
|
firstChildren.length = 0;
|
|
|
|
return targetChild;
|
|
}
|
|
}
|
|
|
|
firstChildren.length = 0;
|
|
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
false,
|
|
'findComponentRoot(..., %s): Unable to find element. This probably ' +
|
|
'means the DOM was unexpectedly mutated (e.g., by the browser), ' +
|
|
'usually due to forgetting a <tbody> when using tables, nesting tags ' +
|
|
'like <form>, <p>, or <a>, or using non-SVG elements in an <svg> ' +
|
|
'parent. ' +
|
|
'Try inspecting the child nodes of the element with React ID `%s`.',
|
|
targetID,
|
|
ReactMount.getID(ancestorNode)
|
|
) : invariant(false));
|
|
},
|
|
|
|
_mountImageIntoNode: function(markup, container, shouldReuseMarkup) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
container && (
|
|
(container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE)
|
|
),
|
|
'mountComponentIntoNode(...): Target container is not valid.'
|
|
) : invariant(container && (
|
|
(container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE)
|
|
)));
|
|
|
|
if (shouldReuseMarkup) {
|
|
var rootElement = getReactRootElementInContainer(container);
|
|
if (ReactMarkupChecksum.canReuseMarkup(markup, rootElement)) {
|
|
return;
|
|
} else {
|
|
var checksum = rootElement.getAttribute(
|
|
ReactMarkupChecksum.CHECKSUM_ATTR_NAME
|
|
);
|
|
rootElement.removeAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME);
|
|
|
|
var rootMarkup = rootElement.outerHTML;
|
|
rootElement.setAttribute(
|
|
ReactMarkupChecksum.CHECKSUM_ATTR_NAME,
|
|
checksum
|
|
);
|
|
|
|
var diffIndex = firstDifferenceIndex(markup, rootMarkup);
|
|
var difference = ' (client) ' +
|
|
markup.substring(diffIndex - 20, diffIndex + 20) +
|
|
'\n (server) ' + rootMarkup.substring(diffIndex - 20, diffIndex + 20);
|
|
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
container.nodeType !== DOC_NODE_TYPE,
|
|
'You\'re trying to render a component to the document using ' +
|
|
'server rendering but the checksum was invalid. This usually ' +
|
|
'means you rendered a different component type or props on ' +
|
|
'the client from the one on the server, or your render() ' +
|
|
'methods are impure. React cannot handle this case due to ' +
|
|
'cross-browser quirks by rendering at the document root. You ' +
|
|
'should look for environment dependent code in your components ' +
|
|
'and ensure the props are the same client and server side:\n%s',
|
|
difference
|
|
) : invariant(container.nodeType !== DOC_NODE_TYPE));
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
false,
|
|
'React attempted to reuse markup in a container but the ' +
|
|
'checksum was invalid. This generally means that you are ' +
|
|
'using server rendering and the markup generated on the ' +
|
|
'server was not what the client was expecting. React injected ' +
|
|
'new markup to compensate which works but you have lost many ' +
|
|
'of the benefits of server rendering. Instead, figure out ' +
|
|
'why the markup being generated is different on the client ' +
|
|
'or server:\n%s',
|
|
difference
|
|
) : null);
|
|
}
|
|
}
|
|
}
|
|
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
container.nodeType !== DOC_NODE_TYPE,
|
|
'You\'re trying to render a component to the document but ' +
|
|
'you didn\'t use server rendering. We can\'t do this ' +
|
|
'without using server rendering due to cross-browser quirks. ' +
|
|
'See React.renderToString() for server rendering.'
|
|
) : invariant(container.nodeType !== DOC_NODE_TYPE));
|
|
|
|
setInnerHTML(container, markup);
|
|
},
|
|
|
|
/**
|
|
* React ID utilities.
|
|
*/
|
|
|
|
getReactRootID: getReactRootID,
|
|
|
|
getID: getID,
|
|
|
|
setID: setID,
|
|
|
|
getNode: getNode,
|
|
|
|
getNodeFromInstance: getNodeFromInstance,
|
|
|
|
purgeID: purgeID
|
|
};
|
|
|
|
ReactPerf.measureMethods(ReactMount, 'ReactMount', {
|
|
_renderNewRootComponent: '_renderNewRootComponent',
|
|
_mountImageIntoNode: '_mountImageIntoNode'
|
|
});
|
|
|
|
module.exports = ReactMount;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./DOMProperty":59,"./ReactBrowserEventEmitter":80,"./ReactCurrentOwner":89,"./ReactElement":107,"./ReactElementValidator":108,"./ReactEmptyComponent":109,"./ReactInstanceHandles":116,"./ReactInstanceMap":117,"./ReactMarkupChecksum":119,"./ReactPerf":125,"./ReactReconciler":131,"./ReactUpdateQueue":136,"./ReactUpdates":137,"./containsNode":159,"./emptyObject":165,"./getReactRootElementInContainer":179,"./instantiateReactComponent":184,"./invariant":185,"./setInnerHTML":198,"./shouldUpdateReactComponent":201,"./warning":204,"_process":1}],121:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactMultiChild
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactComponentEnvironment = require("./ReactComponentEnvironment");
|
|
var ReactMultiChildUpdateTypes = require("./ReactMultiChildUpdateTypes");
|
|
|
|
var ReactReconciler = require("./ReactReconciler");
|
|
var ReactChildReconciler = require("./ReactChildReconciler");
|
|
|
|
/**
|
|
* Updating children of a component may trigger recursive updates. The depth is
|
|
* used to batch recursive updates to render markup more efficiently.
|
|
*
|
|
* @type {number}
|
|
* @private
|
|
*/
|
|
var updateDepth = 0;
|
|
|
|
/**
|
|
* Queue of update configuration objects.
|
|
*
|
|
* Each object has a `type` property that is in `ReactMultiChildUpdateTypes`.
|
|
*
|
|
* @type {array<object>}
|
|
* @private
|
|
*/
|
|
var updateQueue = [];
|
|
|
|
/**
|
|
* Queue of markup to be rendered.
|
|
*
|
|
* @type {array<string>}
|
|
* @private
|
|
*/
|
|
var markupQueue = [];
|
|
|
|
/**
|
|
* Enqueues markup to be rendered and inserted at a supplied index.
|
|
*
|
|
* @param {string} parentID ID of the parent component.
|
|
* @param {string} markup Markup that renders into an element.
|
|
* @param {number} toIndex Destination index.
|
|
* @private
|
|
*/
|
|
function enqueueMarkup(parentID, markup, toIndex) {
|
|
// NOTE: Null values reduce hidden classes.
|
|
updateQueue.push({
|
|
parentID: parentID,
|
|
parentNode: null,
|
|
type: ReactMultiChildUpdateTypes.INSERT_MARKUP,
|
|
markupIndex: markupQueue.push(markup) - 1,
|
|
textContent: null,
|
|
fromIndex: null,
|
|
toIndex: toIndex
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Enqueues moving an existing element to another index.
|
|
*
|
|
* @param {string} parentID ID of the parent component.
|
|
* @param {number} fromIndex Source index of the existing element.
|
|
* @param {number} toIndex Destination index of the element.
|
|
* @private
|
|
*/
|
|
function enqueueMove(parentID, fromIndex, toIndex) {
|
|
// NOTE: Null values reduce hidden classes.
|
|
updateQueue.push({
|
|
parentID: parentID,
|
|
parentNode: null,
|
|
type: ReactMultiChildUpdateTypes.MOVE_EXISTING,
|
|
markupIndex: null,
|
|
textContent: null,
|
|
fromIndex: fromIndex,
|
|
toIndex: toIndex
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Enqueues removing an element at an index.
|
|
*
|
|
* @param {string} parentID ID of the parent component.
|
|
* @param {number} fromIndex Index of the element to remove.
|
|
* @private
|
|
*/
|
|
function enqueueRemove(parentID, fromIndex) {
|
|
// NOTE: Null values reduce hidden classes.
|
|
updateQueue.push({
|
|
parentID: parentID,
|
|
parentNode: null,
|
|
type: ReactMultiChildUpdateTypes.REMOVE_NODE,
|
|
markupIndex: null,
|
|
textContent: null,
|
|
fromIndex: fromIndex,
|
|
toIndex: null
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Enqueues setting the text content.
|
|
*
|
|
* @param {string} parentID ID of the parent component.
|
|
* @param {string} textContent Text content to set.
|
|
* @private
|
|
*/
|
|
function enqueueTextContent(parentID, textContent) {
|
|
// NOTE: Null values reduce hidden classes.
|
|
updateQueue.push({
|
|
parentID: parentID,
|
|
parentNode: null,
|
|
type: ReactMultiChildUpdateTypes.TEXT_CONTENT,
|
|
markupIndex: null,
|
|
textContent: textContent,
|
|
fromIndex: null,
|
|
toIndex: null
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Processes any enqueued updates.
|
|
*
|
|
* @private
|
|
*/
|
|
function processQueue() {
|
|
if (updateQueue.length) {
|
|
ReactComponentEnvironment.processChildrenUpdates(
|
|
updateQueue,
|
|
markupQueue
|
|
);
|
|
clearQueue();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clears any enqueued updates.
|
|
*
|
|
* @private
|
|
*/
|
|
function clearQueue() {
|
|
updateQueue.length = 0;
|
|
markupQueue.length = 0;
|
|
}
|
|
|
|
/**
|
|
* ReactMultiChild are capable of reconciling multiple children.
|
|
*
|
|
* @class ReactMultiChild
|
|
* @internal
|
|
*/
|
|
var ReactMultiChild = {
|
|
|
|
/**
|
|
* Provides common functionality for components that must reconcile multiple
|
|
* children. This is used by `ReactDOMComponent` to mount, update, and
|
|
* unmount child components.
|
|
*
|
|
* @lends {ReactMultiChild.prototype}
|
|
*/
|
|
Mixin: {
|
|
|
|
/**
|
|
* Generates a "mount image" for each of the supplied children. In the case
|
|
* of `ReactDOMComponent`, a mount image is a string of markup.
|
|
*
|
|
* @param {?object} nestedChildren Nested child maps.
|
|
* @return {array} An array of mounted representations.
|
|
* @internal
|
|
*/
|
|
mountChildren: function(nestedChildren, transaction, context) {
|
|
var children = ReactChildReconciler.instantiateChildren(
|
|
nestedChildren, transaction, context
|
|
);
|
|
this._renderedChildren = children;
|
|
var mountImages = [];
|
|
var index = 0;
|
|
for (var name in children) {
|
|
if (children.hasOwnProperty(name)) {
|
|
var child = children[name];
|
|
// Inlined for performance, see `ReactInstanceHandles.createReactID`.
|
|
var rootID = this._rootNodeID + name;
|
|
var mountImage = ReactReconciler.mountComponent(
|
|
child,
|
|
rootID,
|
|
transaction,
|
|
context
|
|
);
|
|
child._mountIndex = index;
|
|
mountImages.push(mountImage);
|
|
index++;
|
|
}
|
|
}
|
|
return mountImages;
|
|
},
|
|
|
|
/**
|
|
* Replaces any rendered children with a text content string.
|
|
*
|
|
* @param {string} nextContent String of content.
|
|
* @internal
|
|
*/
|
|
updateTextContent: function(nextContent) {
|
|
updateDepth++;
|
|
var errorThrown = true;
|
|
try {
|
|
var prevChildren = this._renderedChildren;
|
|
// Remove any rendered children.
|
|
ReactChildReconciler.unmountChildren(prevChildren);
|
|
// TODO: The setTextContent operation should be enough
|
|
for (var name in prevChildren) {
|
|
if (prevChildren.hasOwnProperty(name)) {
|
|
this._unmountChildByName(prevChildren[name], name);
|
|
}
|
|
}
|
|
// Set new text content.
|
|
this.setTextContent(nextContent);
|
|
errorThrown = false;
|
|
} finally {
|
|
updateDepth--;
|
|
if (!updateDepth) {
|
|
if (errorThrown) {
|
|
clearQueue();
|
|
} else {
|
|
processQueue();
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Updates the rendered children with new children.
|
|
*
|
|
* @param {?object} nextNestedChildren Nested child maps.
|
|
* @param {ReactReconcileTransaction} transaction
|
|
* @internal
|
|
*/
|
|
updateChildren: function(nextNestedChildren, transaction, context) {
|
|
updateDepth++;
|
|
var errorThrown = true;
|
|
try {
|
|
this._updateChildren(nextNestedChildren, transaction, context);
|
|
errorThrown = false;
|
|
} finally {
|
|
updateDepth--;
|
|
if (!updateDepth) {
|
|
if (errorThrown) {
|
|
clearQueue();
|
|
} else {
|
|
processQueue();
|
|
}
|
|
}
|
|
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Improve performance by isolating this hot code path from the try/catch
|
|
* block in `updateChildren`.
|
|
*
|
|
* @param {?object} nextNestedChildren Nested child maps.
|
|
* @param {ReactReconcileTransaction} transaction
|
|
* @final
|
|
* @protected
|
|
*/
|
|
_updateChildren: function(nextNestedChildren, transaction, context) {
|
|
var prevChildren = this._renderedChildren;
|
|
var nextChildren = ReactChildReconciler.updateChildren(
|
|
prevChildren, nextNestedChildren, transaction, context
|
|
);
|
|
this._renderedChildren = nextChildren;
|
|
if (!nextChildren && !prevChildren) {
|
|
return;
|
|
}
|
|
var name;
|
|
// `nextIndex` will increment for each child in `nextChildren`, but
|
|
// `lastIndex` will be the last index visited in `prevChildren`.
|
|
var lastIndex = 0;
|
|
var nextIndex = 0;
|
|
for (name in nextChildren) {
|
|
if (!nextChildren.hasOwnProperty(name)) {
|
|
continue;
|
|
}
|
|
var prevChild = prevChildren && prevChildren[name];
|
|
var nextChild = nextChildren[name];
|
|
if (prevChild === nextChild) {
|
|
this.moveChild(prevChild, nextIndex, lastIndex);
|
|
lastIndex = Math.max(prevChild._mountIndex, lastIndex);
|
|
prevChild._mountIndex = nextIndex;
|
|
} else {
|
|
if (prevChild) {
|
|
// Update `lastIndex` before `_mountIndex` gets unset by unmounting.
|
|
lastIndex = Math.max(prevChild._mountIndex, lastIndex);
|
|
this._unmountChildByName(prevChild, name);
|
|
}
|
|
// The child must be instantiated before it's mounted.
|
|
this._mountChildByNameAtIndex(
|
|
nextChild, name, nextIndex, transaction, context
|
|
);
|
|
}
|
|
nextIndex++;
|
|
}
|
|
// Remove children that are no longer present.
|
|
for (name in prevChildren) {
|
|
if (prevChildren.hasOwnProperty(name) &&
|
|
!(nextChildren && nextChildren.hasOwnProperty(name))) {
|
|
this._unmountChildByName(prevChildren[name], name);
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Unmounts all rendered children. This should be used to clean up children
|
|
* when this component is unmounted.
|
|
*
|
|
* @internal
|
|
*/
|
|
unmountChildren: function() {
|
|
var renderedChildren = this._renderedChildren;
|
|
ReactChildReconciler.unmountChildren(renderedChildren);
|
|
this._renderedChildren = null;
|
|
},
|
|
|
|
/**
|
|
* Moves a child component to the supplied index.
|
|
*
|
|
* @param {ReactComponent} child Component to move.
|
|
* @param {number} toIndex Destination index of the element.
|
|
* @param {number} lastIndex Last index visited of the siblings of `child`.
|
|
* @protected
|
|
*/
|
|
moveChild: function(child, toIndex, lastIndex) {
|
|
// If the index of `child` is less than `lastIndex`, then it needs to
|
|
// be moved. Otherwise, we do not need to move it because a child will be
|
|
// inserted or moved before `child`.
|
|
if (child._mountIndex < lastIndex) {
|
|
enqueueMove(this._rootNodeID, child._mountIndex, toIndex);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Creates a child component.
|
|
*
|
|
* @param {ReactComponent} child Component to create.
|
|
* @param {string} mountImage Markup to insert.
|
|
* @protected
|
|
*/
|
|
createChild: function(child, mountImage) {
|
|
enqueueMarkup(this._rootNodeID, mountImage, child._mountIndex);
|
|
},
|
|
|
|
/**
|
|
* Removes a child component.
|
|
*
|
|
* @param {ReactComponent} child Child to remove.
|
|
* @protected
|
|
*/
|
|
removeChild: function(child) {
|
|
enqueueRemove(this._rootNodeID, child._mountIndex);
|
|
},
|
|
|
|
/**
|
|
* Sets this text content string.
|
|
*
|
|
* @param {string} textContent Text content to set.
|
|
* @protected
|
|
*/
|
|
setTextContent: function(textContent) {
|
|
enqueueTextContent(this._rootNodeID, textContent);
|
|
},
|
|
|
|
/**
|
|
* Mounts a child with the supplied name.
|
|
*
|
|
* NOTE: This is part of `updateChildren` and is here for readability.
|
|
*
|
|
* @param {ReactComponent} child Component to mount.
|
|
* @param {string} name Name of the child.
|
|
* @param {number} index Index at which to insert the child.
|
|
* @param {ReactReconcileTransaction} transaction
|
|
* @private
|
|
*/
|
|
_mountChildByNameAtIndex: function(
|
|
child,
|
|
name,
|
|
index,
|
|
transaction,
|
|
context) {
|
|
// Inlined for performance, see `ReactInstanceHandles.createReactID`.
|
|
var rootID = this._rootNodeID + name;
|
|
var mountImage = ReactReconciler.mountComponent(
|
|
child,
|
|
rootID,
|
|
transaction,
|
|
context
|
|
);
|
|
child._mountIndex = index;
|
|
this.createChild(child, mountImage);
|
|
},
|
|
|
|
/**
|
|
* Unmounts a rendered child by name.
|
|
*
|
|
* NOTE: This is part of `updateChildren` and is here for readability.
|
|
*
|
|
* @param {ReactComponent} child Component to unmount.
|
|
* @param {string} name Name of the child in `this._renderedChildren`.
|
|
* @private
|
|
*/
|
|
_unmountChildByName: function(child, name) {
|
|
this.removeChild(child);
|
|
child._mountIndex = null;
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = ReactMultiChild;
|
|
|
|
},{"./ReactChildReconciler":81,"./ReactComponentEnvironment":86,"./ReactMultiChildUpdateTypes":122,"./ReactReconciler":131}],122:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactMultiChildUpdateTypes
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var keyMirror = require("./keyMirror");
|
|
|
|
/**
|
|
* When a component's children are updated, a series of update configuration
|
|
* objects are created in order to batch and serialize the required changes.
|
|
*
|
|
* Enumerates all the possible types of update configurations.
|
|
*
|
|
* @internal
|
|
*/
|
|
var ReactMultiChildUpdateTypes = keyMirror({
|
|
INSERT_MARKUP: null,
|
|
MOVE_EXISTING: null,
|
|
REMOVE_NODE: null,
|
|
TEXT_CONTENT: null
|
|
});
|
|
|
|
module.exports = ReactMultiChildUpdateTypes;
|
|
|
|
},{"./keyMirror":190}],123:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2014-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactNativeComponent
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var assign = require("./Object.assign");
|
|
var invariant = require("./invariant");
|
|
|
|
var autoGenerateWrapperClass = null;
|
|
var genericComponentClass = null;
|
|
// This registry keeps track of wrapper classes around native tags
|
|
var tagToComponentClass = {};
|
|
var textComponentClass = null;
|
|
|
|
var ReactNativeComponentInjection = {
|
|
// This accepts a class that receives the tag string. This is a catch all
|
|
// that can render any kind of tag.
|
|
injectGenericComponentClass: function(componentClass) {
|
|
genericComponentClass = componentClass;
|
|
},
|
|
// This accepts a text component class that takes the text string to be
|
|
// rendered as props.
|
|
injectTextComponentClass: function(componentClass) {
|
|
textComponentClass = componentClass;
|
|
},
|
|
// This accepts a keyed object with classes as values. Each key represents a
|
|
// tag. That particular tag will use this class instead of the generic one.
|
|
injectComponentClasses: function(componentClasses) {
|
|
assign(tagToComponentClass, componentClasses);
|
|
},
|
|
// Temporary hack since we expect DOM refs to behave like composites,
|
|
// for this release.
|
|
injectAutoWrapper: function(wrapperFactory) {
|
|
autoGenerateWrapperClass = wrapperFactory;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Get a composite component wrapper class for a specific tag.
|
|
*
|
|
* @param {ReactElement} element The tag for which to get the class.
|
|
* @return {function} The React class constructor function.
|
|
*/
|
|
function getComponentClassForElement(element) {
|
|
if (typeof element.type === 'function') {
|
|
return element.type;
|
|
}
|
|
var tag = element.type;
|
|
var componentClass = tagToComponentClass[tag];
|
|
if (componentClass == null) {
|
|
tagToComponentClass[tag] = componentClass = autoGenerateWrapperClass(tag);
|
|
}
|
|
return componentClass;
|
|
}
|
|
|
|
/**
|
|
* Get a native internal component class for a specific tag.
|
|
*
|
|
* @param {ReactElement} element The element to create.
|
|
* @return {function} The internal class constructor function.
|
|
*/
|
|
function createInternalComponent(element) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
genericComponentClass,
|
|
'There is no registered component for the tag %s',
|
|
element.type
|
|
) : invariant(genericComponentClass));
|
|
return new genericComponentClass(element.type, element.props);
|
|
}
|
|
|
|
/**
|
|
* @param {ReactText} text
|
|
* @return {ReactComponent}
|
|
*/
|
|
function createInstanceForText(text) {
|
|
return new textComponentClass(text);
|
|
}
|
|
|
|
/**
|
|
* @param {ReactComponent} component
|
|
* @return {boolean}
|
|
*/
|
|
function isTextComponent(component) {
|
|
return component instanceof textComponentClass;
|
|
}
|
|
|
|
var ReactNativeComponent = {
|
|
getComponentClassForElement: getComponentClassForElement,
|
|
createInternalComponent: createInternalComponent,
|
|
createInstanceForText: createInstanceForText,
|
|
isTextComponent: isTextComponent,
|
|
injection: ReactNativeComponentInjection
|
|
};
|
|
|
|
module.exports = ReactNativeComponent;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./Object.assign":76,"./invariant":185,"_process":1}],124:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactOwner
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var invariant = require("./invariant");
|
|
|
|
/**
|
|
* ReactOwners are capable of storing references to owned components.
|
|
*
|
|
* All components are capable of //being// referenced by owner components, but
|
|
* only ReactOwner components are capable of //referencing// owned components.
|
|
* The named reference is known as a "ref".
|
|
*
|
|
* Refs are available when mounted and updated during reconciliation.
|
|
*
|
|
* var MyComponent = React.createClass({
|
|
* render: function() {
|
|
* return (
|
|
* <div onClick={this.handleClick}>
|
|
* <CustomComponent ref="custom" />
|
|
* </div>
|
|
* );
|
|
* },
|
|
* handleClick: function() {
|
|
* this.refs.custom.handleClick();
|
|
* },
|
|
* componentDidMount: function() {
|
|
* this.refs.custom.initialize();
|
|
* }
|
|
* });
|
|
*
|
|
* Refs should rarely be used. When refs are used, they should only be done to
|
|
* control data that is not handled by React's data flow.
|
|
*
|
|
* @class ReactOwner
|
|
*/
|
|
var ReactOwner = {
|
|
|
|
/**
|
|
* @param {?object} object
|
|
* @return {boolean} True if `object` is a valid owner.
|
|
* @final
|
|
*/
|
|
isValidOwner: function(object) {
|
|
return !!(
|
|
(object &&
|
|
typeof object.attachRef === 'function' && typeof object.detachRef === 'function')
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Adds a component by ref to an owner component.
|
|
*
|
|
* @param {ReactComponent} component Component to reference.
|
|
* @param {string} ref Name by which to refer to the component.
|
|
* @param {ReactOwner} owner Component on which to record the ref.
|
|
* @final
|
|
* @internal
|
|
*/
|
|
addComponentAsRefTo: function(component, ref, owner) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
ReactOwner.isValidOwner(owner),
|
|
'addComponentAsRefTo(...): Only a ReactOwner can have refs. This ' +
|
|
'usually means that you\'re trying to add a ref to a component that ' +
|
|
'doesn\'t have an owner (that is, was not created inside of another ' +
|
|
'component\'s `render` method). Try rendering this component inside of ' +
|
|
'a new top-level component which will hold the ref.'
|
|
) : invariant(ReactOwner.isValidOwner(owner)));
|
|
owner.attachRef(ref, component);
|
|
},
|
|
|
|
/**
|
|
* Removes a component by ref from an owner component.
|
|
*
|
|
* @param {ReactComponent} component Component to dereference.
|
|
* @param {string} ref Name of the ref to remove.
|
|
* @param {ReactOwner} owner Component on which the ref is recorded.
|
|
* @final
|
|
* @internal
|
|
*/
|
|
removeComponentAsRefFrom: function(component, ref, owner) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
ReactOwner.isValidOwner(owner),
|
|
'removeComponentAsRefFrom(...): Only a ReactOwner can have refs. This ' +
|
|
'usually means that you\'re trying to remove a ref to a component that ' +
|
|
'doesn\'t have an owner (that is, was not created inside of another ' +
|
|
'component\'s `render` method). Try rendering this component inside of ' +
|
|
'a new top-level component which will hold the ref.'
|
|
) : invariant(ReactOwner.isValidOwner(owner)));
|
|
// Check that `component` is still the current ref because we do not want to
|
|
// detach the ref if another component stole it.
|
|
if (owner.getPublicInstance().refs[ref] === component.getPublicInstance()) {
|
|
owner.detachRef(ref);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = ReactOwner;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./invariant":185,"_process":1}],125:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactPerf
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* ReactPerf is a general AOP system designed to measure performance. This
|
|
* module only has the hooks: see ReactDefaultPerf for the analysis tool.
|
|
*/
|
|
var ReactPerf = {
|
|
/**
|
|
* Boolean to enable/disable measurement. Set to false by default to prevent
|
|
* accidental logging and perf loss.
|
|
*/
|
|
enableMeasure: false,
|
|
|
|
/**
|
|
* Holds onto the measure function in use. By default, don't measure
|
|
* anything, but we'll override this if we inject a measure function.
|
|
*/
|
|
storedMeasure: _noMeasure,
|
|
|
|
/**
|
|
* @param {object} object
|
|
* @param {string} objectName
|
|
* @param {object<string>} methodNames
|
|
*/
|
|
measureMethods: function(object, objectName, methodNames) {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
for (var key in methodNames) {
|
|
if (!methodNames.hasOwnProperty(key)) {
|
|
continue;
|
|
}
|
|
object[key] = ReactPerf.measure(
|
|
objectName,
|
|
methodNames[key],
|
|
object[key]
|
|
);
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Use this to wrap methods you want to measure. Zero overhead in production.
|
|
*
|
|
* @param {string} objName
|
|
* @param {string} fnName
|
|
* @param {function} func
|
|
* @return {function}
|
|
*/
|
|
measure: function(objName, fnName, func) {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
var measuredFunc = null;
|
|
var wrapper = function() {
|
|
if (ReactPerf.enableMeasure) {
|
|
if (!measuredFunc) {
|
|
measuredFunc = ReactPerf.storedMeasure(objName, fnName, func);
|
|
}
|
|
return measuredFunc.apply(this, arguments);
|
|
}
|
|
return func.apply(this, arguments);
|
|
};
|
|
wrapper.displayName = objName + '_' + fnName;
|
|
return wrapper;
|
|
}
|
|
return func;
|
|
},
|
|
|
|
injection: {
|
|
/**
|
|
* @param {function} measure
|
|
*/
|
|
injectMeasure: function(measure) {
|
|
ReactPerf.storedMeasure = measure;
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Simply passes through the measured function, without measuring it.
|
|
*
|
|
* @param {string} objName
|
|
* @param {string} fnName
|
|
* @param {function} func
|
|
* @return {function}
|
|
*/
|
|
function _noMeasure(objName, fnName, func) {
|
|
return func;
|
|
}
|
|
|
|
module.exports = ReactPerf;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"_process":1}],126:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactPropTypeLocationNames
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactPropTypeLocationNames = {};
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
ReactPropTypeLocationNames = {
|
|
prop: 'prop',
|
|
context: 'context',
|
|
childContext: 'child context'
|
|
};
|
|
}
|
|
|
|
module.exports = ReactPropTypeLocationNames;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"_process":1}],127:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactPropTypeLocations
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var keyMirror = require("./keyMirror");
|
|
|
|
var ReactPropTypeLocations = keyMirror({
|
|
prop: null,
|
|
context: null,
|
|
childContext: null
|
|
});
|
|
|
|
module.exports = ReactPropTypeLocations;
|
|
|
|
},{"./keyMirror":190}],128:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactPropTypes
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactElement = require("./ReactElement");
|
|
var ReactFragment = require("./ReactFragment");
|
|
var ReactPropTypeLocationNames = require("./ReactPropTypeLocationNames");
|
|
|
|
var emptyFunction = require("./emptyFunction");
|
|
|
|
/**
|
|
* Collection of methods that allow declaration and validation of props that are
|
|
* supplied to React components. Example usage:
|
|
*
|
|
* var Props = require('ReactPropTypes');
|
|
* var MyArticle = React.createClass({
|
|
* propTypes: {
|
|
* // An optional string prop named "description".
|
|
* description: Props.string,
|
|
*
|
|
* // A required enum prop named "category".
|
|
* category: Props.oneOf(['News','Photos']).isRequired,
|
|
*
|
|
* // A prop named "dialog" that requires an instance of Dialog.
|
|
* dialog: Props.instanceOf(Dialog).isRequired
|
|
* },
|
|
* render: function() { ... }
|
|
* });
|
|
*
|
|
* A more formal specification of how these methods are used:
|
|
*
|
|
* type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...)
|
|
* decl := ReactPropTypes.{type}(.isRequired)?
|
|
*
|
|
* Each and every declaration produces a function with the same signature. This
|
|
* allows the creation of custom validation functions. For example:
|
|
*
|
|
* var MyLink = React.createClass({
|
|
* propTypes: {
|
|
* // An optional string or URI prop named "href".
|
|
* href: function(props, propName, componentName) {
|
|
* var propValue = props[propName];
|
|
* if (propValue != null && typeof propValue !== 'string' &&
|
|
* !(propValue instanceof URI)) {
|
|
* return new Error(
|
|
* 'Expected a string or an URI for ' + propName + ' in ' +
|
|
* componentName
|
|
* );
|
|
* }
|
|
* }
|
|
* },
|
|
* render: function() {...}
|
|
* });
|
|
*
|
|
* @internal
|
|
*/
|
|
|
|
var ANONYMOUS = '<<anonymous>>';
|
|
|
|
var elementTypeChecker = createElementTypeChecker();
|
|
var nodeTypeChecker = createNodeChecker();
|
|
|
|
var ReactPropTypes = {
|
|
array: createPrimitiveTypeChecker('array'),
|
|
bool: createPrimitiveTypeChecker('boolean'),
|
|
func: createPrimitiveTypeChecker('function'),
|
|
number: createPrimitiveTypeChecker('number'),
|
|
object: createPrimitiveTypeChecker('object'),
|
|
string: createPrimitiveTypeChecker('string'),
|
|
|
|
any: createAnyTypeChecker(),
|
|
arrayOf: createArrayOfTypeChecker,
|
|
element: elementTypeChecker,
|
|
instanceOf: createInstanceTypeChecker,
|
|
node: nodeTypeChecker,
|
|
objectOf: createObjectOfTypeChecker,
|
|
oneOf: createEnumTypeChecker,
|
|
oneOfType: createUnionTypeChecker,
|
|
shape: createShapeTypeChecker
|
|
};
|
|
|
|
function createChainableTypeChecker(validate) {
|
|
function checkType(isRequired, props, propName, componentName, location) {
|
|
componentName = componentName || ANONYMOUS;
|
|
if (props[propName] == null) {
|
|
var locationName = ReactPropTypeLocationNames[location];
|
|
if (isRequired) {
|
|
return new Error(
|
|
("Required " + locationName + " `" + propName + "` was not specified in ") +
|
|
("`" + componentName + "`.")
|
|
);
|
|
}
|
|
return null;
|
|
} else {
|
|
return validate(props, propName, componentName, location);
|
|
}
|
|
}
|
|
|
|
var chainedCheckType = checkType.bind(null, false);
|
|
chainedCheckType.isRequired = checkType.bind(null, true);
|
|
|
|
return chainedCheckType;
|
|
}
|
|
|
|
function createPrimitiveTypeChecker(expectedType) {
|
|
function validate(props, propName, componentName, location) {
|
|
var propValue = props[propName];
|
|
var propType = getPropType(propValue);
|
|
if (propType !== expectedType) {
|
|
var locationName = ReactPropTypeLocationNames[location];
|
|
// `propValue` being instance of, say, date/regexp, pass the 'object'
|
|
// check, but we can offer a more precise error message here rather than
|
|
// 'of type `object`'.
|
|
var preciseType = getPreciseType(propValue);
|
|
|
|
return new Error(
|
|
("Invalid " + locationName + " `" + propName + "` of type `" + preciseType + "` ") +
|
|
("supplied to `" + componentName + "`, expected `" + expectedType + "`.")
|
|
);
|
|
}
|
|
return null;
|
|
}
|
|
return createChainableTypeChecker(validate);
|
|
}
|
|
|
|
function createAnyTypeChecker() {
|
|
return createChainableTypeChecker(emptyFunction.thatReturns(null));
|
|
}
|
|
|
|
function createArrayOfTypeChecker(typeChecker) {
|
|
function validate(props, propName, componentName, location) {
|
|
var propValue = props[propName];
|
|
if (!Array.isArray(propValue)) {
|
|
var locationName = ReactPropTypeLocationNames[location];
|
|
var propType = getPropType(propValue);
|
|
return new Error(
|
|
("Invalid " + locationName + " `" + propName + "` of type ") +
|
|
("`" + propType + "` supplied to `" + componentName + "`, expected an array.")
|
|
);
|
|
}
|
|
for (var i = 0; i < propValue.length; i++) {
|
|
var error = typeChecker(propValue, i, componentName, location);
|
|
if (error instanceof Error) {
|
|
return error;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
return createChainableTypeChecker(validate);
|
|
}
|
|
|
|
function createElementTypeChecker() {
|
|
function validate(props, propName, componentName, location) {
|
|
if (!ReactElement.isValidElement(props[propName])) {
|
|
var locationName = ReactPropTypeLocationNames[location];
|
|
return new Error(
|
|
("Invalid " + locationName + " `" + propName + "` supplied to ") +
|
|
("`" + componentName + "`, expected a ReactElement.")
|
|
);
|
|
}
|
|
return null;
|
|
}
|
|
return createChainableTypeChecker(validate);
|
|
}
|
|
|
|
function createInstanceTypeChecker(expectedClass) {
|
|
function validate(props, propName, componentName, location) {
|
|
if (!(props[propName] instanceof expectedClass)) {
|
|
var locationName = ReactPropTypeLocationNames[location];
|
|
var expectedClassName = expectedClass.name || ANONYMOUS;
|
|
return new Error(
|
|
("Invalid " + locationName + " `" + propName + "` supplied to ") +
|
|
("`" + componentName + "`, expected instance of `" + expectedClassName + "`.")
|
|
);
|
|
}
|
|
return null;
|
|
}
|
|
return createChainableTypeChecker(validate);
|
|
}
|
|
|
|
function createEnumTypeChecker(expectedValues) {
|
|
function validate(props, propName, componentName, location) {
|
|
var propValue = props[propName];
|
|
for (var i = 0; i < expectedValues.length; i++) {
|
|
if (propValue === expectedValues[i]) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
var locationName = ReactPropTypeLocationNames[location];
|
|
var valuesString = JSON.stringify(expectedValues);
|
|
return new Error(
|
|
("Invalid " + locationName + " `" + propName + "` of value `" + propValue + "` ") +
|
|
("supplied to `" + componentName + "`, expected one of " + valuesString + ".")
|
|
);
|
|
}
|
|
return createChainableTypeChecker(validate);
|
|
}
|
|
|
|
function createObjectOfTypeChecker(typeChecker) {
|
|
function validate(props, propName, componentName, location) {
|
|
var propValue = props[propName];
|
|
var propType = getPropType(propValue);
|
|
if (propType !== 'object') {
|
|
var locationName = ReactPropTypeLocationNames[location];
|
|
return new Error(
|
|
("Invalid " + locationName + " `" + propName + "` of type ") +
|
|
("`" + propType + "` supplied to `" + componentName + "`, expected an object.")
|
|
);
|
|
}
|
|
for (var key in propValue) {
|
|
if (propValue.hasOwnProperty(key)) {
|
|
var error = typeChecker(propValue, key, componentName, location);
|
|
if (error instanceof Error) {
|
|
return error;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
return createChainableTypeChecker(validate);
|
|
}
|
|
|
|
function createUnionTypeChecker(arrayOfTypeCheckers) {
|
|
function validate(props, propName, componentName, location) {
|
|
for (var i = 0; i < arrayOfTypeCheckers.length; i++) {
|
|
var checker = arrayOfTypeCheckers[i];
|
|
if (checker(props, propName, componentName, location) == null) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
var locationName = ReactPropTypeLocationNames[location];
|
|
return new Error(
|
|
("Invalid " + locationName + " `" + propName + "` supplied to ") +
|
|
("`" + componentName + "`.")
|
|
);
|
|
}
|
|
return createChainableTypeChecker(validate);
|
|
}
|
|
|
|
function createNodeChecker() {
|
|
function validate(props, propName, componentName, location) {
|
|
if (!isNode(props[propName])) {
|
|
var locationName = ReactPropTypeLocationNames[location];
|
|
return new Error(
|
|
("Invalid " + locationName + " `" + propName + "` supplied to ") +
|
|
("`" + componentName + "`, expected a ReactNode.")
|
|
);
|
|
}
|
|
return null;
|
|
}
|
|
return createChainableTypeChecker(validate);
|
|
}
|
|
|
|
function createShapeTypeChecker(shapeTypes) {
|
|
function validate(props, propName, componentName, location) {
|
|
var propValue = props[propName];
|
|
var propType = getPropType(propValue);
|
|
if (propType !== 'object') {
|
|
var locationName = ReactPropTypeLocationNames[location];
|
|
return new Error(
|
|
("Invalid " + locationName + " `" + propName + "` of type `" + propType + "` ") +
|
|
("supplied to `" + componentName + "`, expected `object`.")
|
|
);
|
|
}
|
|
for (var key in shapeTypes) {
|
|
var checker = shapeTypes[key];
|
|
if (!checker) {
|
|
continue;
|
|
}
|
|
var error = checker(propValue, key, componentName, location);
|
|
if (error) {
|
|
return error;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
return createChainableTypeChecker(validate);
|
|
}
|
|
|
|
function isNode(propValue) {
|
|
switch (typeof propValue) {
|
|
case 'number':
|
|
case 'string':
|
|
case 'undefined':
|
|
return true;
|
|
case 'boolean':
|
|
return !propValue;
|
|
case 'object':
|
|
if (Array.isArray(propValue)) {
|
|
return propValue.every(isNode);
|
|
}
|
|
if (propValue === null || ReactElement.isValidElement(propValue)) {
|
|
return true;
|
|
}
|
|
propValue = ReactFragment.extractIfFragment(propValue);
|
|
for (var k in propValue) {
|
|
if (!isNode(propValue[k])) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Equivalent of `typeof` but with special handling for array and regexp.
|
|
function getPropType(propValue) {
|
|
var propType = typeof propValue;
|
|
if (Array.isArray(propValue)) {
|
|
return 'array';
|
|
}
|
|
if (propValue instanceof RegExp) {
|
|
// Old webkits (at least until Android 4.0) return 'function' rather than
|
|
// 'object' for typeof a RegExp. We'll normalize this here so that /bla/
|
|
// passes PropTypes.object.
|
|
return 'object';
|
|
}
|
|
return propType;
|
|
}
|
|
|
|
// This handles more types than `getPropType`. Only used for error messages.
|
|
// See `createPrimitiveTypeChecker`.
|
|
function getPreciseType(propValue) {
|
|
var propType = getPropType(propValue);
|
|
if (propType === 'object') {
|
|
if (propValue instanceof Date) {
|
|
return 'date';
|
|
} else if (propValue instanceof RegExp) {
|
|
return 'regexp';
|
|
}
|
|
}
|
|
return propType;
|
|
}
|
|
|
|
module.exports = ReactPropTypes;
|
|
|
|
},{"./ReactElement":107,"./ReactFragment":113,"./ReactPropTypeLocationNames":126,"./emptyFunction":164}],129:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactPutListenerQueue
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var PooledClass = require("./PooledClass");
|
|
var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter");
|
|
|
|
var assign = require("./Object.assign");
|
|
|
|
function ReactPutListenerQueue() {
|
|
this.listenersToPut = [];
|
|
}
|
|
|
|
assign(ReactPutListenerQueue.prototype, {
|
|
enqueuePutListener: function(rootNodeID, propKey, propValue) {
|
|
this.listenersToPut.push({
|
|
rootNodeID: rootNodeID,
|
|
propKey: propKey,
|
|
propValue: propValue
|
|
});
|
|
},
|
|
|
|
putListeners: function() {
|
|
for (var i = 0; i < this.listenersToPut.length; i++) {
|
|
var listenerToPut = this.listenersToPut[i];
|
|
ReactBrowserEventEmitter.putListener(
|
|
listenerToPut.rootNodeID,
|
|
listenerToPut.propKey,
|
|
listenerToPut.propValue
|
|
);
|
|
}
|
|
},
|
|
|
|
reset: function() {
|
|
this.listenersToPut.length = 0;
|
|
},
|
|
|
|
destructor: function() {
|
|
this.reset();
|
|
}
|
|
});
|
|
|
|
PooledClass.addPoolingTo(ReactPutListenerQueue);
|
|
|
|
module.exports = ReactPutListenerQueue;
|
|
|
|
},{"./Object.assign":76,"./PooledClass":77,"./ReactBrowserEventEmitter":80}],130:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactReconcileTransaction
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var CallbackQueue = require("./CallbackQueue");
|
|
var PooledClass = require("./PooledClass");
|
|
var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter");
|
|
var ReactInputSelection = require("./ReactInputSelection");
|
|
var ReactPutListenerQueue = require("./ReactPutListenerQueue");
|
|
var Transaction = require("./Transaction");
|
|
|
|
var assign = require("./Object.assign");
|
|
|
|
/**
|
|
* Ensures that, when possible, the selection range (currently selected text
|
|
* input) is not disturbed by performing the transaction.
|
|
*/
|
|
var SELECTION_RESTORATION = {
|
|
/**
|
|
* @return {Selection} Selection information.
|
|
*/
|
|
initialize: ReactInputSelection.getSelectionInformation,
|
|
/**
|
|
* @param {Selection} sel Selection information returned from `initialize`.
|
|
*/
|
|
close: ReactInputSelection.restoreSelection
|
|
};
|
|
|
|
/**
|
|
* Suppresses events (blur/focus) that could be inadvertently dispatched due to
|
|
* high level DOM manipulations (like temporarily removing a text input from the
|
|
* DOM).
|
|
*/
|
|
var EVENT_SUPPRESSION = {
|
|
/**
|
|
* @return {boolean} The enabled status of `ReactBrowserEventEmitter` before
|
|
* the reconciliation.
|
|
*/
|
|
initialize: function() {
|
|
var currentlyEnabled = ReactBrowserEventEmitter.isEnabled();
|
|
ReactBrowserEventEmitter.setEnabled(false);
|
|
return currentlyEnabled;
|
|
},
|
|
|
|
/**
|
|
* @param {boolean} previouslyEnabled Enabled status of
|
|
* `ReactBrowserEventEmitter` before the reconciliation occured. `close`
|
|
* restores the previous value.
|
|
*/
|
|
close: function(previouslyEnabled) {
|
|
ReactBrowserEventEmitter.setEnabled(previouslyEnabled);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Provides a queue for collecting `componentDidMount` and
|
|
* `componentDidUpdate` callbacks during the the transaction.
|
|
*/
|
|
var ON_DOM_READY_QUEUEING = {
|
|
/**
|
|
* Initializes the internal `onDOMReady` queue.
|
|
*/
|
|
initialize: function() {
|
|
this.reactMountReady.reset();
|
|
},
|
|
|
|
/**
|
|
* After DOM is flushed, invoke all registered `onDOMReady` callbacks.
|
|
*/
|
|
close: function() {
|
|
this.reactMountReady.notifyAll();
|
|
}
|
|
};
|
|
|
|
var PUT_LISTENER_QUEUEING = {
|
|
initialize: function() {
|
|
this.putListenerQueue.reset();
|
|
},
|
|
|
|
close: function() {
|
|
this.putListenerQueue.putListeners();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Executed within the scope of the `Transaction` instance. Consider these as
|
|
* being member methods, but with an implied ordering while being isolated from
|
|
* each other.
|
|
*/
|
|
var TRANSACTION_WRAPPERS = [
|
|
PUT_LISTENER_QUEUEING,
|
|
SELECTION_RESTORATION,
|
|
EVENT_SUPPRESSION,
|
|
ON_DOM_READY_QUEUEING
|
|
];
|
|
|
|
/**
|
|
* Currently:
|
|
* - The order that these are listed in the transaction is critical:
|
|
* - Suppresses events.
|
|
* - Restores selection range.
|
|
*
|
|
* Future:
|
|
* - Restore document/overflow scroll positions that were unintentionally
|
|
* modified via DOM insertions above the top viewport boundary.
|
|
* - Implement/integrate with customized constraint based layout system and keep
|
|
* track of which dimensions must be remeasured.
|
|
*
|
|
* @class ReactReconcileTransaction
|
|
*/
|
|
function ReactReconcileTransaction() {
|
|
this.reinitializeTransaction();
|
|
// Only server-side rendering really needs this option (see
|
|
// `ReactServerRendering`), but server-side uses
|
|
// `ReactServerRenderingTransaction` instead. This option is here so that it's
|
|
// accessible and defaults to false when `ReactDOMComponent` and
|
|
// `ReactTextComponent` checks it in `mountComponent`.`
|
|
this.renderToStaticMarkup = false;
|
|
this.reactMountReady = CallbackQueue.getPooled(null);
|
|
this.putListenerQueue = ReactPutListenerQueue.getPooled();
|
|
}
|
|
|
|
var Mixin = {
|
|
/**
|
|
* @see Transaction
|
|
* @abstract
|
|
* @final
|
|
* @return {array<object>} List of operation wrap proceedures.
|
|
* TODO: convert to array<TransactionWrapper>
|
|
*/
|
|
getTransactionWrappers: function() {
|
|
return TRANSACTION_WRAPPERS;
|
|
},
|
|
|
|
/**
|
|
* @return {object} The queue to collect `onDOMReady` callbacks with.
|
|
*/
|
|
getReactMountReady: function() {
|
|
return this.reactMountReady;
|
|
},
|
|
|
|
getPutListenerQueue: function() {
|
|
return this.putListenerQueue;
|
|
},
|
|
|
|
/**
|
|
* `PooledClass` looks for this, and will invoke this before allowing this
|
|
* instance to be resused.
|
|
*/
|
|
destructor: function() {
|
|
CallbackQueue.release(this.reactMountReady);
|
|
this.reactMountReady = null;
|
|
|
|
ReactPutListenerQueue.release(this.putListenerQueue);
|
|
this.putListenerQueue = null;
|
|
}
|
|
};
|
|
|
|
|
|
assign(ReactReconcileTransaction.prototype, Transaction.Mixin, Mixin);
|
|
|
|
PooledClass.addPoolingTo(ReactReconcileTransaction);
|
|
|
|
module.exports = ReactReconcileTransaction;
|
|
|
|
},{"./CallbackQueue":55,"./Object.assign":76,"./PooledClass":77,"./ReactBrowserEventEmitter":80,"./ReactInputSelection":115,"./ReactPutListenerQueue":129,"./Transaction":153}],131:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactReconciler
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactRef = require("./ReactRef");
|
|
var ReactElementValidator = require("./ReactElementValidator");
|
|
|
|
/**
|
|
* Helper to call ReactRef.attachRefs with this composite component, split out
|
|
* to avoid allocations in the transaction mount-ready queue.
|
|
*/
|
|
function attachRefs() {
|
|
ReactRef.attachRefs(this, this._currentElement);
|
|
}
|
|
|
|
var ReactReconciler = {
|
|
|
|
/**
|
|
* Initializes the component, renders markup, and registers event listeners.
|
|
*
|
|
* @param {ReactComponent} internalInstance
|
|
* @param {string} rootID DOM ID of the root node.
|
|
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
|
|
* @return {?string} Rendered markup to be inserted into the DOM.
|
|
* @final
|
|
* @internal
|
|
*/
|
|
mountComponent: function(internalInstance, rootID, transaction, context) {
|
|
var markup = internalInstance.mountComponent(rootID, transaction, context);
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
ReactElementValidator.checkAndWarnForMutatedProps(
|
|
internalInstance._currentElement
|
|
);
|
|
}
|
|
transaction.getReactMountReady().enqueue(attachRefs, internalInstance);
|
|
return markup;
|
|
},
|
|
|
|
/**
|
|
* Releases any resources allocated by `mountComponent`.
|
|
*
|
|
* @final
|
|
* @internal
|
|
*/
|
|
unmountComponent: function(internalInstance) {
|
|
ReactRef.detachRefs(internalInstance, internalInstance._currentElement);
|
|
internalInstance.unmountComponent();
|
|
},
|
|
|
|
/**
|
|
* Update a component using a new element.
|
|
*
|
|
* @param {ReactComponent} internalInstance
|
|
* @param {ReactElement} nextElement
|
|
* @param {ReactReconcileTransaction} transaction
|
|
* @param {object} context
|
|
* @internal
|
|
*/
|
|
receiveComponent: function(
|
|
internalInstance, nextElement, transaction, context
|
|
) {
|
|
var prevElement = internalInstance._currentElement;
|
|
|
|
if (nextElement === prevElement && nextElement._owner != null) {
|
|
// Since elements are immutable after the owner is rendered,
|
|
// we can do a cheap identity compare here to determine if this is a
|
|
// superfluous reconcile. It's possible for state to be mutable but such
|
|
// change should trigger an update of the owner which would recreate
|
|
// the element. We explicitly check for the existence of an owner since
|
|
// it's possible for an element created outside a composite to be
|
|
// deeply mutated and reused.
|
|
return;
|
|
}
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
ReactElementValidator.checkAndWarnForMutatedProps(nextElement);
|
|
}
|
|
|
|
var refsChanged = ReactRef.shouldUpdateRefs(
|
|
prevElement,
|
|
nextElement
|
|
);
|
|
|
|
if (refsChanged) {
|
|
ReactRef.detachRefs(internalInstance, prevElement);
|
|
}
|
|
|
|
internalInstance.receiveComponent(nextElement, transaction, context);
|
|
|
|
if (refsChanged) {
|
|
transaction.getReactMountReady().enqueue(attachRefs, internalInstance);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Flush any dirty changes in a component.
|
|
*
|
|
* @param {ReactComponent} internalInstance
|
|
* @param {ReactReconcileTransaction} transaction
|
|
* @internal
|
|
*/
|
|
performUpdateIfNecessary: function(
|
|
internalInstance,
|
|
transaction
|
|
) {
|
|
internalInstance.performUpdateIfNecessary(transaction);
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = ReactReconciler;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./ReactElementValidator":108,"./ReactRef":132,"_process":1}],132:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactRef
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactOwner = require("./ReactOwner");
|
|
|
|
var ReactRef = {};
|
|
|
|
function attachRef(ref, component, owner) {
|
|
if (typeof ref === 'function') {
|
|
ref(component.getPublicInstance());
|
|
} else {
|
|
// Legacy ref
|
|
ReactOwner.addComponentAsRefTo(component, ref, owner);
|
|
}
|
|
}
|
|
|
|
function detachRef(ref, component, owner) {
|
|
if (typeof ref === 'function') {
|
|
ref(null);
|
|
} else {
|
|
// Legacy ref
|
|
ReactOwner.removeComponentAsRefFrom(component, ref, owner);
|
|
}
|
|
}
|
|
|
|
ReactRef.attachRefs = function(instance, element) {
|
|
var ref = element.ref;
|
|
if (ref != null) {
|
|
attachRef(ref, instance, element._owner);
|
|
}
|
|
};
|
|
|
|
ReactRef.shouldUpdateRefs = function(prevElement, nextElement) {
|
|
// If either the owner or a `ref` has changed, make sure the newest owner
|
|
// has stored a reference to `this`, and the previous owner (if different)
|
|
// has forgotten the reference to `this`. We use the element instead
|
|
// of the public this.props because the post processing cannot determine
|
|
// a ref. The ref conceptually lives on the element.
|
|
|
|
// TODO: Should this even be possible? The owner cannot change because
|
|
// it's forbidden by shouldUpdateReactComponent. The ref can change
|
|
// if you swap the keys of but not the refs. Reconsider where this check
|
|
// is made. It probably belongs where the key checking and
|
|
// instantiateReactComponent is done.
|
|
|
|
return (
|
|
nextElement._owner !== prevElement._owner ||
|
|
nextElement.ref !== prevElement.ref
|
|
);
|
|
};
|
|
|
|
ReactRef.detachRefs = function(instance, element) {
|
|
var ref = element.ref;
|
|
if (ref != null) {
|
|
detachRef(ref, instance, element._owner);
|
|
}
|
|
};
|
|
|
|
module.exports = ReactRef;
|
|
|
|
},{"./ReactOwner":124}],133:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactRootIndex
|
|
* @typechecks
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactRootIndexInjection = {
|
|
/**
|
|
* @param {function} _createReactRootIndex
|
|
*/
|
|
injectCreateReactRootIndex: function(_createReactRootIndex) {
|
|
ReactRootIndex.createReactRootIndex = _createReactRootIndex;
|
|
}
|
|
};
|
|
|
|
var ReactRootIndex = {
|
|
createReactRootIndex: null,
|
|
injection: ReactRootIndexInjection
|
|
};
|
|
|
|
module.exports = ReactRootIndex;
|
|
|
|
},{}],134:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @typechecks static-only
|
|
* @providesModule ReactServerRendering
|
|
*/
|
|
'use strict';
|
|
|
|
var ReactElement = require("./ReactElement");
|
|
var ReactInstanceHandles = require("./ReactInstanceHandles");
|
|
var ReactMarkupChecksum = require("./ReactMarkupChecksum");
|
|
var ReactServerRenderingTransaction =
|
|
require("./ReactServerRenderingTransaction");
|
|
|
|
var emptyObject = require("./emptyObject");
|
|
var instantiateReactComponent = require("./instantiateReactComponent");
|
|
var invariant = require("./invariant");
|
|
|
|
/**
|
|
* @param {ReactElement} element
|
|
* @return {string} the HTML markup
|
|
*/
|
|
function renderToString(element) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
ReactElement.isValidElement(element),
|
|
'renderToString(): You must pass a valid ReactElement.'
|
|
) : invariant(ReactElement.isValidElement(element)));
|
|
|
|
var transaction;
|
|
try {
|
|
var id = ReactInstanceHandles.createReactRootID();
|
|
transaction = ReactServerRenderingTransaction.getPooled(false);
|
|
|
|
return transaction.perform(function() {
|
|
var componentInstance = instantiateReactComponent(element, null);
|
|
var markup =
|
|
componentInstance.mountComponent(id, transaction, emptyObject);
|
|
return ReactMarkupChecksum.addChecksumToMarkup(markup);
|
|
}, null);
|
|
} finally {
|
|
ReactServerRenderingTransaction.release(transaction);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {ReactElement} element
|
|
* @return {string} the HTML markup, without the extra React ID and checksum
|
|
* (for generating static pages)
|
|
*/
|
|
function renderToStaticMarkup(element) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
ReactElement.isValidElement(element),
|
|
'renderToStaticMarkup(): You must pass a valid ReactElement.'
|
|
) : invariant(ReactElement.isValidElement(element)));
|
|
|
|
var transaction;
|
|
try {
|
|
var id = ReactInstanceHandles.createReactRootID();
|
|
transaction = ReactServerRenderingTransaction.getPooled(true);
|
|
|
|
return transaction.perform(function() {
|
|
var componentInstance = instantiateReactComponent(element, null);
|
|
return componentInstance.mountComponent(id, transaction, emptyObject);
|
|
}, null);
|
|
} finally {
|
|
ReactServerRenderingTransaction.release(transaction);
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
renderToString: renderToString,
|
|
renderToStaticMarkup: renderToStaticMarkup
|
|
};
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./ReactElement":107,"./ReactInstanceHandles":116,"./ReactMarkupChecksum":119,"./ReactServerRenderingTransaction":135,"./emptyObject":165,"./instantiateReactComponent":184,"./invariant":185,"_process":1}],135:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2014-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactServerRenderingTransaction
|
|
* @typechecks
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var PooledClass = require("./PooledClass");
|
|
var CallbackQueue = require("./CallbackQueue");
|
|
var ReactPutListenerQueue = require("./ReactPutListenerQueue");
|
|
var Transaction = require("./Transaction");
|
|
|
|
var assign = require("./Object.assign");
|
|
var emptyFunction = require("./emptyFunction");
|
|
|
|
/**
|
|
* Provides a `CallbackQueue` queue for collecting `onDOMReady` callbacks
|
|
* during the performing of the transaction.
|
|
*/
|
|
var ON_DOM_READY_QUEUEING = {
|
|
/**
|
|
* Initializes the internal `onDOMReady` queue.
|
|
*/
|
|
initialize: function() {
|
|
this.reactMountReady.reset();
|
|
},
|
|
|
|
close: emptyFunction
|
|
};
|
|
|
|
var PUT_LISTENER_QUEUEING = {
|
|
initialize: function() {
|
|
this.putListenerQueue.reset();
|
|
},
|
|
|
|
close: emptyFunction
|
|
};
|
|
|
|
/**
|
|
* Executed within the scope of the `Transaction` instance. Consider these as
|
|
* being member methods, but with an implied ordering while being isolated from
|
|
* each other.
|
|
*/
|
|
var TRANSACTION_WRAPPERS = [
|
|
PUT_LISTENER_QUEUEING,
|
|
ON_DOM_READY_QUEUEING
|
|
];
|
|
|
|
/**
|
|
* @class ReactServerRenderingTransaction
|
|
* @param {boolean} renderToStaticMarkup
|
|
*/
|
|
function ReactServerRenderingTransaction(renderToStaticMarkup) {
|
|
this.reinitializeTransaction();
|
|
this.renderToStaticMarkup = renderToStaticMarkup;
|
|
this.reactMountReady = CallbackQueue.getPooled(null);
|
|
this.putListenerQueue = ReactPutListenerQueue.getPooled();
|
|
}
|
|
|
|
var Mixin = {
|
|
/**
|
|
* @see Transaction
|
|
* @abstract
|
|
* @final
|
|
* @return {array} Empty list of operation wrap proceedures.
|
|
*/
|
|
getTransactionWrappers: function() {
|
|
return TRANSACTION_WRAPPERS;
|
|
},
|
|
|
|
/**
|
|
* @return {object} The queue to collect `onDOMReady` callbacks with.
|
|
*/
|
|
getReactMountReady: function() {
|
|
return this.reactMountReady;
|
|
},
|
|
|
|
getPutListenerQueue: function() {
|
|
return this.putListenerQueue;
|
|
},
|
|
|
|
/**
|
|
* `PooledClass` looks for this, and will invoke this before allowing this
|
|
* instance to be resused.
|
|
*/
|
|
destructor: function() {
|
|
CallbackQueue.release(this.reactMountReady);
|
|
this.reactMountReady = null;
|
|
|
|
ReactPutListenerQueue.release(this.putListenerQueue);
|
|
this.putListenerQueue = null;
|
|
}
|
|
};
|
|
|
|
|
|
assign(
|
|
ReactServerRenderingTransaction.prototype,
|
|
Transaction.Mixin,
|
|
Mixin
|
|
);
|
|
|
|
PooledClass.addPoolingTo(ReactServerRenderingTransaction);
|
|
|
|
module.exports = ReactServerRenderingTransaction;
|
|
|
|
},{"./CallbackQueue":55,"./Object.assign":76,"./PooledClass":77,"./ReactPutListenerQueue":129,"./Transaction":153,"./emptyFunction":164}],136:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactUpdateQueue
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactLifeCycle = require("./ReactLifeCycle");
|
|
var ReactCurrentOwner = require("./ReactCurrentOwner");
|
|
var ReactElement = require("./ReactElement");
|
|
var ReactInstanceMap = require("./ReactInstanceMap");
|
|
var ReactUpdates = require("./ReactUpdates");
|
|
|
|
var assign = require("./Object.assign");
|
|
var invariant = require("./invariant");
|
|
var warning = require("./warning");
|
|
|
|
function enqueueUpdate(internalInstance) {
|
|
if (internalInstance !== ReactLifeCycle.currentlyMountingInstance) {
|
|
// If we're in a componentWillMount handler, don't enqueue a rerender
|
|
// because ReactUpdates assumes we're in a browser context (which is
|
|
// wrong for server rendering) and we're about to do a render anyway.
|
|
// See bug in #1740.
|
|
ReactUpdates.enqueueUpdate(internalInstance);
|
|
}
|
|
}
|
|
|
|
function getInternalInstanceReadyForUpdate(publicInstance, callerName) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
ReactCurrentOwner.current == null,
|
|
'%s(...): Cannot update during an existing state transition ' +
|
|
'(such as within `render`). Render methods should be a pure function ' +
|
|
'of props and state.',
|
|
callerName
|
|
) : invariant(ReactCurrentOwner.current == null));
|
|
|
|
var internalInstance = ReactInstanceMap.get(publicInstance);
|
|
if (!internalInstance) {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
// Only warn when we have a callerName. Otherwise we should be silent.
|
|
// We're probably calling from enqueueCallback. We don't want to warn
|
|
// there because we already warned for the corresponding lifecycle method.
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
!callerName,
|
|
'%s(...): Can only update a mounted or mounting component. ' +
|
|
'This usually means you called %s() on an unmounted ' +
|
|
'component. This is a no-op.',
|
|
callerName,
|
|
callerName
|
|
) : null);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
if (internalInstance === ReactLifeCycle.currentlyUnmountingInstance) {
|
|
return null;
|
|
}
|
|
|
|
return internalInstance;
|
|
}
|
|
|
|
/**
|
|
* ReactUpdateQueue allows for state updates to be scheduled into a later
|
|
* reconciliation step.
|
|
*/
|
|
var ReactUpdateQueue = {
|
|
|
|
/**
|
|
* Enqueue a callback that will be executed after all the pending updates
|
|
* have processed.
|
|
*
|
|
* @param {ReactClass} publicInstance The instance to use as `this` context.
|
|
* @param {?function} callback Called after state is updated.
|
|
* @internal
|
|
*/
|
|
enqueueCallback: function(publicInstance, callback) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
typeof callback === 'function',
|
|
'enqueueCallback(...): You called `setProps`, `replaceProps`, ' +
|
|
'`setState`, `replaceState`, or `forceUpdate` with a callback that ' +
|
|
'isn\'t callable.'
|
|
) : invariant(typeof callback === 'function'));
|
|
var internalInstance = getInternalInstanceReadyForUpdate(publicInstance);
|
|
|
|
// Previously we would throw an error if we didn't have an internal
|
|
// instance. Since we want to make it a no-op instead, we mirror the same
|
|
// behavior we have in other enqueue* methods.
|
|
// We also need to ignore callbacks in componentWillMount. See
|
|
// enqueueUpdates.
|
|
if (!internalInstance ||
|
|
internalInstance === ReactLifeCycle.currentlyMountingInstance) {
|
|
return null;
|
|
}
|
|
|
|
if (internalInstance._pendingCallbacks) {
|
|
internalInstance._pendingCallbacks.push(callback);
|
|
} else {
|
|
internalInstance._pendingCallbacks = [callback];
|
|
}
|
|
// TODO: The callback here is ignored when setState is called from
|
|
// componentWillMount. Either fix it or disallow doing so completely in
|
|
// favor of getInitialState. Alternatively, we can disallow
|
|
// componentWillMount during server-side rendering.
|
|
enqueueUpdate(internalInstance);
|
|
},
|
|
|
|
enqueueCallbackInternal: function(internalInstance, callback) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
typeof callback === 'function',
|
|
'enqueueCallback(...): You called `setProps`, `replaceProps`, ' +
|
|
'`setState`, `replaceState`, or `forceUpdate` with a callback that ' +
|
|
'isn\'t callable.'
|
|
) : invariant(typeof callback === 'function'));
|
|
if (internalInstance._pendingCallbacks) {
|
|
internalInstance._pendingCallbacks.push(callback);
|
|
} else {
|
|
internalInstance._pendingCallbacks = [callback];
|
|
}
|
|
enqueueUpdate(internalInstance);
|
|
},
|
|
|
|
/**
|
|
* Forces an update. This should only be invoked when it is known with
|
|
* certainty that we are **not** in a DOM transaction.
|
|
*
|
|
* You may want to call this when you know that some deeper aspect of the
|
|
* component's state has changed but `setState` was not called.
|
|
*
|
|
* This will not invoke `shouldUpdateComponent`, but it will invoke
|
|
* `componentWillUpdate` and `componentDidUpdate`.
|
|
*
|
|
* @param {ReactClass} publicInstance The instance that should rerender.
|
|
* @internal
|
|
*/
|
|
enqueueForceUpdate: function(publicInstance) {
|
|
var internalInstance = getInternalInstanceReadyForUpdate(
|
|
publicInstance,
|
|
'forceUpdate'
|
|
);
|
|
|
|
if (!internalInstance) {
|
|
return;
|
|
}
|
|
|
|
internalInstance._pendingForceUpdate = true;
|
|
|
|
enqueueUpdate(internalInstance);
|
|
},
|
|
|
|
/**
|
|
* Replaces all of the state. Always use this or `setState` to mutate state.
|
|
* You should treat `this.state` as immutable.
|
|
*
|
|
* There is no guarantee that `this.state` will be immediately updated, so
|
|
* accessing `this.state` after calling this method may return the old value.
|
|
*
|
|
* @param {ReactClass} publicInstance The instance that should rerender.
|
|
* @param {object} completeState Next state.
|
|
* @internal
|
|
*/
|
|
enqueueReplaceState: function(publicInstance, completeState) {
|
|
var internalInstance = getInternalInstanceReadyForUpdate(
|
|
publicInstance,
|
|
'replaceState'
|
|
);
|
|
|
|
if (!internalInstance) {
|
|
return;
|
|
}
|
|
|
|
internalInstance._pendingStateQueue = [completeState];
|
|
internalInstance._pendingReplaceState = true;
|
|
|
|
enqueueUpdate(internalInstance);
|
|
},
|
|
|
|
/**
|
|
* Sets a subset of the state. This only exists because _pendingState is
|
|
* internal. This provides a merging strategy that is not available to deep
|
|
* properties which is confusing. TODO: Expose pendingState or don't use it
|
|
* during the merge.
|
|
*
|
|
* @param {ReactClass} publicInstance The instance that should rerender.
|
|
* @param {object} partialState Next partial state to be merged with state.
|
|
* @internal
|
|
*/
|
|
enqueueSetState: function(publicInstance, partialState) {
|
|
var internalInstance = getInternalInstanceReadyForUpdate(
|
|
publicInstance,
|
|
'setState'
|
|
);
|
|
|
|
if (!internalInstance) {
|
|
return;
|
|
}
|
|
|
|
var queue =
|
|
internalInstance._pendingStateQueue ||
|
|
(internalInstance._pendingStateQueue = []);
|
|
queue.push(partialState);
|
|
|
|
enqueueUpdate(internalInstance);
|
|
},
|
|
|
|
/**
|
|
* Sets a subset of the props.
|
|
*
|
|
* @param {ReactClass} publicInstance The instance that should rerender.
|
|
* @param {object} partialProps Subset of the next props.
|
|
* @internal
|
|
*/
|
|
enqueueSetProps: function(publicInstance, partialProps) {
|
|
var internalInstance = getInternalInstanceReadyForUpdate(
|
|
publicInstance,
|
|
'setProps'
|
|
);
|
|
|
|
if (!internalInstance) {
|
|
return;
|
|
}
|
|
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
internalInstance._isTopLevel,
|
|
'setProps(...): You called `setProps` on a ' +
|
|
'component with a parent. This is an anti-pattern since props will ' +
|
|
'get reactively updated when rendered. Instead, change the owner\'s ' +
|
|
'`render` method to pass the correct value as props to the component ' +
|
|
'where it is created.'
|
|
) : invariant(internalInstance._isTopLevel));
|
|
|
|
// Merge with the pending element if it exists, otherwise with existing
|
|
// element props.
|
|
var element = internalInstance._pendingElement ||
|
|
internalInstance._currentElement;
|
|
var props = assign({}, element.props, partialProps);
|
|
internalInstance._pendingElement = ReactElement.cloneAndReplaceProps(
|
|
element,
|
|
props
|
|
);
|
|
|
|
enqueueUpdate(internalInstance);
|
|
},
|
|
|
|
/**
|
|
* Replaces all of the props.
|
|
*
|
|
* @param {ReactClass} publicInstance The instance that should rerender.
|
|
* @param {object} props New props.
|
|
* @internal
|
|
*/
|
|
enqueueReplaceProps: function(publicInstance, props) {
|
|
var internalInstance = getInternalInstanceReadyForUpdate(
|
|
publicInstance,
|
|
'replaceProps'
|
|
);
|
|
|
|
if (!internalInstance) {
|
|
return;
|
|
}
|
|
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
internalInstance._isTopLevel,
|
|
'replaceProps(...): You called `replaceProps` on a ' +
|
|
'component with a parent. This is an anti-pattern since props will ' +
|
|
'get reactively updated when rendered. Instead, change the owner\'s ' +
|
|
'`render` method to pass the correct value as props to the component ' +
|
|
'where it is created.'
|
|
) : invariant(internalInstance._isTopLevel));
|
|
|
|
// Merge with the pending element if it exists, otherwise with existing
|
|
// element props.
|
|
var element = internalInstance._pendingElement ||
|
|
internalInstance._currentElement;
|
|
internalInstance._pendingElement = ReactElement.cloneAndReplaceProps(
|
|
element,
|
|
props
|
|
);
|
|
|
|
enqueueUpdate(internalInstance);
|
|
},
|
|
|
|
enqueueElementInternal: function(internalInstance, newElement) {
|
|
internalInstance._pendingElement = newElement;
|
|
enqueueUpdate(internalInstance);
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = ReactUpdateQueue;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./Object.assign":76,"./ReactCurrentOwner":89,"./ReactElement":107,"./ReactInstanceMap":117,"./ReactLifeCycle":118,"./ReactUpdates":137,"./invariant":185,"./warning":204,"_process":1}],137:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ReactUpdates
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var CallbackQueue = require("./CallbackQueue");
|
|
var PooledClass = require("./PooledClass");
|
|
var ReactCurrentOwner = require("./ReactCurrentOwner");
|
|
var ReactPerf = require("./ReactPerf");
|
|
var ReactReconciler = require("./ReactReconciler");
|
|
var Transaction = require("./Transaction");
|
|
|
|
var assign = require("./Object.assign");
|
|
var invariant = require("./invariant");
|
|
var warning = require("./warning");
|
|
|
|
var dirtyComponents = [];
|
|
var asapCallbackQueue = CallbackQueue.getPooled();
|
|
var asapEnqueued = false;
|
|
|
|
var batchingStrategy = null;
|
|
|
|
function ensureInjected() {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
ReactUpdates.ReactReconcileTransaction && batchingStrategy,
|
|
'ReactUpdates: must inject a reconcile transaction class and batching ' +
|
|
'strategy'
|
|
) : invariant(ReactUpdates.ReactReconcileTransaction && batchingStrategy));
|
|
}
|
|
|
|
var NESTED_UPDATES = {
|
|
initialize: function() {
|
|
this.dirtyComponentsLength = dirtyComponents.length;
|
|
},
|
|
close: function() {
|
|
if (this.dirtyComponentsLength !== dirtyComponents.length) {
|
|
// Additional updates were enqueued by componentDidUpdate handlers or
|
|
// similar; before our own UPDATE_QUEUEING wrapper closes, we want to run
|
|
// these new updates so that if A's componentDidUpdate calls setState on
|
|
// B, B will update before the callback A's updater provided when calling
|
|
// setState.
|
|
dirtyComponents.splice(0, this.dirtyComponentsLength);
|
|
flushBatchedUpdates();
|
|
} else {
|
|
dirtyComponents.length = 0;
|
|
}
|
|
}
|
|
};
|
|
|
|
var UPDATE_QUEUEING = {
|
|
initialize: function() {
|
|
this.callbackQueue.reset();
|
|
},
|
|
close: function() {
|
|
this.callbackQueue.notifyAll();
|
|
}
|
|
};
|
|
|
|
var TRANSACTION_WRAPPERS = [NESTED_UPDATES, UPDATE_QUEUEING];
|
|
|
|
function ReactUpdatesFlushTransaction() {
|
|
this.reinitializeTransaction();
|
|
this.dirtyComponentsLength = null;
|
|
this.callbackQueue = CallbackQueue.getPooled();
|
|
this.reconcileTransaction =
|
|
ReactUpdates.ReactReconcileTransaction.getPooled();
|
|
}
|
|
|
|
assign(
|
|
ReactUpdatesFlushTransaction.prototype,
|
|
Transaction.Mixin, {
|
|
getTransactionWrappers: function() {
|
|
return TRANSACTION_WRAPPERS;
|
|
},
|
|
|
|
destructor: function() {
|
|
this.dirtyComponentsLength = null;
|
|
CallbackQueue.release(this.callbackQueue);
|
|
this.callbackQueue = null;
|
|
ReactUpdates.ReactReconcileTransaction.release(this.reconcileTransaction);
|
|
this.reconcileTransaction = null;
|
|
},
|
|
|
|
perform: function(method, scope, a) {
|
|
// Essentially calls `this.reconcileTransaction.perform(method, scope, a)`
|
|
// with this transaction's wrappers around it.
|
|
return Transaction.Mixin.perform.call(
|
|
this,
|
|
this.reconcileTransaction.perform,
|
|
this.reconcileTransaction,
|
|
method,
|
|
scope,
|
|
a
|
|
);
|
|
}
|
|
});
|
|
|
|
PooledClass.addPoolingTo(ReactUpdatesFlushTransaction);
|
|
|
|
function batchedUpdates(callback, a, b, c, d) {
|
|
ensureInjected();
|
|
batchingStrategy.batchedUpdates(callback, a, b, c, d);
|
|
}
|
|
|
|
/**
|
|
* Array comparator for ReactComponents by mount ordering.
|
|
*
|
|
* @param {ReactComponent} c1 first component you're comparing
|
|
* @param {ReactComponent} c2 second component you're comparing
|
|
* @return {number} Return value usable by Array.prototype.sort().
|
|
*/
|
|
function mountOrderComparator(c1, c2) {
|
|
return c1._mountOrder - c2._mountOrder;
|
|
}
|
|
|
|
function runBatchedUpdates(transaction) {
|
|
var len = transaction.dirtyComponentsLength;
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
len === dirtyComponents.length,
|
|
'Expected flush transaction\'s stored dirty-components length (%s) to ' +
|
|
'match dirty-components array length (%s).',
|
|
len,
|
|
dirtyComponents.length
|
|
) : invariant(len === dirtyComponents.length));
|
|
|
|
// Since reconciling a component higher in the owner hierarchy usually (not
|
|
// always -- see shouldComponentUpdate()) will reconcile children, reconcile
|
|
// them before their children by sorting the array.
|
|
dirtyComponents.sort(mountOrderComparator);
|
|
|
|
for (var i = 0; i < len; i++) {
|
|
// If a component is unmounted before pending changes apply, it will still
|
|
// be here, but we assume that it has cleared its _pendingCallbacks and
|
|
// that performUpdateIfNecessary is a noop.
|
|
var component = dirtyComponents[i];
|
|
|
|
// If performUpdateIfNecessary happens to enqueue any new updates, we
|
|
// shouldn't execute the callbacks until the next render happens, so
|
|
// stash the callbacks first
|
|
var callbacks = component._pendingCallbacks;
|
|
component._pendingCallbacks = null;
|
|
|
|
ReactReconciler.performUpdateIfNecessary(
|
|
component,
|
|
transaction.reconcileTransaction
|
|
);
|
|
|
|
if (callbacks) {
|
|
for (var j = 0; j < callbacks.length; j++) {
|
|
transaction.callbackQueue.enqueue(
|
|
callbacks[j],
|
|
component.getPublicInstance()
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var flushBatchedUpdates = function() {
|
|
// ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents
|
|
// array and perform any updates enqueued by mount-ready handlers (i.e.,
|
|
// componentDidUpdate) but we need to check here too in order to catch
|
|
// updates enqueued by setState callbacks and asap calls.
|
|
while (dirtyComponents.length || asapEnqueued) {
|
|
if (dirtyComponents.length) {
|
|
var transaction = ReactUpdatesFlushTransaction.getPooled();
|
|
transaction.perform(runBatchedUpdates, null, transaction);
|
|
ReactUpdatesFlushTransaction.release(transaction);
|
|
}
|
|
|
|
if (asapEnqueued) {
|
|
asapEnqueued = false;
|
|
var queue = asapCallbackQueue;
|
|
asapCallbackQueue = CallbackQueue.getPooled();
|
|
queue.notifyAll();
|
|
CallbackQueue.release(queue);
|
|
}
|
|
}
|
|
};
|
|
flushBatchedUpdates = ReactPerf.measure(
|
|
'ReactUpdates',
|
|
'flushBatchedUpdates',
|
|
flushBatchedUpdates
|
|
);
|
|
|
|
/**
|
|
* Mark a component as needing a rerender, adding an optional callback to a
|
|
* list of functions which will be executed once the rerender occurs.
|
|
*/
|
|
function enqueueUpdate(component) {
|
|
ensureInjected();
|
|
|
|
// Various parts of our code (such as ReactCompositeComponent's
|
|
// _renderValidatedComponent) assume that calls to render aren't nested;
|
|
// verify that that's the case. (This is called by each top-level update
|
|
// function, like setProps, setState, forceUpdate, etc.; creation and
|
|
// destruction of top-level components is guarded in ReactMount.)
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
ReactCurrentOwner.current == null,
|
|
'enqueueUpdate(): Render methods should be a pure function of props ' +
|
|
'and state; triggering nested component updates from render is not ' +
|
|
'allowed. If necessary, trigger nested updates in ' +
|
|
'componentDidUpdate.'
|
|
) : null);
|
|
|
|
if (!batchingStrategy.isBatchingUpdates) {
|
|
batchingStrategy.batchedUpdates(enqueueUpdate, component);
|
|
return;
|
|
}
|
|
|
|
dirtyComponents.push(component);
|
|
}
|
|
|
|
/**
|
|
* Enqueue a callback to be run at the end of the current batching cycle. Throws
|
|
* if no updates are currently being performed.
|
|
*/
|
|
function asap(callback, context) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
batchingStrategy.isBatchingUpdates,
|
|
'ReactUpdates.asap: Can\'t enqueue an asap callback in a context where' +
|
|
'updates are not being batched.'
|
|
) : invariant(batchingStrategy.isBatchingUpdates));
|
|
asapCallbackQueue.enqueue(callback, context);
|
|
asapEnqueued = true;
|
|
}
|
|
|
|
var ReactUpdatesInjection = {
|
|
injectReconcileTransaction: function(ReconcileTransaction) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
ReconcileTransaction,
|
|
'ReactUpdates: must provide a reconcile transaction class'
|
|
) : invariant(ReconcileTransaction));
|
|
ReactUpdates.ReactReconcileTransaction = ReconcileTransaction;
|
|
},
|
|
|
|
injectBatchingStrategy: function(_batchingStrategy) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
_batchingStrategy,
|
|
'ReactUpdates: must provide a batching strategy'
|
|
) : invariant(_batchingStrategy));
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
typeof _batchingStrategy.batchedUpdates === 'function',
|
|
'ReactUpdates: must provide a batchedUpdates() function'
|
|
) : invariant(typeof _batchingStrategy.batchedUpdates === 'function'));
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
typeof _batchingStrategy.isBatchingUpdates === 'boolean',
|
|
'ReactUpdates: must provide an isBatchingUpdates boolean attribute'
|
|
) : invariant(typeof _batchingStrategy.isBatchingUpdates === 'boolean'));
|
|
batchingStrategy = _batchingStrategy;
|
|
}
|
|
};
|
|
|
|
var ReactUpdates = {
|
|
/**
|
|
* React references `ReactReconcileTransaction` using this property in order
|
|
* to allow dependency injection.
|
|
*
|
|
* @internal
|
|
*/
|
|
ReactReconcileTransaction: null,
|
|
|
|
batchedUpdates: batchedUpdates,
|
|
enqueueUpdate: enqueueUpdate,
|
|
flushBatchedUpdates: flushBatchedUpdates,
|
|
injection: ReactUpdatesInjection,
|
|
asap: asap
|
|
};
|
|
|
|
module.exports = ReactUpdates;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./CallbackQueue":55,"./Object.assign":76,"./PooledClass":77,"./ReactCurrentOwner":89,"./ReactPerf":125,"./ReactReconciler":131,"./Transaction":153,"./invariant":185,"./warning":204,"_process":1}],138:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule SVGDOMPropertyConfig
|
|
*/
|
|
|
|
/*jslint bitwise: true*/
|
|
|
|
'use strict';
|
|
|
|
var DOMProperty = require("./DOMProperty");
|
|
|
|
var MUST_USE_ATTRIBUTE = DOMProperty.injection.MUST_USE_ATTRIBUTE;
|
|
|
|
var SVGDOMPropertyConfig = {
|
|
Properties: {
|
|
clipPath: MUST_USE_ATTRIBUTE,
|
|
cx: MUST_USE_ATTRIBUTE,
|
|
cy: MUST_USE_ATTRIBUTE,
|
|
d: MUST_USE_ATTRIBUTE,
|
|
dx: MUST_USE_ATTRIBUTE,
|
|
dy: MUST_USE_ATTRIBUTE,
|
|
fill: MUST_USE_ATTRIBUTE,
|
|
fillOpacity: MUST_USE_ATTRIBUTE,
|
|
fontFamily: MUST_USE_ATTRIBUTE,
|
|
fontSize: MUST_USE_ATTRIBUTE,
|
|
fx: MUST_USE_ATTRIBUTE,
|
|
fy: MUST_USE_ATTRIBUTE,
|
|
gradientTransform: MUST_USE_ATTRIBUTE,
|
|
gradientUnits: MUST_USE_ATTRIBUTE,
|
|
markerEnd: MUST_USE_ATTRIBUTE,
|
|
markerMid: MUST_USE_ATTRIBUTE,
|
|
markerStart: MUST_USE_ATTRIBUTE,
|
|
offset: MUST_USE_ATTRIBUTE,
|
|
opacity: MUST_USE_ATTRIBUTE,
|
|
patternContentUnits: MUST_USE_ATTRIBUTE,
|
|
patternUnits: MUST_USE_ATTRIBUTE,
|
|
points: MUST_USE_ATTRIBUTE,
|
|
preserveAspectRatio: MUST_USE_ATTRIBUTE,
|
|
r: MUST_USE_ATTRIBUTE,
|
|
rx: MUST_USE_ATTRIBUTE,
|
|
ry: MUST_USE_ATTRIBUTE,
|
|
spreadMethod: MUST_USE_ATTRIBUTE,
|
|
stopColor: MUST_USE_ATTRIBUTE,
|
|
stopOpacity: MUST_USE_ATTRIBUTE,
|
|
stroke: MUST_USE_ATTRIBUTE,
|
|
strokeDasharray: MUST_USE_ATTRIBUTE,
|
|
strokeLinecap: MUST_USE_ATTRIBUTE,
|
|
strokeOpacity: MUST_USE_ATTRIBUTE,
|
|
strokeWidth: MUST_USE_ATTRIBUTE,
|
|
textAnchor: MUST_USE_ATTRIBUTE,
|
|
transform: MUST_USE_ATTRIBUTE,
|
|
version: MUST_USE_ATTRIBUTE,
|
|
viewBox: MUST_USE_ATTRIBUTE,
|
|
x1: MUST_USE_ATTRIBUTE,
|
|
x2: MUST_USE_ATTRIBUTE,
|
|
x: MUST_USE_ATTRIBUTE,
|
|
y1: MUST_USE_ATTRIBUTE,
|
|
y2: MUST_USE_ATTRIBUTE,
|
|
y: MUST_USE_ATTRIBUTE
|
|
},
|
|
DOMAttributeNames: {
|
|
clipPath: 'clip-path',
|
|
fillOpacity: 'fill-opacity',
|
|
fontFamily: 'font-family',
|
|
fontSize: 'font-size',
|
|
gradientTransform: 'gradientTransform',
|
|
gradientUnits: 'gradientUnits',
|
|
markerEnd: 'marker-end',
|
|
markerMid: 'marker-mid',
|
|
markerStart: 'marker-start',
|
|
patternContentUnits: 'patternContentUnits',
|
|
patternUnits: 'patternUnits',
|
|
preserveAspectRatio: 'preserveAspectRatio',
|
|
spreadMethod: 'spreadMethod',
|
|
stopColor: 'stop-color',
|
|
stopOpacity: 'stop-opacity',
|
|
strokeDasharray: 'stroke-dasharray',
|
|
strokeLinecap: 'stroke-linecap',
|
|
strokeOpacity: 'stroke-opacity',
|
|
strokeWidth: 'stroke-width',
|
|
textAnchor: 'text-anchor',
|
|
viewBox: 'viewBox'
|
|
}
|
|
};
|
|
|
|
module.exports = SVGDOMPropertyConfig;
|
|
|
|
},{"./DOMProperty":59}],139:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule SelectEventPlugin
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var EventConstants = require("./EventConstants");
|
|
var EventPropagators = require("./EventPropagators");
|
|
var ReactInputSelection = require("./ReactInputSelection");
|
|
var SyntheticEvent = require("./SyntheticEvent");
|
|
|
|
var getActiveElement = require("./getActiveElement");
|
|
var isTextInputElement = require("./isTextInputElement");
|
|
var keyOf = require("./keyOf");
|
|
var shallowEqual = require("./shallowEqual");
|
|
|
|
var topLevelTypes = EventConstants.topLevelTypes;
|
|
|
|
var eventTypes = {
|
|
select: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onSelect: null}),
|
|
captured: keyOf({onSelectCapture: null})
|
|
},
|
|
dependencies: [
|
|
topLevelTypes.topBlur,
|
|
topLevelTypes.topContextMenu,
|
|
topLevelTypes.topFocus,
|
|
topLevelTypes.topKeyDown,
|
|
topLevelTypes.topMouseDown,
|
|
topLevelTypes.topMouseUp,
|
|
topLevelTypes.topSelectionChange
|
|
]
|
|
}
|
|
};
|
|
|
|
var activeElement = null;
|
|
var activeElementID = null;
|
|
var lastSelection = null;
|
|
var mouseDown = false;
|
|
|
|
/**
|
|
* Get an object which is a unique representation of the current selection.
|
|
*
|
|
* The return value will not be consistent across nodes or browsers, but
|
|
* two identical selections on the same node will return identical objects.
|
|
*
|
|
* @param {DOMElement} node
|
|
* @param {object}
|
|
*/
|
|
function getSelection(node) {
|
|
if ('selectionStart' in node &&
|
|
ReactInputSelection.hasSelectionCapabilities(node)) {
|
|
return {
|
|
start: node.selectionStart,
|
|
end: node.selectionEnd
|
|
};
|
|
} else if (window.getSelection) {
|
|
var selection = window.getSelection();
|
|
return {
|
|
anchorNode: selection.anchorNode,
|
|
anchorOffset: selection.anchorOffset,
|
|
focusNode: selection.focusNode,
|
|
focusOffset: selection.focusOffset
|
|
};
|
|
} else if (document.selection) {
|
|
var range = document.selection.createRange();
|
|
return {
|
|
parentElement: range.parentElement(),
|
|
text: range.text,
|
|
top: range.boundingTop,
|
|
left: range.boundingLeft
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Poll selection to see whether it's changed.
|
|
*
|
|
* @param {object} nativeEvent
|
|
* @return {?SyntheticEvent}
|
|
*/
|
|
function constructSelectEvent(nativeEvent) {
|
|
// Ensure we have the right element, and that the user is not dragging a
|
|
// selection (this matches native `select` event behavior). In HTML5, select
|
|
// fires only on input and textarea thus if there's no focused element we
|
|
// won't dispatch.
|
|
if (mouseDown ||
|
|
activeElement == null ||
|
|
activeElement !== getActiveElement()) {
|
|
return null;
|
|
}
|
|
|
|
// Only fire when selection has actually changed.
|
|
var currentSelection = getSelection(activeElement);
|
|
if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
|
|
lastSelection = currentSelection;
|
|
|
|
var syntheticEvent = SyntheticEvent.getPooled(
|
|
eventTypes.select,
|
|
activeElementID,
|
|
nativeEvent
|
|
);
|
|
|
|
syntheticEvent.type = 'select';
|
|
syntheticEvent.target = activeElement;
|
|
|
|
EventPropagators.accumulateTwoPhaseDispatches(syntheticEvent);
|
|
|
|
return syntheticEvent;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This plugin creates an `onSelect` event that normalizes select events
|
|
* across form elements.
|
|
*
|
|
* Supported elements are:
|
|
* - input (see `isTextInputElement`)
|
|
* - textarea
|
|
* - contentEditable
|
|
*
|
|
* This differs from native browser implementations in the following ways:
|
|
* - Fires on contentEditable fields as well as inputs.
|
|
* - Fires for collapsed selection.
|
|
* - Fires after user input.
|
|
*/
|
|
var SelectEventPlugin = {
|
|
|
|
eventTypes: eventTypes,
|
|
|
|
/**
|
|
* @param {string} topLevelType Record from `EventConstants`.
|
|
* @param {DOMEventTarget} topLevelTarget The listening component root node.
|
|
* @param {string} topLevelTargetID ID of `topLevelTarget`.
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @return {*} An accumulation of synthetic events.
|
|
* @see {EventPluginHub.extractEvents}
|
|
*/
|
|
extractEvents: function(
|
|
topLevelType,
|
|
topLevelTarget,
|
|
topLevelTargetID,
|
|
nativeEvent) {
|
|
|
|
switch (topLevelType) {
|
|
// Track the input node that has focus.
|
|
case topLevelTypes.topFocus:
|
|
if (isTextInputElement(topLevelTarget) ||
|
|
topLevelTarget.contentEditable === 'true') {
|
|
activeElement = topLevelTarget;
|
|
activeElementID = topLevelTargetID;
|
|
lastSelection = null;
|
|
}
|
|
break;
|
|
case topLevelTypes.topBlur:
|
|
activeElement = null;
|
|
activeElementID = null;
|
|
lastSelection = null;
|
|
break;
|
|
|
|
// Don't fire the event while the user is dragging. This matches the
|
|
// semantics of the native select event.
|
|
case topLevelTypes.topMouseDown:
|
|
mouseDown = true;
|
|
break;
|
|
case topLevelTypes.topContextMenu:
|
|
case topLevelTypes.topMouseUp:
|
|
mouseDown = false;
|
|
return constructSelectEvent(nativeEvent);
|
|
|
|
// Chrome and IE fire non-standard event when selection is changed (and
|
|
// sometimes when it hasn't).
|
|
// Firefox doesn't support selectionchange, so check selection status
|
|
// after each key entry. The selection changes after keydown and before
|
|
// keyup, but we check on keydown as well in the case of holding down a
|
|
// key, when multiple keydown events are fired but only one keyup is.
|
|
case topLevelTypes.topSelectionChange:
|
|
case topLevelTypes.topKeyDown:
|
|
case topLevelTypes.topKeyUp:
|
|
return constructSelectEvent(nativeEvent);
|
|
}
|
|
}
|
|
};
|
|
|
|
module.exports = SelectEventPlugin;
|
|
|
|
},{"./EventConstants":64,"./EventPropagators":69,"./ReactInputSelection":115,"./SyntheticEvent":145,"./getActiveElement":171,"./isTextInputElement":188,"./keyOf":191,"./shallowEqual":200}],140:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ServerReactRootIndex
|
|
* @typechecks
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* Size of the reactRoot ID space. We generate random numbers for React root
|
|
* IDs and if there's a collision the events and DOM update system will
|
|
* get confused. In the future we need a way to generate GUIDs but for
|
|
* now this will work on a smaller scale.
|
|
*/
|
|
var GLOBAL_MOUNT_POINT_MAX = Math.pow(2, 53);
|
|
|
|
var ServerReactRootIndex = {
|
|
createReactRootIndex: function() {
|
|
return Math.ceil(Math.random() * GLOBAL_MOUNT_POINT_MAX);
|
|
}
|
|
};
|
|
|
|
module.exports = ServerReactRootIndex;
|
|
|
|
},{}],141:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule SimpleEventPlugin
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var EventConstants = require("./EventConstants");
|
|
var EventPluginUtils = require("./EventPluginUtils");
|
|
var EventPropagators = require("./EventPropagators");
|
|
var SyntheticClipboardEvent = require("./SyntheticClipboardEvent");
|
|
var SyntheticEvent = require("./SyntheticEvent");
|
|
var SyntheticFocusEvent = require("./SyntheticFocusEvent");
|
|
var SyntheticKeyboardEvent = require("./SyntheticKeyboardEvent");
|
|
var SyntheticMouseEvent = require("./SyntheticMouseEvent");
|
|
var SyntheticDragEvent = require("./SyntheticDragEvent");
|
|
var SyntheticTouchEvent = require("./SyntheticTouchEvent");
|
|
var SyntheticUIEvent = require("./SyntheticUIEvent");
|
|
var SyntheticWheelEvent = require("./SyntheticWheelEvent");
|
|
|
|
var getEventCharCode = require("./getEventCharCode");
|
|
|
|
var invariant = require("./invariant");
|
|
var keyOf = require("./keyOf");
|
|
var warning = require("./warning");
|
|
|
|
var topLevelTypes = EventConstants.topLevelTypes;
|
|
|
|
var eventTypes = {
|
|
blur: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onBlur: true}),
|
|
captured: keyOf({onBlurCapture: true})
|
|
}
|
|
},
|
|
click: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onClick: true}),
|
|
captured: keyOf({onClickCapture: true})
|
|
}
|
|
},
|
|
contextMenu: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onContextMenu: true}),
|
|
captured: keyOf({onContextMenuCapture: true})
|
|
}
|
|
},
|
|
copy: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onCopy: true}),
|
|
captured: keyOf({onCopyCapture: true})
|
|
}
|
|
},
|
|
cut: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onCut: true}),
|
|
captured: keyOf({onCutCapture: true})
|
|
}
|
|
},
|
|
doubleClick: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onDoubleClick: true}),
|
|
captured: keyOf({onDoubleClickCapture: true})
|
|
}
|
|
},
|
|
drag: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onDrag: true}),
|
|
captured: keyOf({onDragCapture: true})
|
|
}
|
|
},
|
|
dragEnd: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onDragEnd: true}),
|
|
captured: keyOf({onDragEndCapture: true})
|
|
}
|
|
},
|
|
dragEnter: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onDragEnter: true}),
|
|
captured: keyOf({onDragEnterCapture: true})
|
|
}
|
|
},
|
|
dragExit: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onDragExit: true}),
|
|
captured: keyOf({onDragExitCapture: true})
|
|
}
|
|
},
|
|
dragLeave: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onDragLeave: true}),
|
|
captured: keyOf({onDragLeaveCapture: true})
|
|
}
|
|
},
|
|
dragOver: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onDragOver: true}),
|
|
captured: keyOf({onDragOverCapture: true})
|
|
}
|
|
},
|
|
dragStart: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onDragStart: true}),
|
|
captured: keyOf({onDragStartCapture: true})
|
|
}
|
|
},
|
|
drop: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onDrop: true}),
|
|
captured: keyOf({onDropCapture: true})
|
|
}
|
|
},
|
|
focus: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onFocus: true}),
|
|
captured: keyOf({onFocusCapture: true})
|
|
}
|
|
},
|
|
input: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onInput: true}),
|
|
captured: keyOf({onInputCapture: true})
|
|
}
|
|
},
|
|
keyDown: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onKeyDown: true}),
|
|
captured: keyOf({onKeyDownCapture: true})
|
|
}
|
|
},
|
|
keyPress: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onKeyPress: true}),
|
|
captured: keyOf({onKeyPressCapture: true})
|
|
}
|
|
},
|
|
keyUp: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onKeyUp: true}),
|
|
captured: keyOf({onKeyUpCapture: true})
|
|
}
|
|
},
|
|
load: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onLoad: true}),
|
|
captured: keyOf({onLoadCapture: true})
|
|
}
|
|
},
|
|
error: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onError: true}),
|
|
captured: keyOf({onErrorCapture: true})
|
|
}
|
|
},
|
|
// Note: We do not allow listening to mouseOver events. Instead, use the
|
|
// onMouseEnter/onMouseLeave created by `EnterLeaveEventPlugin`.
|
|
mouseDown: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onMouseDown: true}),
|
|
captured: keyOf({onMouseDownCapture: true})
|
|
}
|
|
},
|
|
mouseMove: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onMouseMove: true}),
|
|
captured: keyOf({onMouseMoveCapture: true})
|
|
}
|
|
},
|
|
mouseOut: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onMouseOut: true}),
|
|
captured: keyOf({onMouseOutCapture: true})
|
|
}
|
|
},
|
|
mouseOver: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onMouseOver: true}),
|
|
captured: keyOf({onMouseOverCapture: true})
|
|
}
|
|
},
|
|
mouseUp: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onMouseUp: true}),
|
|
captured: keyOf({onMouseUpCapture: true})
|
|
}
|
|
},
|
|
paste: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onPaste: true}),
|
|
captured: keyOf({onPasteCapture: true})
|
|
}
|
|
},
|
|
reset: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onReset: true}),
|
|
captured: keyOf({onResetCapture: true})
|
|
}
|
|
},
|
|
scroll: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onScroll: true}),
|
|
captured: keyOf({onScrollCapture: true})
|
|
}
|
|
},
|
|
submit: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onSubmit: true}),
|
|
captured: keyOf({onSubmitCapture: true})
|
|
}
|
|
},
|
|
touchCancel: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onTouchCancel: true}),
|
|
captured: keyOf({onTouchCancelCapture: true})
|
|
}
|
|
},
|
|
touchEnd: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onTouchEnd: true}),
|
|
captured: keyOf({onTouchEndCapture: true})
|
|
}
|
|
},
|
|
touchMove: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onTouchMove: true}),
|
|
captured: keyOf({onTouchMoveCapture: true})
|
|
}
|
|
},
|
|
touchStart: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onTouchStart: true}),
|
|
captured: keyOf({onTouchStartCapture: true})
|
|
}
|
|
},
|
|
wheel: {
|
|
phasedRegistrationNames: {
|
|
bubbled: keyOf({onWheel: true}),
|
|
captured: keyOf({onWheelCapture: true})
|
|
}
|
|
}
|
|
};
|
|
|
|
var topLevelEventsToDispatchConfig = {
|
|
topBlur: eventTypes.blur,
|
|
topClick: eventTypes.click,
|
|
topContextMenu: eventTypes.contextMenu,
|
|
topCopy: eventTypes.copy,
|
|
topCut: eventTypes.cut,
|
|
topDoubleClick: eventTypes.doubleClick,
|
|
topDrag: eventTypes.drag,
|
|
topDragEnd: eventTypes.dragEnd,
|
|
topDragEnter: eventTypes.dragEnter,
|
|
topDragExit: eventTypes.dragExit,
|
|
topDragLeave: eventTypes.dragLeave,
|
|
topDragOver: eventTypes.dragOver,
|
|
topDragStart: eventTypes.dragStart,
|
|
topDrop: eventTypes.drop,
|
|
topError: eventTypes.error,
|
|
topFocus: eventTypes.focus,
|
|
topInput: eventTypes.input,
|
|
topKeyDown: eventTypes.keyDown,
|
|
topKeyPress: eventTypes.keyPress,
|
|
topKeyUp: eventTypes.keyUp,
|
|
topLoad: eventTypes.load,
|
|
topMouseDown: eventTypes.mouseDown,
|
|
topMouseMove: eventTypes.mouseMove,
|
|
topMouseOut: eventTypes.mouseOut,
|
|
topMouseOver: eventTypes.mouseOver,
|
|
topMouseUp: eventTypes.mouseUp,
|
|
topPaste: eventTypes.paste,
|
|
topReset: eventTypes.reset,
|
|
topScroll: eventTypes.scroll,
|
|
topSubmit: eventTypes.submit,
|
|
topTouchCancel: eventTypes.touchCancel,
|
|
topTouchEnd: eventTypes.touchEnd,
|
|
topTouchMove: eventTypes.touchMove,
|
|
topTouchStart: eventTypes.touchStart,
|
|
topWheel: eventTypes.wheel
|
|
};
|
|
|
|
for (var type in topLevelEventsToDispatchConfig) {
|
|
topLevelEventsToDispatchConfig[type].dependencies = [type];
|
|
}
|
|
|
|
var SimpleEventPlugin = {
|
|
|
|
eventTypes: eventTypes,
|
|
|
|
/**
|
|
* Same as the default implementation, except cancels the event when return
|
|
* value is false. This behavior will be disabled in a future release.
|
|
*
|
|
* @param {object} Event to be dispatched.
|
|
* @param {function} Application-level callback.
|
|
* @param {string} domID DOM ID to pass to the callback.
|
|
*/
|
|
executeDispatch: function(event, listener, domID) {
|
|
var returnValue = EventPluginUtils.executeDispatch(event, listener, domID);
|
|
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
typeof returnValue !== 'boolean',
|
|
'Returning `false` from an event handler is deprecated and will be ' +
|
|
'ignored in a future release. Instead, manually call ' +
|
|
'e.stopPropagation() or e.preventDefault(), as appropriate.'
|
|
) : null);
|
|
|
|
if (returnValue === false) {
|
|
event.stopPropagation();
|
|
event.preventDefault();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @param {string} topLevelType Record from `EventConstants`.
|
|
* @param {DOMEventTarget} topLevelTarget The listening component root node.
|
|
* @param {string} topLevelTargetID ID of `topLevelTarget`.
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @return {*} An accumulation of synthetic events.
|
|
* @see {EventPluginHub.extractEvents}
|
|
*/
|
|
extractEvents: function(
|
|
topLevelType,
|
|
topLevelTarget,
|
|
topLevelTargetID,
|
|
nativeEvent) {
|
|
var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
|
|
if (!dispatchConfig) {
|
|
return null;
|
|
}
|
|
var EventConstructor;
|
|
switch (topLevelType) {
|
|
case topLevelTypes.topInput:
|
|
case topLevelTypes.topLoad:
|
|
case topLevelTypes.topError:
|
|
case topLevelTypes.topReset:
|
|
case topLevelTypes.topSubmit:
|
|
// HTML Events
|
|
// @see http://www.w3.org/TR/html5/index.html#events-0
|
|
EventConstructor = SyntheticEvent;
|
|
break;
|
|
case topLevelTypes.topKeyPress:
|
|
// FireFox creates a keypress event for function keys too. This removes
|
|
// the unwanted keypress events. Enter is however both printable and
|
|
// non-printable. One would expect Tab to be as well (but it isn't).
|
|
if (getEventCharCode(nativeEvent) === 0) {
|
|
return null;
|
|
}
|
|
/* falls through */
|
|
case topLevelTypes.topKeyDown:
|
|
case topLevelTypes.topKeyUp:
|
|
EventConstructor = SyntheticKeyboardEvent;
|
|
break;
|
|
case topLevelTypes.topBlur:
|
|
case topLevelTypes.topFocus:
|
|
EventConstructor = SyntheticFocusEvent;
|
|
break;
|
|
case topLevelTypes.topClick:
|
|
// Firefox creates a click event on right mouse clicks. This removes the
|
|
// unwanted click events.
|
|
if (nativeEvent.button === 2) {
|
|
return null;
|
|
}
|
|
/* falls through */
|
|
case topLevelTypes.topContextMenu:
|
|
case topLevelTypes.topDoubleClick:
|
|
case topLevelTypes.topMouseDown:
|
|
case topLevelTypes.topMouseMove:
|
|
case topLevelTypes.topMouseOut:
|
|
case topLevelTypes.topMouseOver:
|
|
case topLevelTypes.topMouseUp:
|
|
EventConstructor = SyntheticMouseEvent;
|
|
break;
|
|
case topLevelTypes.topDrag:
|
|
case topLevelTypes.topDragEnd:
|
|
case topLevelTypes.topDragEnter:
|
|
case topLevelTypes.topDragExit:
|
|
case topLevelTypes.topDragLeave:
|
|
case topLevelTypes.topDragOver:
|
|
case topLevelTypes.topDragStart:
|
|
case topLevelTypes.topDrop:
|
|
EventConstructor = SyntheticDragEvent;
|
|
break;
|
|
case topLevelTypes.topTouchCancel:
|
|
case topLevelTypes.topTouchEnd:
|
|
case topLevelTypes.topTouchMove:
|
|
case topLevelTypes.topTouchStart:
|
|
EventConstructor = SyntheticTouchEvent;
|
|
break;
|
|
case topLevelTypes.topScroll:
|
|
EventConstructor = SyntheticUIEvent;
|
|
break;
|
|
case topLevelTypes.topWheel:
|
|
EventConstructor = SyntheticWheelEvent;
|
|
break;
|
|
case topLevelTypes.topCopy:
|
|
case topLevelTypes.topCut:
|
|
case topLevelTypes.topPaste:
|
|
EventConstructor = SyntheticClipboardEvent;
|
|
break;
|
|
}
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
EventConstructor,
|
|
'SimpleEventPlugin: Unhandled event type, `%s`.',
|
|
topLevelType
|
|
) : invariant(EventConstructor));
|
|
var event = EventConstructor.getPooled(
|
|
dispatchConfig,
|
|
topLevelTargetID,
|
|
nativeEvent
|
|
);
|
|
EventPropagators.accumulateTwoPhaseDispatches(event);
|
|
return event;
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = SimpleEventPlugin;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./EventConstants":64,"./EventPluginUtils":68,"./EventPropagators":69,"./SyntheticClipboardEvent":142,"./SyntheticDragEvent":144,"./SyntheticEvent":145,"./SyntheticFocusEvent":146,"./SyntheticKeyboardEvent":148,"./SyntheticMouseEvent":149,"./SyntheticTouchEvent":150,"./SyntheticUIEvent":151,"./SyntheticWheelEvent":152,"./getEventCharCode":172,"./invariant":185,"./keyOf":191,"./warning":204,"_process":1}],142:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule SyntheticClipboardEvent
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var SyntheticEvent = require("./SyntheticEvent");
|
|
|
|
/**
|
|
* @interface Event
|
|
* @see http://www.w3.org/TR/clipboard-apis/
|
|
*/
|
|
var ClipboardEventInterface = {
|
|
clipboardData: function(event) {
|
|
return (
|
|
'clipboardData' in event ?
|
|
event.clipboardData :
|
|
window.clipboardData
|
|
);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @param {object} dispatchConfig Configuration used to dispatch this event.
|
|
* @param {string} dispatchMarker Marker identifying the event target.
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @extends {SyntheticUIEvent}
|
|
*/
|
|
function SyntheticClipboardEvent(dispatchConfig, dispatchMarker, nativeEvent) {
|
|
SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
|
|
}
|
|
|
|
SyntheticEvent.augmentClass(SyntheticClipboardEvent, ClipboardEventInterface);
|
|
|
|
module.exports = SyntheticClipboardEvent;
|
|
|
|
},{"./SyntheticEvent":145}],143:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule SyntheticCompositionEvent
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var SyntheticEvent = require("./SyntheticEvent");
|
|
|
|
/**
|
|
* @interface Event
|
|
* @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
|
|
*/
|
|
var CompositionEventInterface = {
|
|
data: null
|
|
};
|
|
|
|
/**
|
|
* @param {object} dispatchConfig Configuration used to dispatch this event.
|
|
* @param {string} dispatchMarker Marker identifying the event target.
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @extends {SyntheticUIEvent}
|
|
*/
|
|
function SyntheticCompositionEvent(
|
|
dispatchConfig,
|
|
dispatchMarker,
|
|
nativeEvent) {
|
|
SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
|
|
}
|
|
|
|
SyntheticEvent.augmentClass(
|
|
SyntheticCompositionEvent,
|
|
CompositionEventInterface
|
|
);
|
|
|
|
module.exports = SyntheticCompositionEvent;
|
|
|
|
},{"./SyntheticEvent":145}],144:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule SyntheticDragEvent
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var SyntheticMouseEvent = require("./SyntheticMouseEvent");
|
|
|
|
/**
|
|
* @interface DragEvent
|
|
* @see http://www.w3.org/TR/DOM-Level-3-Events/
|
|
*/
|
|
var DragEventInterface = {
|
|
dataTransfer: null
|
|
};
|
|
|
|
/**
|
|
* @param {object} dispatchConfig Configuration used to dispatch this event.
|
|
* @param {string} dispatchMarker Marker identifying the event target.
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @extends {SyntheticUIEvent}
|
|
*/
|
|
function SyntheticDragEvent(dispatchConfig, dispatchMarker, nativeEvent) {
|
|
SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
|
|
}
|
|
|
|
SyntheticMouseEvent.augmentClass(SyntheticDragEvent, DragEventInterface);
|
|
|
|
module.exports = SyntheticDragEvent;
|
|
|
|
},{"./SyntheticMouseEvent":149}],145:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule SyntheticEvent
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var PooledClass = require("./PooledClass");
|
|
|
|
var assign = require("./Object.assign");
|
|
var emptyFunction = require("./emptyFunction");
|
|
var getEventTarget = require("./getEventTarget");
|
|
|
|
/**
|
|
* @interface Event
|
|
* @see http://www.w3.org/TR/DOM-Level-3-Events/
|
|
*/
|
|
var EventInterface = {
|
|
type: null,
|
|
target: getEventTarget,
|
|
// currentTarget is set when dispatching; no use in copying it here
|
|
currentTarget: emptyFunction.thatReturnsNull,
|
|
eventPhase: null,
|
|
bubbles: null,
|
|
cancelable: null,
|
|
timeStamp: function(event) {
|
|
return event.timeStamp || Date.now();
|
|
},
|
|
defaultPrevented: null,
|
|
isTrusted: null
|
|
};
|
|
|
|
/**
|
|
* Synthetic events are dispatched by event plugins, typically in response to a
|
|
* top-level event delegation handler.
|
|
*
|
|
* These systems should generally use pooling to reduce the frequency of garbage
|
|
* collection. The system should check `isPersistent` to determine whether the
|
|
* event should be released into the pool after being dispatched. Users that
|
|
* need a persisted event should invoke `persist`.
|
|
*
|
|
* Synthetic events (and subclasses) implement the DOM Level 3 Events API by
|
|
* normalizing browser quirks. Subclasses do not necessarily have to implement a
|
|
* DOM interface; custom application-specific events can also subclass this.
|
|
*
|
|
* @param {object} dispatchConfig Configuration used to dispatch this event.
|
|
* @param {string} dispatchMarker Marker identifying the event target.
|
|
* @param {object} nativeEvent Native browser event.
|
|
*/
|
|
function SyntheticEvent(dispatchConfig, dispatchMarker, nativeEvent) {
|
|
this.dispatchConfig = dispatchConfig;
|
|
this.dispatchMarker = dispatchMarker;
|
|
this.nativeEvent = nativeEvent;
|
|
|
|
var Interface = this.constructor.Interface;
|
|
for (var propName in Interface) {
|
|
if (!Interface.hasOwnProperty(propName)) {
|
|
continue;
|
|
}
|
|
var normalize = Interface[propName];
|
|
if (normalize) {
|
|
this[propName] = normalize(nativeEvent);
|
|
} else {
|
|
this[propName] = nativeEvent[propName];
|
|
}
|
|
}
|
|
|
|
var defaultPrevented = nativeEvent.defaultPrevented != null ?
|
|
nativeEvent.defaultPrevented :
|
|
nativeEvent.returnValue === false;
|
|
if (defaultPrevented) {
|
|
this.isDefaultPrevented = emptyFunction.thatReturnsTrue;
|
|
} else {
|
|
this.isDefaultPrevented = emptyFunction.thatReturnsFalse;
|
|
}
|
|
this.isPropagationStopped = emptyFunction.thatReturnsFalse;
|
|
}
|
|
|
|
assign(SyntheticEvent.prototype, {
|
|
|
|
preventDefault: function() {
|
|
this.defaultPrevented = true;
|
|
var event = this.nativeEvent;
|
|
if (event.preventDefault) {
|
|
event.preventDefault();
|
|
} else {
|
|
event.returnValue = false;
|
|
}
|
|
this.isDefaultPrevented = emptyFunction.thatReturnsTrue;
|
|
},
|
|
|
|
stopPropagation: function() {
|
|
var event = this.nativeEvent;
|
|
if (event.stopPropagation) {
|
|
event.stopPropagation();
|
|
} else {
|
|
event.cancelBubble = true;
|
|
}
|
|
this.isPropagationStopped = emptyFunction.thatReturnsTrue;
|
|
},
|
|
|
|
/**
|
|
* We release all dispatched `SyntheticEvent`s after each event loop, adding
|
|
* them back into the pool. This allows a way to hold onto a reference that
|
|
* won't be added back into the pool.
|
|
*/
|
|
persist: function() {
|
|
this.isPersistent = emptyFunction.thatReturnsTrue;
|
|
},
|
|
|
|
/**
|
|
* Checks if this event should be released back into the pool.
|
|
*
|
|
* @return {boolean} True if this should not be released, false otherwise.
|
|
*/
|
|
isPersistent: emptyFunction.thatReturnsFalse,
|
|
|
|
/**
|
|
* `PooledClass` looks for `destructor` on each instance it releases.
|
|
*/
|
|
destructor: function() {
|
|
var Interface = this.constructor.Interface;
|
|
for (var propName in Interface) {
|
|
this[propName] = null;
|
|
}
|
|
this.dispatchConfig = null;
|
|
this.dispatchMarker = null;
|
|
this.nativeEvent = null;
|
|
}
|
|
|
|
});
|
|
|
|
SyntheticEvent.Interface = EventInterface;
|
|
|
|
/**
|
|
* Helper to reduce boilerplate when creating subclasses.
|
|
*
|
|
* @param {function} Class
|
|
* @param {?object} Interface
|
|
*/
|
|
SyntheticEvent.augmentClass = function(Class, Interface) {
|
|
var Super = this;
|
|
|
|
var prototype = Object.create(Super.prototype);
|
|
assign(prototype, Class.prototype);
|
|
Class.prototype = prototype;
|
|
Class.prototype.constructor = Class;
|
|
|
|
Class.Interface = assign({}, Super.Interface, Interface);
|
|
Class.augmentClass = Super.augmentClass;
|
|
|
|
PooledClass.addPoolingTo(Class, PooledClass.threeArgumentPooler);
|
|
};
|
|
|
|
PooledClass.addPoolingTo(SyntheticEvent, PooledClass.threeArgumentPooler);
|
|
|
|
module.exports = SyntheticEvent;
|
|
|
|
},{"./Object.assign":76,"./PooledClass":77,"./emptyFunction":164,"./getEventTarget":175}],146:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule SyntheticFocusEvent
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var SyntheticUIEvent = require("./SyntheticUIEvent");
|
|
|
|
/**
|
|
* @interface FocusEvent
|
|
* @see http://www.w3.org/TR/DOM-Level-3-Events/
|
|
*/
|
|
var FocusEventInterface = {
|
|
relatedTarget: null
|
|
};
|
|
|
|
/**
|
|
* @param {object} dispatchConfig Configuration used to dispatch this event.
|
|
* @param {string} dispatchMarker Marker identifying the event target.
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @extends {SyntheticUIEvent}
|
|
*/
|
|
function SyntheticFocusEvent(dispatchConfig, dispatchMarker, nativeEvent) {
|
|
SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
|
|
}
|
|
|
|
SyntheticUIEvent.augmentClass(SyntheticFocusEvent, FocusEventInterface);
|
|
|
|
module.exports = SyntheticFocusEvent;
|
|
|
|
},{"./SyntheticUIEvent":151}],147:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule SyntheticInputEvent
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var SyntheticEvent = require("./SyntheticEvent");
|
|
|
|
/**
|
|
* @interface Event
|
|
* @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
|
|
* /#events-inputevents
|
|
*/
|
|
var InputEventInterface = {
|
|
data: null
|
|
};
|
|
|
|
/**
|
|
* @param {object} dispatchConfig Configuration used to dispatch this event.
|
|
* @param {string} dispatchMarker Marker identifying the event target.
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @extends {SyntheticUIEvent}
|
|
*/
|
|
function SyntheticInputEvent(
|
|
dispatchConfig,
|
|
dispatchMarker,
|
|
nativeEvent) {
|
|
SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
|
|
}
|
|
|
|
SyntheticEvent.augmentClass(
|
|
SyntheticInputEvent,
|
|
InputEventInterface
|
|
);
|
|
|
|
module.exports = SyntheticInputEvent;
|
|
|
|
},{"./SyntheticEvent":145}],148:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule SyntheticKeyboardEvent
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var SyntheticUIEvent = require("./SyntheticUIEvent");
|
|
|
|
var getEventCharCode = require("./getEventCharCode");
|
|
var getEventKey = require("./getEventKey");
|
|
var getEventModifierState = require("./getEventModifierState");
|
|
|
|
/**
|
|
* @interface KeyboardEvent
|
|
* @see http://www.w3.org/TR/DOM-Level-3-Events/
|
|
*/
|
|
var KeyboardEventInterface = {
|
|
key: getEventKey,
|
|
location: null,
|
|
ctrlKey: null,
|
|
shiftKey: null,
|
|
altKey: null,
|
|
metaKey: null,
|
|
repeat: null,
|
|
locale: null,
|
|
getModifierState: getEventModifierState,
|
|
// Legacy Interface
|
|
charCode: function(event) {
|
|
// `charCode` is the result of a KeyPress event and represents the value of
|
|
// the actual printable character.
|
|
|
|
// KeyPress is deprecated, but its replacement is not yet final and not
|
|
// implemented in any major browser. Only KeyPress has charCode.
|
|
if (event.type === 'keypress') {
|
|
return getEventCharCode(event);
|
|
}
|
|
return 0;
|
|
},
|
|
keyCode: function(event) {
|
|
// `keyCode` is the result of a KeyDown/Up event and represents the value of
|
|
// physical keyboard key.
|
|
|
|
// The actual meaning of the value depends on the users' keyboard layout
|
|
// which cannot be detected. Assuming that it is a US keyboard layout
|
|
// provides a surprisingly accurate mapping for US and European users.
|
|
// Due to this, it is left to the user to implement at this time.
|
|
if (event.type === 'keydown' || event.type === 'keyup') {
|
|
return event.keyCode;
|
|
}
|
|
return 0;
|
|
},
|
|
which: function(event) {
|
|
// `which` is an alias for either `keyCode` or `charCode` depending on the
|
|
// type of the event.
|
|
if (event.type === 'keypress') {
|
|
return getEventCharCode(event);
|
|
}
|
|
if (event.type === 'keydown' || event.type === 'keyup') {
|
|
return event.keyCode;
|
|
}
|
|
return 0;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @param {object} dispatchConfig Configuration used to dispatch this event.
|
|
* @param {string} dispatchMarker Marker identifying the event target.
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @extends {SyntheticUIEvent}
|
|
*/
|
|
function SyntheticKeyboardEvent(dispatchConfig, dispatchMarker, nativeEvent) {
|
|
SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
|
|
}
|
|
|
|
SyntheticUIEvent.augmentClass(SyntheticKeyboardEvent, KeyboardEventInterface);
|
|
|
|
module.exports = SyntheticKeyboardEvent;
|
|
|
|
},{"./SyntheticUIEvent":151,"./getEventCharCode":172,"./getEventKey":173,"./getEventModifierState":174}],149:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule SyntheticMouseEvent
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var SyntheticUIEvent = require("./SyntheticUIEvent");
|
|
var ViewportMetrics = require("./ViewportMetrics");
|
|
|
|
var getEventModifierState = require("./getEventModifierState");
|
|
|
|
/**
|
|
* @interface MouseEvent
|
|
* @see http://www.w3.org/TR/DOM-Level-3-Events/
|
|
*/
|
|
var MouseEventInterface = {
|
|
screenX: null,
|
|
screenY: null,
|
|
clientX: null,
|
|
clientY: null,
|
|
ctrlKey: null,
|
|
shiftKey: null,
|
|
altKey: null,
|
|
metaKey: null,
|
|
getModifierState: getEventModifierState,
|
|
button: function(event) {
|
|
// Webkit, Firefox, IE9+
|
|
// which: 1 2 3
|
|
// button: 0 1 2 (standard)
|
|
var button = event.button;
|
|
if ('which' in event) {
|
|
return button;
|
|
}
|
|
// IE<9
|
|
// which: undefined
|
|
// button: 0 0 0
|
|
// button: 1 4 2 (onmouseup)
|
|
return button === 2 ? 2 : button === 4 ? 1 : 0;
|
|
},
|
|
buttons: null,
|
|
relatedTarget: function(event) {
|
|
return event.relatedTarget || (
|
|
((event.fromElement === event.srcElement ? event.toElement : event.fromElement))
|
|
);
|
|
},
|
|
// "Proprietary" Interface.
|
|
pageX: function(event) {
|
|
return 'pageX' in event ?
|
|
event.pageX :
|
|
event.clientX + ViewportMetrics.currentScrollLeft;
|
|
},
|
|
pageY: function(event) {
|
|
return 'pageY' in event ?
|
|
event.pageY :
|
|
event.clientY + ViewportMetrics.currentScrollTop;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @param {object} dispatchConfig Configuration used to dispatch this event.
|
|
* @param {string} dispatchMarker Marker identifying the event target.
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @extends {SyntheticUIEvent}
|
|
*/
|
|
function SyntheticMouseEvent(dispatchConfig, dispatchMarker, nativeEvent) {
|
|
SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
|
|
}
|
|
|
|
SyntheticUIEvent.augmentClass(SyntheticMouseEvent, MouseEventInterface);
|
|
|
|
module.exports = SyntheticMouseEvent;
|
|
|
|
},{"./SyntheticUIEvent":151,"./ViewportMetrics":154,"./getEventModifierState":174}],150:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule SyntheticTouchEvent
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var SyntheticUIEvent = require("./SyntheticUIEvent");
|
|
|
|
var getEventModifierState = require("./getEventModifierState");
|
|
|
|
/**
|
|
* @interface TouchEvent
|
|
* @see http://www.w3.org/TR/touch-events/
|
|
*/
|
|
var TouchEventInterface = {
|
|
touches: null,
|
|
targetTouches: null,
|
|
changedTouches: null,
|
|
altKey: null,
|
|
metaKey: null,
|
|
ctrlKey: null,
|
|
shiftKey: null,
|
|
getModifierState: getEventModifierState
|
|
};
|
|
|
|
/**
|
|
* @param {object} dispatchConfig Configuration used to dispatch this event.
|
|
* @param {string} dispatchMarker Marker identifying the event target.
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @extends {SyntheticUIEvent}
|
|
*/
|
|
function SyntheticTouchEvent(dispatchConfig, dispatchMarker, nativeEvent) {
|
|
SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
|
|
}
|
|
|
|
SyntheticUIEvent.augmentClass(SyntheticTouchEvent, TouchEventInterface);
|
|
|
|
module.exports = SyntheticTouchEvent;
|
|
|
|
},{"./SyntheticUIEvent":151,"./getEventModifierState":174}],151:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule SyntheticUIEvent
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var SyntheticEvent = require("./SyntheticEvent");
|
|
|
|
var getEventTarget = require("./getEventTarget");
|
|
|
|
/**
|
|
* @interface UIEvent
|
|
* @see http://www.w3.org/TR/DOM-Level-3-Events/
|
|
*/
|
|
var UIEventInterface = {
|
|
view: function(event) {
|
|
if (event.view) {
|
|
return event.view;
|
|
}
|
|
|
|
var target = getEventTarget(event);
|
|
if (target != null && target.window === target) {
|
|
// target is a window object
|
|
return target;
|
|
}
|
|
|
|
var doc = target.ownerDocument;
|
|
// TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
|
|
if (doc) {
|
|
return doc.defaultView || doc.parentWindow;
|
|
} else {
|
|
return window;
|
|
}
|
|
},
|
|
detail: function(event) {
|
|
return event.detail || 0;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @param {object} dispatchConfig Configuration used to dispatch this event.
|
|
* @param {string} dispatchMarker Marker identifying the event target.
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @extends {SyntheticEvent}
|
|
*/
|
|
function SyntheticUIEvent(dispatchConfig, dispatchMarker, nativeEvent) {
|
|
SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
|
|
}
|
|
|
|
SyntheticEvent.augmentClass(SyntheticUIEvent, UIEventInterface);
|
|
|
|
module.exports = SyntheticUIEvent;
|
|
|
|
},{"./SyntheticEvent":145,"./getEventTarget":175}],152:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule SyntheticWheelEvent
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var SyntheticMouseEvent = require("./SyntheticMouseEvent");
|
|
|
|
/**
|
|
* @interface WheelEvent
|
|
* @see http://www.w3.org/TR/DOM-Level-3-Events/
|
|
*/
|
|
var WheelEventInterface = {
|
|
deltaX: function(event) {
|
|
return (
|
|
'deltaX' in event ? event.deltaX :
|
|
// Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
|
|
'wheelDeltaX' in event ? -event.wheelDeltaX : 0
|
|
);
|
|
},
|
|
deltaY: function(event) {
|
|
return (
|
|
'deltaY' in event ? event.deltaY :
|
|
// Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
|
|
'wheelDeltaY' in event ? -event.wheelDeltaY :
|
|
// Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
|
|
'wheelDelta' in event ? -event.wheelDelta : 0
|
|
);
|
|
},
|
|
deltaZ: null,
|
|
|
|
// Browsers without "deltaMode" is reporting in raw wheel delta where one
|
|
// notch on the scroll is always +/- 120, roughly equivalent to pixels.
|
|
// A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
|
|
// ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
|
|
deltaMode: null
|
|
};
|
|
|
|
/**
|
|
* @param {object} dispatchConfig Configuration used to dispatch this event.
|
|
* @param {string} dispatchMarker Marker identifying the event target.
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @extends {SyntheticMouseEvent}
|
|
*/
|
|
function SyntheticWheelEvent(dispatchConfig, dispatchMarker, nativeEvent) {
|
|
SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
|
|
}
|
|
|
|
SyntheticMouseEvent.augmentClass(SyntheticWheelEvent, WheelEventInterface);
|
|
|
|
module.exports = SyntheticWheelEvent;
|
|
|
|
},{"./SyntheticMouseEvent":149}],153:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule Transaction
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var invariant = require("./invariant");
|
|
|
|
/**
|
|
* `Transaction` creates a black box that is able to wrap any method such that
|
|
* certain invariants are maintained before and after the method is invoked
|
|
* (Even if an exception is thrown while invoking the wrapped method). Whoever
|
|
* instantiates a transaction can provide enforcers of the invariants at
|
|
* creation time. The `Transaction` class itself will supply one additional
|
|
* automatic invariant for you - the invariant that any transaction instance
|
|
* should not be run while it is already being run. You would typically create a
|
|
* single instance of a `Transaction` for reuse multiple times, that potentially
|
|
* is used to wrap several different methods. Wrappers are extremely simple -
|
|
* they only require implementing two methods.
|
|
*
|
|
* <pre>
|
|
* wrappers (injected at creation time)
|
|
* + +
|
|
* | |
|
|
* +-----------------|--------|--------------+
|
|
* | v | |
|
|
* | +---------------+ | |
|
|
* | +--| wrapper1 |---|----+ |
|
|
* | | +---------------+ v | |
|
|
* | | +-------------+ | |
|
|
* | | +----| wrapper2 |--------+ |
|
|
* | | | +-------------+ | | |
|
|
* | | | | | |
|
|
* | v v v v | wrapper
|
|
* | +---+ +---+ +---------+ +---+ +---+ | invariants
|
|
* perform(anyMethod) | | | | | | | | | | | | maintained
|
|
* +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|-------->
|
|
* | | | | | | | | | | | |
|
|
* | | | | | | | | | | | |
|
|
* | | | | | | | | | | | |
|
|
* | +---+ +---+ +---------+ +---+ +---+ |
|
|
* | initialize close |
|
|
* +-----------------------------------------+
|
|
* </pre>
|
|
*
|
|
* Use cases:
|
|
* - Preserving the input selection ranges before/after reconciliation.
|
|
* Restoring selection even in the event of an unexpected error.
|
|
* - Deactivating events while rearranging the DOM, preventing blurs/focuses,
|
|
* while guaranteeing that afterwards, the event system is reactivated.
|
|
* - Flushing a queue of collected DOM mutations to the main UI thread after a
|
|
* reconciliation takes place in a worker thread.
|
|
* - Invoking any collected `componentDidUpdate` callbacks after rendering new
|
|
* content.
|
|
* - (Future use case): Wrapping particular flushes of the `ReactWorker` queue
|
|
* to preserve the `scrollTop` (an automatic scroll aware DOM).
|
|
* - (Future use case): Layout calculations before and after DOM updates.
|
|
*
|
|
* Transactional plugin API:
|
|
* - A module that has an `initialize` method that returns any precomputation.
|
|
* - and a `close` method that accepts the precomputation. `close` is invoked
|
|
* when the wrapped process is completed, or has failed.
|
|
*
|
|
* @param {Array<TransactionalWrapper>} transactionWrapper Wrapper modules
|
|
* that implement `initialize` and `close`.
|
|
* @return {Transaction} Single transaction for reuse in thread.
|
|
*
|
|
* @class Transaction
|
|
*/
|
|
var Mixin = {
|
|
/**
|
|
* Sets up this instance so that it is prepared for collecting metrics. Does
|
|
* so such that this setup method may be used on an instance that is already
|
|
* initialized, in a way that does not consume additional memory upon reuse.
|
|
* That can be useful if you decide to make your subclass of this mixin a
|
|
* "PooledClass".
|
|
*/
|
|
reinitializeTransaction: function() {
|
|
this.transactionWrappers = this.getTransactionWrappers();
|
|
if (!this.wrapperInitData) {
|
|
this.wrapperInitData = [];
|
|
} else {
|
|
this.wrapperInitData.length = 0;
|
|
}
|
|
this._isInTransaction = false;
|
|
},
|
|
|
|
_isInTransaction: false,
|
|
|
|
/**
|
|
* @abstract
|
|
* @return {Array<TransactionWrapper>} Array of transaction wrappers.
|
|
*/
|
|
getTransactionWrappers: null,
|
|
|
|
isInTransaction: function() {
|
|
return !!this._isInTransaction;
|
|
},
|
|
|
|
/**
|
|
* Executes the function within a safety window. Use this for the top level
|
|
* methods that result in large amounts of computation/mutations that would
|
|
* need to be safety checked.
|
|
*
|
|
* @param {function} method Member of scope to call.
|
|
* @param {Object} scope Scope to invoke from.
|
|
* @param {Object?=} args... Arguments to pass to the method (optional).
|
|
* Helps prevent need to bind in many cases.
|
|
* @return Return value from `method`.
|
|
*/
|
|
perform: function(method, scope, a, b, c, d, e, f) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
!this.isInTransaction(),
|
|
'Transaction.perform(...): Cannot initialize a transaction when there ' +
|
|
'is already an outstanding transaction.'
|
|
) : invariant(!this.isInTransaction()));
|
|
var errorThrown;
|
|
var ret;
|
|
try {
|
|
this._isInTransaction = true;
|
|
// Catching errors makes debugging more difficult, so we start with
|
|
// errorThrown set to true before setting it to false after calling
|
|
// close -- if it's still set to true in the finally block, it means
|
|
// one of these calls threw.
|
|
errorThrown = true;
|
|
this.initializeAll(0);
|
|
ret = method.call(scope, a, b, c, d, e, f);
|
|
errorThrown = false;
|
|
} finally {
|
|
try {
|
|
if (errorThrown) {
|
|
// If `method` throws, prefer to show that stack trace over any thrown
|
|
// by invoking `closeAll`.
|
|
try {
|
|
this.closeAll(0);
|
|
} catch (err) {
|
|
}
|
|
} else {
|
|
// Since `method` didn't throw, we don't want to silence the exception
|
|
// here.
|
|
this.closeAll(0);
|
|
}
|
|
} finally {
|
|
this._isInTransaction = false;
|
|
}
|
|
}
|
|
return ret;
|
|
},
|
|
|
|
initializeAll: function(startIndex) {
|
|
var transactionWrappers = this.transactionWrappers;
|
|
for (var i = startIndex; i < transactionWrappers.length; i++) {
|
|
var wrapper = transactionWrappers[i];
|
|
try {
|
|
// Catching errors makes debugging more difficult, so we start with the
|
|
// OBSERVED_ERROR state before overwriting it with the real return value
|
|
// of initialize -- if it's still set to OBSERVED_ERROR in the finally
|
|
// block, it means wrapper.initialize threw.
|
|
this.wrapperInitData[i] = Transaction.OBSERVED_ERROR;
|
|
this.wrapperInitData[i] = wrapper.initialize ?
|
|
wrapper.initialize.call(this) :
|
|
null;
|
|
} finally {
|
|
if (this.wrapperInitData[i] === Transaction.OBSERVED_ERROR) {
|
|
// The initializer for wrapper i threw an error; initialize the
|
|
// remaining wrappers but silence any exceptions from them to ensure
|
|
// that the first error is the one to bubble up.
|
|
try {
|
|
this.initializeAll(i + 1);
|
|
} catch (err) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Invokes each of `this.transactionWrappers.close[i]` functions, passing into
|
|
* them the respective return values of `this.transactionWrappers.init[i]`
|
|
* (`close`rs that correspond to initializers that failed will not be
|
|
* invoked).
|
|
*/
|
|
closeAll: function(startIndex) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
this.isInTransaction(),
|
|
'Transaction.closeAll(): Cannot close transaction when none are open.'
|
|
) : invariant(this.isInTransaction()));
|
|
var transactionWrappers = this.transactionWrappers;
|
|
for (var i = startIndex; i < transactionWrappers.length; i++) {
|
|
var wrapper = transactionWrappers[i];
|
|
var initData = this.wrapperInitData[i];
|
|
var errorThrown;
|
|
try {
|
|
// Catching errors makes debugging more difficult, so we start with
|
|
// errorThrown set to true before setting it to false after calling
|
|
// close -- if it's still set to true in the finally block, it means
|
|
// wrapper.close threw.
|
|
errorThrown = true;
|
|
if (initData !== Transaction.OBSERVED_ERROR && wrapper.close) {
|
|
wrapper.close.call(this, initData);
|
|
}
|
|
errorThrown = false;
|
|
} finally {
|
|
if (errorThrown) {
|
|
// The closer for wrapper i threw an error; close the remaining
|
|
// wrappers but silence any exceptions from them to ensure that the
|
|
// first error is the one to bubble up.
|
|
try {
|
|
this.closeAll(i + 1);
|
|
} catch (e) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
this.wrapperInitData.length = 0;
|
|
}
|
|
};
|
|
|
|
var Transaction = {
|
|
|
|
Mixin: Mixin,
|
|
|
|
/**
|
|
* Token to look for to determine if an error occured.
|
|
*/
|
|
OBSERVED_ERROR: {}
|
|
|
|
};
|
|
|
|
module.exports = Transaction;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./invariant":185,"_process":1}],154:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule ViewportMetrics
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ViewportMetrics = {
|
|
|
|
currentScrollLeft: 0,
|
|
|
|
currentScrollTop: 0,
|
|
|
|
refreshScrollValues: function(scrollPosition) {
|
|
ViewportMetrics.currentScrollLeft = scrollPosition.x;
|
|
ViewportMetrics.currentScrollTop = scrollPosition.y;
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = ViewportMetrics;
|
|
|
|
},{}],155:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2014-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule accumulateInto
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var invariant = require("./invariant");
|
|
|
|
/**
|
|
*
|
|
* Accumulates items that must not be null or undefined into the first one. This
|
|
* is used to conserve memory by avoiding array allocations, and thus sacrifices
|
|
* API cleanness. Since `current` can be null before being passed in and not
|
|
* null after this function, make sure to assign it back to `current`:
|
|
*
|
|
* `a = accumulateInto(a, b);`
|
|
*
|
|
* This API should be sparingly used. Try `accumulate` for something cleaner.
|
|
*
|
|
* @return {*|array<*>} An accumulation of items.
|
|
*/
|
|
|
|
function accumulateInto(current, next) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
next != null,
|
|
'accumulateInto(...): Accumulated items must not be null or undefined.'
|
|
) : invariant(next != null));
|
|
if (current == null) {
|
|
return next;
|
|
}
|
|
|
|
// Both are not empty. Warning: Never call x.concat(y) when you are not
|
|
// certain that x is an Array (x could be a string with concat method).
|
|
var currentIsArray = Array.isArray(current);
|
|
var nextIsArray = Array.isArray(next);
|
|
|
|
if (currentIsArray && nextIsArray) {
|
|
current.push.apply(current, next);
|
|
return current;
|
|
}
|
|
|
|
if (currentIsArray) {
|
|
current.push(next);
|
|
return current;
|
|
}
|
|
|
|
if (nextIsArray) {
|
|
// A bit too dangerous to mutate `next`.
|
|
return [current].concat(next);
|
|
}
|
|
|
|
return [current, next];
|
|
}
|
|
|
|
module.exports = accumulateInto;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./invariant":185,"_process":1}],156:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule adler32
|
|
*/
|
|
|
|
/* jslint bitwise:true */
|
|
|
|
'use strict';
|
|
|
|
var MOD = 65521;
|
|
|
|
// This is a clean-room implementation of adler32 designed for detecting
|
|
// if markup is not what we expect it to be. It does not need to be
|
|
// cryptographically strong, only reasonably good at detecting if markup
|
|
// generated on the server is different than that on the client.
|
|
function adler32(data) {
|
|
var a = 1;
|
|
var b = 0;
|
|
for (var i = 0; i < data.length; i++) {
|
|
a = (a + data.charCodeAt(i)) % MOD;
|
|
b = (b + a) % MOD;
|
|
}
|
|
return a | (b << 16);
|
|
}
|
|
|
|
module.exports = adler32;
|
|
|
|
},{}],157:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule camelize
|
|
* @typechecks
|
|
*/
|
|
|
|
var _hyphenPattern = /-(.)/g;
|
|
|
|
/**
|
|
* Camelcases a hyphenated string, for example:
|
|
*
|
|
* > camelize('background-color')
|
|
* < "backgroundColor"
|
|
*
|
|
* @param {string} string
|
|
* @return {string}
|
|
*/
|
|
function camelize(string) {
|
|
return string.replace(_hyphenPattern, function(_, character) {
|
|
return character.toUpperCase();
|
|
});
|
|
}
|
|
|
|
module.exports = camelize;
|
|
|
|
},{}],158:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2014-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule camelizeStyleName
|
|
* @typechecks
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
var camelize = require("./camelize");
|
|
|
|
var msPattern = /^-ms-/;
|
|
|
|
/**
|
|
* Camelcases a hyphenated CSS property name, for example:
|
|
*
|
|
* > camelizeStyleName('background-color')
|
|
* < "backgroundColor"
|
|
* > camelizeStyleName('-moz-transition')
|
|
* < "MozTransition"
|
|
* > camelizeStyleName('-ms-transition')
|
|
* < "msTransition"
|
|
*
|
|
* As Andi Smith suggests
|
|
* (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
|
|
* is converted to lowercase `ms`.
|
|
*
|
|
* @param {string} string
|
|
* @return {string}
|
|
*/
|
|
function camelizeStyleName(string) {
|
|
return camelize(string.replace(msPattern, 'ms-'));
|
|
}
|
|
|
|
module.exports = camelizeStyleName;
|
|
|
|
},{"./camelize":157}],159:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule containsNode
|
|
* @typechecks
|
|
*/
|
|
|
|
var isTextNode = require("./isTextNode");
|
|
|
|
/*jslint bitwise:true */
|
|
|
|
/**
|
|
* Checks if a given DOM node contains or is another DOM node.
|
|
*
|
|
* @param {?DOMNode} outerNode Outer DOM node.
|
|
* @param {?DOMNode} innerNode Inner DOM node.
|
|
* @return {boolean} True if `outerNode` contains or is `innerNode`.
|
|
*/
|
|
function containsNode(outerNode, innerNode) {
|
|
if (!outerNode || !innerNode) {
|
|
return false;
|
|
} else if (outerNode === innerNode) {
|
|
return true;
|
|
} else if (isTextNode(outerNode)) {
|
|
return false;
|
|
} else if (isTextNode(innerNode)) {
|
|
return containsNode(outerNode, innerNode.parentNode);
|
|
} else if (outerNode.contains) {
|
|
return outerNode.contains(innerNode);
|
|
} else if (outerNode.compareDocumentPosition) {
|
|
return !!(outerNode.compareDocumentPosition(innerNode) & 16);
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
module.exports = containsNode;
|
|
|
|
},{"./isTextNode":189}],160:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule createArrayFromMixed
|
|
* @typechecks
|
|
*/
|
|
|
|
var toArray = require("./toArray");
|
|
|
|
/**
|
|
* Perform a heuristic test to determine if an object is "array-like".
|
|
*
|
|
* A monk asked Joshu, a Zen master, "Has a dog Buddha nature?"
|
|
* Joshu replied: "Mu."
|
|
*
|
|
* This function determines if its argument has "array nature": it returns
|
|
* true if the argument is an actual array, an `arguments' object, or an
|
|
* HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()).
|
|
*
|
|
* It will return false for other array-like objects like Filelist.
|
|
*
|
|
* @param {*} obj
|
|
* @return {boolean}
|
|
*/
|
|
function hasArrayNature(obj) {
|
|
return (
|
|
// not null/false
|
|
!!obj &&
|
|
// arrays are objects, NodeLists are functions in Safari
|
|
(typeof obj == 'object' || typeof obj == 'function') &&
|
|
// quacks like an array
|
|
('length' in obj) &&
|
|
// not window
|
|
!('setInterval' in obj) &&
|
|
// no DOM node should be considered an array-like
|
|
// a 'select' element has 'length' and 'item' properties on IE8
|
|
(typeof obj.nodeType != 'number') &&
|
|
(
|
|
// a real array
|
|
(// HTMLCollection/NodeList
|
|
(Array.isArray(obj) ||
|
|
// arguments
|
|
('callee' in obj) || 'item' in obj))
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Ensure that the argument is an array by wrapping it in an array if it is not.
|
|
* Creates a copy of the argument if it is already an array.
|
|
*
|
|
* This is mostly useful idiomatically:
|
|
*
|
|
* var createArrayFromMixed = require('createArrayFromMixed');
|
|
*
|
|
* function takesOneOrMoreThings(things) {
|
|
* things = createArrayFromMixed(things);
|
|
* ...
|
|
* }
|
|
*
|
|
* This allows you to treat `things' as an array, but accept scalars in the API.
|
|
*
|
|
* If you need to convert an array-like object, like `arguments`, into an array
|
|
* use toArray instead.
|
|
*
|
|
* @param {*} obj
|
|
* @return {array}
|
|
*/
|
|
function createArrayFromMixed(obj) {
|
|
if (!hasArrayNature(obj)) {
|
|
return [obj];
|
|
} else if (Array.isArray(obj)) {
|
|
return obj.slice();
|
|
} else {
|
|
return toArray(obj);
|
|
}
|
|
}
|
|
|
|
module.exports = createArrayFromMixed;
|
|
|
|
},{"./toArray":202}],161:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule createFullPageComponent
|
|
* @typechecks
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
// Defeat circular references by requiring this directly.
|
|
var ReactClass = require("./ReactClass");
|
|
var ReactElement = require("./ReactElement");
|
|
|
|
var invariant = require("./invariant");
|
|
|
|
/**
|
|
* Create a component that will throw an exception when unmounted.
|
|
*
|
|
* Components like <html> <head> and <body> can't be removed or added
|
|
* easily in a cross-browser way, however it's valuable to be able to
|
|
* take advantage of React's reconciliation for styling and <title>
|
|
* management. So we just document it and throw in dangerous cases.
|
|
*
|
|
* @param {string} tag The tag to wrap
|
|
* @return {function} convenience constructor of new component
|
|
*/
|
|
function createFullPageComponent(tag) {
|
|
var elementFactory = ReactElement.createFactory(tag);
|
|
|
|
var FullPageComponent = ReactClass.createClass({
|
|
tagName: tag.toUpperCase(),
|
|
displayName: 'ReactFullPageComponent' + tag,
|
|
|
|
componentWillUnmount: function() {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
false,
|
|
'%s tried to unmount. Because of cross-browser quirks it is ' +
|
|
'impossible to unmount some top-level components (eg <html>, <head>, ' +
|
|
'and <body>) reliably and efficiently. To fix this, have a single ' +
|
|
'top-level component that never unmounts render these elements.',
|
|
this.constructor.displayName
|
|
) : invariant(false));
|
|
},
|
|
|
|
render: function() {
|
|
return elementFactory(this.props);
|
|
}
|
|
});
|
|
|
|
return FullPageComponent;
|
|
}
|
|
|
|
module.exports = createFullPageComponent;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./ReactClass":83,"./ReactElement":107,"./invariant":185,"_process":1}],162:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule createNodesFromMarkup
|
|
* @typechecks
|
|
*/
|
|
|
|
/*jslint evil: true, sub: true */
|
|
|
|
var ExecutionEnvironment = require("./ExecutionEnvironment");
|
|
|
|
var createArrayFromMixed = require("./createArrayFromMixed");
|
|
var getMarkupWrap = require("./getMarkupWrap");
|
|
var invariant = require("./invariant");
|
|
|
|
/**
|
|
* Dummy container used to render all markup.
|
|
*/
|
|
var dummyNode =
|
|
ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;
|
|
|
|
/**
|
|
* Pattern used by `getNodeName`.
|
|
*/
|
|
var nodeNamePattern = /^\s*<(\w+)/;
|
|
|
|
/**
|
|
* Extracts the `nodeName` of the first element in a string of markup.
|
|
*
|
|
* @param {string} markup String of markup.
|
|
* @return {?string} Node name of the supplied markup.
|
|
*/
|
|
function getNodeName(markup) {
|
|
var nodeNameMatch = markup.match(nodeNamePattern);
|
|
return nodeNameMatch && nodeNameMatch[1].toLowerCase();
|
|
}
|
|
|
|
/**
|
|
* Creates an array containing the nodes rendered from the supplied markup. The
|
|
* optionally supplied `handleScript` function will be invoked once for each
|
|
* <script> element that is rendered. If no `handleScript` function is supplied,
|
|
* an exception is thrown if any <script> elements are rendered.
|
|
*
|
|
* @param {string} markup A string of valid HTML markup.
|
|
* @param {?function} handleScript Invoked once for each rendered <script>.
|
|
* @return {array<DOMElement|DOMTextNode>} An array of rendered nodes.
|
|
*/
|
|
function createNodesFromMarkup(markup, handleScript) {
|
|
var node = dummyNode;
|
|
("production" !== process.env.NODE_ENV ? invariant(!!dummyNode, 'createNodesFromMarkup dummy not initialized') : invariant(!!dummyNode));
|
|
var nodeName = getNodeName(markup);
|
|
|
|
var wrap = nodeName && getMarkupWrap(nodeName);
|
|
if (wrap) {
|
|
node.innerHTML = wrap[1] + markup + wrap[2];
|
|
|
|
var wrapDepth = wrap[0];
|
|
while (wrapDepth--) {
|
|
node = node.lastChild;
|
|
}
|
|
} else {
|
|
node.innerHTML = markup;
|
|
}
|
|
|
|
var scripts = node.getElementsByTagName('script');
|
|
if (scripts.length) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
handleScript,
|
|
'createNodesFromMarkup(...): Unexpected <script> element rendered.'
|
|
) : invariant(handleScript));
|
|
createArrayFromMixed(scripts).forEach(handleScript);
|
|
}
|
|
|
|
var nodes = createArrayFromMixed(node.childNodes);
|
|
while (node.lastChild) {
|
|
node.removeChild(node.lastChild);
|
|
}
|
|
return nodes;
|
|
}
|
|
|
|
module.exports = createNodesFromMarkup;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./ExecutionEnvironment":70,"./createArrayFromMixed":160,"./getMarkupWrap":177,"./invariant":185,"_process":1}],163:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule dangerousStyleValue
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var CSSProperty = require("./CSSProperty");
|
|
|
|
var isUnitlessNumber = CSSProperty.isUnitlessNumber;
|
|
|
|
/**
|
|
* Convert a value into the proper css writable value. The style name `name`
|
|
* should be logical (no hyphens), as specified
|
|
* in `CSSProperty.isUnitlessNumber`.
|
|
*
|
|
* @param {string} name CSS property name such as `topMargin`.
|
|
* @param {*} value CSS property value such as `10px`.
|
|
* @return {string} Normalized style value with dimensions applied.
|
|
*/
|
|
function dangerousStyleValue(name, value) {
|
|
// Note that we've removed escapeTextForBrowser() calls here since the
|
|
// whole string will be escaped when the attribute is injected into
|
|
// the markup. If you provide unsafe user data here they can inject
|
|
// arbitrary CSS which may be problematic (I couldn't repro this):
|
|
// https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
|
|
// http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
|
|
// This is not an XSS hole but instead a potential CSS injection issue
|
|
// which has lead to a greater discussion about how we're going to
|
|
// trust URLs moving forward. See #2115901
|
|
|
|
var isEmpty = value == null || typeof value === 'boolean' || value === '';
|
|
if (isEmpty) {
|
|
return '';
|
|
}
|
|
|
|
var isNonNumeric = isNaN(value);
|
|
if (isNonNumeric || value === 0 ||
|
|
isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name]) {
|
|
return '' + value; // cast to string
|
|
}
|
|
|
|
if (typeof value === 'string') {
|
|
value = value.trim();
|
|
}
|
|
return value + 'px';
|
|
}
|
|
|
|
module.exports = dangerousStyleValue;
|
|
|
|
},{"./CSSProperty":53}],164:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule emptyFunction
|
|
*/
|
|
|
|
function makeEmptyFunction(arg) {
|
|
return function() {
|
|
return arg;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* This function accepts and discards inputs; it has no side effects. This is
|
|
* primarily useful idiomatically for overridable function endpoints which
|
|
* always need to be callable, since JS lacks a null-call idiom ala Cocoa.
|
|
*/
|
|
function emptyFunction() {}
|
|
|
|
emptyFunction.thatReturns = makeEmptyFunction;
|
|
emptyFunction.thatReturnsFalse = makeEmptyFunction(false);
|
|
emptyFunction.thatReturnsTrue = makeEmptyFunction(true);
|
|
emptyFunction.thatReturnsNull = makeEmptyFunction(null);
|
|
emptyFunction.thatReturnsThis = function() { return this; };
|
|
emptyFunction.thatReturnsArgument = function(arg) { return arg; };
|
|
|
|
module.exports = emptyFunction;
|
|
|
|
},{}],165:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule emptyObject
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
var emptyObject = {};
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
Object.freeze(emptyObject);
|
|
}
|
|
|
|
module.exports = emptyObject;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"_process":1}],166:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule escapeTextContentForBrowser
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ESCAPE_LOOKUP = {
|
|
'&': '&',
|
|
'>': '>',
|
|
'<': '<',
|
|
'"': '"',
|
|
'\'': '''
|
|
};
|
|
|
|
var ESCAPE_REGEX = /[&><"']/g;
|
|
|
|
function escaper(match) {
|
|
return ESCAPE_LOOKUP[match];
|
|
}
|
|
|
|
/**
|
|
* Escapes text to prevent scripting attacks.
|
|
*
|
|
* @param {*} text Text value to escape.
|
|
* @return {string} An escaped string.
|
|
*/
|
|
function escapeTextContentForBrowser(text) {
|
|
return ('' + text).replace(ESCAPE_REGEX, escaper);
|
|
}
|
|
|
|
module.exports = escapeTextContentForBrowser;
|
|
|
|
},{}],167:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule findDOMNode
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactCurrentOwner = require("./ReactCurrentOwner");
|
|
var ReactInstanceMap = require("./ReactInstanceMap");
|
|
var ReactMount = require("./ReactMount");
|
|
|
|
var invariant = require("./invariant");
|
|
var isNode = require("./isNode");
|
|
var warning = require("./warning");
|
|
|
|
/**
|
|
* Returns the DOM node rendered by this element.
|
|
*
|
|
* @param {ReactComponent|DOMElement} componentOrElement
|
|
* @return {DOMElement} The root node of this element.
|
|
*/
|
|
function findDOMNode(componentOrElement) {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
var owner = ReactCurrentOwner.current;
|
|
if (owner !== null) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
owner._warnedAboutRefsInRender,
|
|
'%s is accessing getDOMNode or findDOMNode inside its render(). ' +
|
|
'render() should be a pure function of props and state. It should ' +
|
|
'never access something that requires stale data from the previous ' +
|
|
'render, such as refs. Move this logic to componentDidMount and ' +
|
|
'componentDidUpdate instead.',
|
|
owner.getName() || 'A component'
|
|
) : null);
|
|
owner._warnedAboutRefsInRender = true;
|
|
}
|
|
}
|
|
if (componentOrElement == null) {
|
|
return null;
|
|
}
|
|
if (isNode(componentOrElement)) {
|
|
return componentOrElement;
|
|
}
|
|
if (ReactInstanceMap.has(componentOrElement)) {
|
|
return ReactMount.getNodeFromInstance(componentOrElement);
|
|
}
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
componentOrElement.render == null ||
|
|
typeof componentOrElement.render !== 'function',
|
|
'Component (with keys: %s) contains `render` method ' +
|
|
'but is not mounted in the DOM',
|
|
Object.keys(componentOrElement)
|
|
) : invariant(componentOrElement.render == null ||
|
|
typeof componentOrElement.render !== 'function'));
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
false,
|
|
'Element appears to be neither ReactComponent nor DOMNode (keys: %s)',
|
|
Object.keys(componentOrElement)
|
|
) : invariant(false));
|
|
}
|
|
|
|
module.exports = findDOMNode;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./ReactCurrentOwner":89,"./ReactInstanceMap":117,"./ReactMount":120,"./invariant":185,"./isNode":187,"./warning":204,"_process":1}],168:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule flattenChildren
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var traverseAllChildren = require("./traverseAllChildren");
|
|
var warning = require("./warning");
|
|
|
|
/**
|
|
* @param {function} traverseContext Context passed through traversal.
|
|
* @param {?ReactComponent} child React child component.
|
|
* @param {!string} name String name of key path to child.
|
|
*/
|
|
function flattenSingleChildIntoContext(traverseContext, child, name) {
|
|
// We found a component instance.
|
|
var result = traverseContext;
|
|
var keyUnique = !result.hasOwnProperty(name);
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
keyUnique,
|
|
'flattenChildren(...): Encountered two children with the same key, ' +
|
|
'`%s`. Child keys must be unique; when two children share a key, only ' +
|
|
'the first child will be used.',
|
|
name
|
|
) : null);
|
|
}
|
|
if (keyUnique && child != null) {
|
|
result[name] = child;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Flattens children that are typically specified as `props.children`. Any null
|
|
* children will not be included in the resulting object.
|
|
* @return {!object} flattened children keyed by name.
|
|
*/
|
|
function flattenChildren(children) {
|
|
if (children == null) {
|
|
return children;
|
|
}
|
|
var result = {};
|
|
traverseAllChildren(children, flattenSingleChildIntoContext, result);
|
|
return result;
|
|
}
|
|
|
|
module.exports = flattenChildren;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./traverseAllChildren":203,"./warning":204,"_process":1}],169:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2014-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule focusNode
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
/**
|
|
* @param {DOMElement} node input/textarea to focus
|
|
*/
|
|
function focusNode(node) {
|
|
// IE8 can throw "Can't move focus to the control because it is invisible,
|
|
// not enabled, or of a type that does not accept the focus." for all kinds of
|
|
// reasons that are too expensive and fragile to test.
|
|
try {
|
|
node.focus();
|
|
} catch(e) {
|
|
}
|
|
}
|
|
|
|
module.exports = focusNode;
|
|
|
|
},{}],170:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule forEachAccumulated
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* @param {array} an "accumulation" of items which is either an Array or
|
|
* a single item. Useful when paired with the `accumulate` module. This is a
|
|
* simple utility that allows us to reason about a collection of items, but
|
|
* handling the case when there is exactly one item (and we do not need to
|
|
* allocate an array).
|
|
*/
|
|
var forEachAccumulated = function(arr, cb, scope) {
|
|
if (Array.isArray(arr)) {
|
|
arr.forEach(cb, scope);
|
|
} else if (arr) {
|
|
cb.call(scope, arr);
|
|
}
|
|
};
|
|
|
|
module.exports = forEachAccumulated;
|
|
|
|
},{}],171:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule getActiveElement
|
|
* @typechecks
|
|
*/
|
|
|
|
/**
|
|
* Same as document.activeElement but wraps in a try-catch block. In IE it is
|
|
* not safe to call document.activeElement if there is nothing focused.
|
|
*
|
|
* The activeElement will be null only if the document body is not yet defined.
|
|
*/
|
|
function getActiveElement() /*?DOMElement*/ {
|
|
try {
|
|
return document.activeElement || document.body;
|
|
} catch (e) {
|
|
return document.body;
|
|
}
|
|
}
|
|
|
|
module.exports = getActiveElement;
|
|
|
|
},{}],172:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule getEventCharCode
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* `charCode` represents the actual "character code" and is safe to use with
|
|
* `String.fromCharCode`. As such, only keys that correspond to printable
|
|
* characters produce a valid `charCode`, the only exception to this is Enter.
|
|
* The Tab-key is considered non-printable and does not have a `charCode`,
|
|
* presumably because it does not produce a tab-character in browsers.
|
|
*
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @return {string} Normalized `charCode` property.
|
|
*/
|
|
function getEventCharCode(nativeEvent) {
|
|
var charCode;
|
|
var keyCode = nativeEvent.keyCode;
|
|
|
|
if ('charCode' in nativeEvent) {
|
|
charCode = nativeEvent.charCode;
|
|
|
|
// FF does not set `charCode` for the Enter-key, check against `keyCode`.
|
|
if (charCode === 0 && keyCode === 13) {
|
|
charCode = 13;
|
|
}
|
|
} else {
|
|
// IE8 does not implement `charCode`, but `keyCode` has the correct value.
|
|
charCode = keyCode;
|
|
}
|
|
|
|
// Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
|
|
// Must not discard the (non-)printable Enter-key.
|
|
if (charCode >= 32 || charCode === 13) {
|
|
return charCode;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
module.exports = getEventCharCode;
|
|
|
|
},{}],173:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule getEventKey
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var getEventCharCode = require("./getEventCharCode");
|
|
|
|
/**
|
|
* Normalization of deprecated HTML5 `key` values
|
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
|
|
*/
|
|
var normalizeKey = {
|
|
'Esc': 'Escape',
|
|
'Spacebar': ' ',
|
|
'Left': 'ArrowLeft',
|
|
'Up': 'ArrowUp',
|
|
'Right': 'ArrowRight',
|
|
'Down': 'ArrowDown',
|
|
'Del': 'Delete',
|
|
'Win': 'OS',
|
|
'Menu': 'ContextMenu',
|
|
'Apps': 'ContextMenu',
|
|
'Scroll': 'ScrollLock',
|
|
'MozPrintableKey': 'Unidentified'
|
|
};
|
|
|
|
/**
|
|
* Translation from legacy `keyCode` to HTML5 `key`
|
|
* Only special keys supported, all others depend on keyboard layout or browser
|
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
|
|
*/
|
|
var translateToKey = {
|
|
8: 'Backspace',
|
|
9: 'Tab',
|
|
12: 'Clear',
|
|
13: 'Enter',
|
|
16: 'Shift',
|
|
17: 'Control',
|
|
18: 'Alt',
|
|
19: 'Pause',
|
|
20: 'CapsLock',
|
|
27: 'Escape',
|
|
32: ' ',
|
|
33: 'PageUp',
|
|
34: 'PageDown',
|
|
35: 'End',
|
|
36: 'Home',
|
|
37: 'ArrowLeft',
|
|
38: 'ArrowUp',
|
|
39: 'ArrowRight',
|
|
40: 'ArrowDown',
|
|
45: 'Insert',
|
|
46: 'Delete',
|
|
112: 'F1', 113: 'F2', 114: 'F3', 115: 'F4', 116: 'F5', 117: 'F6',
|
|
118: 'F7', 119: 'F8', 120: 'F9', 121: 'F10', 122: 'F11', 123: 'F12',
|
|
144: 'NumLock',
|
|
145: 'ScrollLock',
|
|
224: 'Meta'
|
|
};
|
|
|
|
/**
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @return {string} Normalized `key` property.
|
|
*/
|
|
function getEventKey(nativeEvent) {
|
|
if (nativeEvent.key) {
|
|
// Normalize inconsistent values reported by browsers due to
|
|
// implementations of a working draft specification.
|
|
|
|
// FireFox implements `key` but returns `MozPrintableKey` for all
|
|
// printable characters (normalized to `Unidentified`), ignore it.
|
|
var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
|
|
if (key !== 'Unidentified') {
|
|
return key;
|
|
}
|
|
}
|
|
|
|
// Browser does not implement `key`, polyfill as much of it as we can.
|
|
if (nativeEvent.type === 'keypress') {
|
|
var charCode = getEventCharCode(nativeEvent);
|
|
|
|
// The enter-key is technically both printable and non-printable and can
|
|
// thus be captured by `keypress`, no other non-printable key should.
|
|
return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
|
|
}
|
|
if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
|
|
// While user keyboard layout determines the actual meaning of each
|
|
// `keyCode` value, almost all function keys have a universal value.
|
|
return translateToKey[nativeEvent.keyCode] || 'Unidentified';
|
|
}
|
|
return '';
|
|
}
|
|
|
|
module.exports = getEventKey;
|
|
|
|
},{"./getEventCharCode":172}],174:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule getEventModifierState
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* Translation from modifier key to the associated property in the event.
|
|
* @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
|
|
*/
|
|
|
|
var modifierKeyToProp = {
|
|
'Alt': 'altKey',
|
|
'Control': 'ctrlKey',
|
|
'Meta': 'metaKey',
|
|
'Shift': 'shiftKey'
|
|
};
|
|
|
|
// IE8 does not implement getModifierState so we simply map it to the only
|
|
// modifier keys exposed by the event itself, does not support Lock-keys.
|
|
// Currently, all major browsers except Chrome seems to support Lock-keys.
|
|
function modifierStateGetter(keyArg) {
|
|
/*jshint validthis:true */
|
|
var syntheticEvent = this;
|
|
var nativeEvent = syntheticEvent.nativeEvent;
|
|
if (nativeEvent.getModifierState) {
|
|
return nativeEvent.getModifierState(keyArg);
|
|
}
|
|
var keyProp = modifierKeyToProp[keyArg];
|
|
return keyProp ? !!nativeEvent[keyProp] : false;
|
|
}
|
|
|
|
function getEventModifierState(nativeEvent) {
|
|
return modifierStateGetter;
|
|
}
|
|
|
|
module.exports = getEventModifierState;
|
|
|
|
},{}],175:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule getEventTarget
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* Gets the target node from a native browser event by accounting for
|
|
* inconsistencies in browser DOM APIs.
|
|
*
|
|
* @param {object} nativeEvent Native browser event.
|
|
* @return {DOMEventTarget} Target node.
|
|
*/
|
|
function getEventTarget(nativeEvent) {
|
|
var target = nativeEvent.target || nativeEvent.srcElement || window;
|
|
// Safari may fire events on text nodes (Node.TEXT_NODE is 3).
|
|
// @see http://www.quirksmode.org/js/events_properties.html
|
|
return target.nodeType === 3 ? target.parentNode : target;
|
|
}
|
|
|
|
module.exports = getEventTarget;
|
|
|
|
},{}],176:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule getIteratorFn
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
/* global Symbol */
|
|
var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
|
|
var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec.
|
|
|
|
/**
|
|
* Returns the iterator method function contained on the iterable object.
|
|
*
|
|
* Be sure to invoke the function with the iterable as context:
|
|
*
|
|
* var iteratorFn = getIteratorFn(myIterable);
|
|
* if (iteratorFn) {
|
|
* var iterator = iteratorFn.call(myIterable);
|
|
* ...
|
|
* }
|
|
*
|
|
* @param {?object} maybeIterable
|
|
* @return {?function}
|
|
*/
|
|
function getIteratorFn(maybeIterable) {
|
|
var iteratorFn = maybeIterable && (
|
|
(ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL])
|
|
);
|
|
if (typeof iteratorFn === 'function') {
|
|
return iteratorFn;
|
|
}
|
|
}
|
|
|
|
module.exports = getIteratorFn;
|
|
|
|
},{}],177:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule getMarkupWrap
|
|
*/
|
|
|
|
var ExecutionEnvironment = require("./ExecutionEnvironment");
|
|
|
|
var invariant = require("./invariant");
|
|
|
|
/**
|
|
* Dummy container used to detect which wraps are necessary.
|
|
*/
|
|
var dummyNode =
|
|
ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;
|
|
|
|
/**
|
|
* Some browsers cannot use `innerHTML` to render certain elements standalone,
|
|
* so we wrap them, render the wrapped nodes, then extract the desired node.
|
|
*
|
|
* In IE8, certain elements cannot render alone, so wrap all elements ('*').
|
|
*/
|
|
var shouldWrap = {
|
|
// Force wrapping for SVG elements because if they get created inside a <div>,
|
|
// they will be initialized in the wrong namespace (and will not display).
|
|
'circle': true,
|
|
'clipPath': true,
|
|
'defs': true,
|
|
'ellipse': true,
|
|
'g': true,
|
|
'line': true,
|
|
'linearGradient': true,
|
|
'path': true,
|
|
'polygon': true,
|
|
'polyline': true,
|
|
'radialGradient': true,
|
|
'rect': true,
|
|
'stop': true,
|
|
'text': true
|
|
};
|
|
|
|
var selectWrap = [1, '<select multiple="true">', '</select>'];
|
|
var tableWrap = [1, '<table>', '</table>'];
|
|
var trWrap = [3, '<table><tbody><tr>', '</tr></tbody></table>'];
|
|
|
|
var svgWrap = [1, '<svg>', '</svg>'];
|
|
|
|
var markupWrap = {
|
|
'*': [1, '?<div>', '</div>'],
|
|
|
|
'area': [1, '<map>', '</map>'],
|
|
'col': [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
|
|
'legend': [1, '<fieldset>', '</fieldset>'],
|
|
'param': [1, '<object>', '</object>'],
|
|
'tr': [2, '<table><tbody>', '</tbody></table>'],
|
|
|
|
'optgroup': selectWrap,
|
|
'option': selectWrap,
|
|
|
|
'caption': tableWrap,
|
|
'colgroup': tableWrap,
|
|
'tbody': tableWrap,
|
|
'tfoot': tableWrap,
|
|
'thead': tableWrap,
|
|
|
|
'td': trWrap,
|
|
'th': trWrap,
|
|
|
|
'circle': svgWrap,
|
|
'clipPath': svgWrap,
|
|
'defs': svgWrap,
|
|
'ellipse': svgWrap,
|
|
'g': svgWrap,
|
|
'line': svgWrap,
|
|
'linearGradient': svgWrap,
|
|
'path': svgWrap,
|
|
'polygon': svgWrap,
|
|
'polyline': svgWrap,
|
|
'radialGradient': svgWrap,
|
|
'rect': svgWrap,
|
|
'stop': svgWrap,
|
|
'text': svgWrap
|
|
};
|
|
|
|
/**
|
|
* Gets the markup wrap configuration for the supplied `nodeName`.
|
|
*
|
|
* NOTE: This lazily detects which wraps are necessary for the current browser.
|
|
*
|
|
* @param {string} nodeName Lowercase `nodeName`.
|
|
* @return {?array} Markup wrap configuration, if applicable.
|
|
*/
|
|
function getMarkupWrap(nodeName) {
|
|
("production" !== process.env.NODE_ENV ? invariant(!!dummyNode, 'Markup wrapping node not initialized') : invariant(!!dummyNode));
|
|
if (!markupWrap.hasOwnProperty(nodeName)) {
|
|
nodeName = '*';
|
|
}
|
|
if (!shouldWrap.hasOwnProperty(nodeName)) {
|
|
if (nodeName === '*') {
|
|
dummyNode.innerHTML = '<link />';
|
|
} else {
|
|
dummyNode.innerHTML = '<' + nodeName + '></' + nodeName + '>';
|
|
}
|
|
shouldWrap[nodeName] = !dummyNode.firstChild;
|
|
}
|
|
return shouldWrap[nodeName] ? markupWrap[nodeName] : null;
|
|
}
|
|
|
|
|
|
module.exports = getMarkupWrap;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./ExecutionEnvironment":70,"./invariant":185,"_process":1}],178:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule getNodeForCharacterOffset
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* Given any node return the first leaf node without children.
|
|
*
|
|
* @param {DOMElement|DOMTextNode} node
|
|
* @return {DOMElement|DOMTextNode}
|
|
*/
|
|
function getLeafNode(node) {
|
|
while (node && node.firstChild) {
|
|
node = node.firstChild;
|
|
}
|
|
return node;
|
|
}
|
|
|
|
/**
|
|
* Get the next sibling within a container. This will walk up the
|
|
* DOM if a node's siblings have been exhausted.
|
|
*
|
|
* @param {DOMElement|DOMTextNode} node
|
|
* @return {?DOMElement|DOMTextNode}
|
|
*/
|
|
function getSiblingNode(node) {
|
|
while (node) {
|
|
if (node.nextSibling) {
|
|
return node.nextSibling;
|
|
}
|
|
node = node.parentNode;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get object describing the nodes which contain characters at offset.
|
|
*
|
|
* @param {DOMElement|DOMTextNode} root
|
|
* @param {number} offset
|
|
* @return {?object}
|
|
*/
|
|
function getNodeForCharacterOffset(root, offset) {
|
|
var node = getLeafNode(root);
|
|
var nodeStart = 0;
|
|
var nodeEnd = 0;
|
|
|
|
while (node) {
|
|
if (node.nodeType === 3) {
|
|
nodeEnd = nodeStart + node.textContent.length;
|
|
|
|
if (nodeStart <= offset && nodeEnd >= offset) {
|
|
return {
|
|
node: node,
|
|
offset: offset - nodeStart
|
|
};
|
|
}
|
|
|
|
nodeStart = nodeEnd;
|
|
}
|
|
|
|
node = getLeafNode(getSiblingNode(node));
|
|
}
|
|
}
|
|
|
|
module.exports = getNodeForCharacterOffset;
|
|
|
|
},{}],179:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule getReactRootElementInContainer
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var DOC_NODE_TYPE = 9;
|
|
|
|
/**
|
|
* @param {DOMElement|DOMDocument} container DOM element that may contain
|
|
* a React component
|
|
* @return {?*} DOM element that may have the reactRoot ID, or null.
|
|
*/
|
|
function getReactRootElementInContainer(container) {
|
|
if (!container) {
|
|
return null;
|
|
}
|
|
|
|
if (container.nodeType === DOC_NODE_TYPE) {
|
|
return container.documentElement;
|
|
} else {
|
|
return container.firstChild;
|
|
}
|
|
}
|
|
|
|
module.exports = getReactRootElementInContainer;
|
|
|
|
},{}],180:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule getTextContentAccessor
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ExecutionEnvironment = require("./ExecutionEnvironment");
|
|
|
|
var contentKey = null;
|
|
|
|
/**
|
|
* Gets the key used to access text content on a DOM node.
|
|
*
|
|
* @return {?string} Key used to access text content.
|
|
* @internal
|
|
*/
|
|
function getTextContentAccessor() {
|
|
if (!contentKey && ExecutionEnvironment.canUseDOM) {
|
|
// Prefer textContent to innerText because many browsers support both but
|
|
// SVG <text> elements don't support innerText even when <div> does.
|
|
contentKey = 'textContent' in document.documentElement ?
|
|
'textContent' :
|
|
'innerText';
|
|
}
|
|
return contentKey;
|
|
}
|
|
|
|
module.exports = getTextContentAccessor;
|
|
|
|
},{"./ExecutionEnvironment":70}],181:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule getUnboundedScrollPosition
|
|
* @typechecks
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
/**
|
|
* Gets the scroll position of the supplied element or window.
|
|
*
|
|
* The return values are unbounded, unlike `getScrollPosition`. This means they
|
|
* may be negative or exceed the element boundaries (which is possible using
|
|
* inertial scrolling).
|
|
*
|
|
* @param {DOMWindow|DOMElement} scrollable
|
|
* @return {object} Map with `x` and `y` keys.
|
|
*/
|
|
function getUnboundedScrollPosition(scrollable) {
|
|
if (scrollable === window) {
|
|
return {
|
|
x: window.pageXOffset || document.documentElement.scrollLeft,
|
|
y: window.pageYOffset || document.documentElement.scrollTop
|
|
};
|
|
}
|
|
return {
|
|
x: scrollable.scrollLeft,
|
|
y: scrollable.scrollTop
|
|
};
|
|
}
|
|
|
|
module.exports = getUnboundedScrollPosition;
|
|
|
|
},{}],182:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule hyphenate
|
|
* @typechecks
|
|
*/
|
|
|
|
var _uppercasePattern = /([A-Z])/g;
|
|
|
|
/**
|
|
* Hyphenates a camelcased string, for example:
|
|
*
|
|
* > hyphenate('backgroundColor')
|
|
* < "background-color"
|
|
*
|
|
* For CSS style names, use `hyphenateStyleName` instead which works properly
|
|
* with all vendor prefixes, including `ms`.
|
|
*
|
|
* @param {string} string
|
|
* @return {string}
|
|
*/
|
|
function hyphenate(string) {
|
|
return string.replace(_uppercasePattern, '-$1').toLowerCase();
|
|
}
|
|
|
|
module.exports = hyphenate;
|
|
|
|
},{}],183:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule hyphenateStyleName
|
|
* @typechecks
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
var hyphenate = require("./hyphenate");
|
|
|
|
var msPattern = /^ms-/;
|
|
|
|
/**
|
|
* Hyphenates a camelcased CSS property name, for example:
|
|
*
|
|
* > hyphenateStyleName('backgroundColor')
|
|
* < "background-color"
|
|
* > hyphenateStyleName('MozTransition')
|
|
* < "-moz-transition"
|
|
* > hyphenateStyleName('msTransition')
|
|
* < "-ms-transition"
|
|
*
|
|
* As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
|
|
* is converted to `-ms-`.
|
|
*
|
|
* @param {string} string
|
|
* @return {string}
|
|
*/
|
|
function hyphenateStyleName(string) {
|
|
return hyphenate(string).replace(msPattern, '-ms-');
|
|
}
|
|
|
|
module.exports = hyphenateStyleName;
|
|
|
|
},{"./hyphenate":182}],184:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule instantiateReactComponent
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactCompositeComponent = require("./ReactCompositeComponent");
|
|
var ReactEmptyComponent = require("./ReactEmptyComponent");
|
|
var ReactNativeComponent = require("./ReactNativeComponent");
|
|
|
|
var assign = require("./Object.assign");
|
|
var invariant = require("./invariant");
|
|
var warning = require("./warning");
|
|
|
|
// To avoid a cyclic dependency, we create the final class in this module
|
|
var ReactCompositeComponentWrapper = function() { };
|
|
assign(
|
|
ReactCompositeComponentWrapper.prototype,
|
|
ReactCompositeComponent.Mixin,
|
|
{
|
|
_instantiateReactComponent: instantiateReactComponent
|
|
}
|
|
);
|
|
|
|
/**
|
|
* Check if the type reference is a known internal type. I.e. not a user
|
|
* provided composite type.
|
|
*
|
|
* @param {function} type
|
|
* @return {boolean} Returns true if this is a valid internal type.
|
|
*/
|
|
function isInternalComponentType(type) {
|
|
return (
|
|
typeof type === 'function' &&
|
|
typeof type.prototype !== 'undefined' &&
|
|
typeof type.prototype.mountComponent === 'function' &&
|
|
typeof type.prototype.receiveComponent === 'function'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Given a ReactNode, create an instance that will actually be mounted.
|
|
*
|
|
* @param {ReactNode} node
|
|
* @param {*} parentCompositeType The composite type that resolved this.
|
|
* @return {object} A new instance of the element's constructor.
|
|
* @protected
|
|
*/
|
|
function instantiateReactComponent(node, parentCompositeType) {
|
|
var instance;
|
|
|
|
if (node === null || node === false) {
|
|
node = ReactEmptyComponent.emptyElement;
|
|
}
|
|
|
|
if (typeof node === 'object') {
|
|
var element = node;
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
element && (typeof element.type === 'function' ||
|
|
typeof element.type === 'string'),
|
|
'Only functions or strings can be mounted as React components.'
|
|
) : null);
|
|
}
|
|
|
|
// Special case string values
|
|
if (parentCompositeType === element.type &&
|
|
typeof element.type === 'string') {
|
|
// Avoid recursion if the wrapper renders itself.
|
|
instance = ReactNativeComponent.createInternalComponent(element);
|
|
// All native components are currently wrapped in a composite so we're
|
|
// safe to assume that this is what we should instantiate.
|
|
} else if (isInternalComponentType(element.type)) {
|
|
// This is temporarily available for custom components that are not string
|
|
// represenations. I.e. ART. Once those are updated to use the string
|
|
// representation, we can drop this code path.
|
|
instance = new element.type(element);
|
|
} else {
|
|
instance = new ReactCompositeComponentWrapper();
|
|
}
|
|
} else if (typeof node === 'string' || typeof node === 'number') {
|
|
instance = ReactNativeComponent.createInstanceForText(node);
|
|
} else {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
false,
|
|
'Encountered invalid React node of type %s',
|
|
typeof node
|
|
) : invariant(false));
|
|
}
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
typeof instance.construct === 'function' &&
|
|
typeof instance.mountComponent === 'function' &&
|
|
typeof instance.receiveComponent === 'function' &&
|
|
typeof instance.unmountComponent === 'function',
|
|
'Only React Components can be mounted.'
|
|
) : null);
|
|
}
|
|
|
|
// Sets up the instance. This can probably just move into the constructor now.
|
|
instance.construct(node);
|
|
|
|
// These two fields are used by the DOM and ART diffing algorithms
|
|
// respectively. Instead of using expandos on components, we should be
|
|
// storing the state needed by the diffing algorithms elsewhere.
|
|
instance._mountIndex = 0;
|
|
instance._mountImage = null;
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
instance._isOwnerNecessary = false;
|
|
instance._warnedAboutRefsInRender = false;
|
|
}
|
|
|
|
// Internal instances should fully constructed at this point, so they should
|
|
// not get any new fields added to them at this point.
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
if (Object.preventExtensions) {
|
|
Object.preventExtensions(instance);
|
|
}
|
|
}
|
|
|
|
return instance;
|
|
}
|
|
|
|
module.exports = instantiateReactComponent;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./Object.assign":76,"./ReactCompositeComponent":87,"./ReactEmptyComponent":109,"./ReactNativeComponent":123,"./invariant":185,"./warning":204,"_process":1}],185:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule invariant
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
/**
|
|
* Use invariant() to assert state which your program assumes to be true.
|
|
*
|
|
* Provide sprintf-style format (only %s is supported) and arguments
|
|
* to provide information about what broke and what you were
|
|
* expecting.
|
|
*
|
|
* The invariant message will be stripped in production, but the invariant
|
|
* will remain to ensure logic does not differ in production.
|
|
*/
|
|
|
|
var invariant = function(condition, format, a, b, c, d, e, f) {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
if (format === undefined) {
|
|
throw new Error('invariant requires an error message argument');
|
|
}
|
|
}
|
|
|
|
if (!condition) {
|
|
var error;
|
|
if (format === undefined) {
|
|
error = new Error(
|
|
'Minified exception occurred; use the non-minified dev environment ' +
|
|
'for the full error message and additional helpful warnings.'
|
|
);
|
|
} else {
|
|
var args = [a, b, c, d, e, f];
|
|
var argIndex = 0;
|
|
error = new Error(
|
|
'Invariant Violation: ' +
|
|
format.replace(/%s/g, function() { return args[argIndex++]; })
|
|
);
|
|
}
|
|
|
|
error.framesToPop = 1; // we don't care about invariant's own frame
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
module.exports = invariant;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"_process":1}],186:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule isEventSupported
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ExecutionEnvironment = require("./ExecutionEnvironment");
|
|
|
|
var useHasFeature;
|
|
if (ExecutionEnvironment.canUseDOM) {
|
|
useHasFeature =
|
|
document.implementation &&
|
|
document.implementation.hasFeature &&
|
|
// always returns true in newer browsers as per the standard.
|
|
// @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature
|
|
document.implementation.hasFeature('', '') !== true;
|
|
}
|
|
|
|
/**
|
|
* Checks if an event is supported in the current execution environment.
|
|
*
|
|
* NOTE: This will not work correctly for non-generic events such as `change`,
|
|
* `reset`, `load`, `error`, and `select`.
|
|
*
|
|
* Borrows from Modernizr.
|
|
*
|
|
* @param {string} eventNameSuffix Event name, e.g. "click".
|
|
* @param {?boolean} capture Check if the capture phase is supported.
|
|
* @return {boolean} True if the event is supported.
|
|
* @internal
|
|
* @license Modernizr 3.0.0pre (Custom Build) | MIT
|
|
*/
|
|
function isEventSupported(eventNameSuffix, capture) {
|
|
if (!ExecutionEnvironment.canUseDOM ||
|
|
capture && !('addEventListener' in document)) {
|
|
return false;
|
|
}
|
|
|
|
var eventName = 'on' + eventNameSuffix;
|
|
var isSupported = eventName in document;
|
|
|
|
if (!isSupported) {
|
|
var element = document.createElement('div');
|
|
element.setAttribute(eventName, 'return;');
|
|
isSupported = typeof element[eventName] === 'function';
|
|
}
|
|
|
|
if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') {
|
|
// This is the only way to test support for the `wheel` event in IE9+.
|
|
isSupported = document.implementation.hasFeature('Events.wheel', '3.0');
|
|
}
|
|
|
|
return isSupported;
|
|
}
|
|
|
|
module.exports = isEventSupported;
|
|
|
|
},{"./ExecutionEnvironment":70}],187:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule isNode
|
|
* @typechecks
|
|
*/
|
|
|
|
/**
|
|
* @param {*} object The object to check.
|
|
* @return {boolean} Whether or not the object is a DOM node.
|
|
*/
|
|
function isNode(object) {
|
|
return !!(object && (
|
|
((typeof Node === 'function' ? object instanceof Node : typeof object === 'object' &&
|
|
typeof object.nodeType === 'number' &&
|
|
typeof object.nodeName === 'string'))
|
|
));
|
|
}
|
|
|
|
module.exports = isNode;
|
|
|
|
},{}],188:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule isTextInputElement
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
|
|
*/
|
|
var supportedInputTypes = {
|
|
'color': true,
|
|
'date': true,
|
|
'datetime': true,
|
|
'datetime-local': true,
|
|
'email': true,
|
|
'month': true,
|
|
'number': true,
|
|
'password': true,
|
|
'range': true,
|
|
'search': true,
|
|
'tel': true,
|
|
'text': true,
|
|
'time': true,
|
|
'url': true,
|
|
'week': true
|
|
};
|
|
|
|
function isTextInputElement(elem) {
|
|
return elem && (
|
|
(elem.nodeName === 'INPUT' && supportedInputTypes[elem.type] || elem.nodeName === 'TEXTAREA')
|
|
);
|
|
}
|
|
|
|
module.exports = isTextInputElement;
|
|
|
|
},{}],189:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule isTextNode
|
|
* @typechecks
|
|
*/
|
|
|
|
var isNode = require("./isNode");
|
|
|
|
/**
|
|
* @param {*} object The object to check.
|
|
* @return {boolean} Whether or not the object is a DOM text node.
|
|
*/
|
|
function isTextNode(object) {
|
|
return isNode(object) && object.nodeType == 3;
|
|
}
|
|
|
|
module.exports = isTextNode;
|
|
|
|
},{"./isNode":187}],190:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule keyMirror
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var invariant = require("./invariant");
|
|
|
|
/**
|
|
* Constructs an enumeration with keys equal to their value.
|
|
*
|
|
* For example:
|
|
*
|
|
* var COLORS = keyMirror({blue: null, red: null});
|
|
* var myColor = COLORS.blue;
|
|
* var isColorValid = !!COLORS[myColor];
|
|
*
|
|
* The last line could not be performed if the values of the generated enum were
|
|
* not equal to their keys.
|
|
*
|
|
* Input: {key1: val1, key2: val2}
|
|
* Output: {key1: key1, key2: key2}
|
|
*
|
|
* @param {object} obj
|
|
* @return {object}
|
|
*/
|
|
var keyMirror = function(obj) {
|
|
var ret = {};
|
|
var key;
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
obj instanceof Object && !Array.isArray(obj),
|
|
'keyMirror(...): Argument must be an object.'
|
|
) : invariant(obj instanceof Object && !Array.isArray(obj)));
|
|
for (key in obj) {
|
|
if (!obj.hasOwnProperty(key)) {
|
|
continue;
|
|
}
|
|
ret[key] = key;
|
|
}
|
|
return ret;
|
|
};
|
|
|
|
module.exports = keyMirror;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./invariant":185,"_process":1}],191:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule keyOf
|
|
*/
|
|
|
|
/**
|
|
* Allows extraction of a minified key. Let's the build system minify keys
|
|
* without loosing the ability to dynamically use key strings as values
|
|
* themselves. Pass in an object with a single key/val pair and it will return
|
|
* you the string key of that single record. Suppose you want to grab the
|
|
* value for a key 'className' inside of an object. Key/val minification may
|
|
* have aliased that key to be 'xa12'. keyOf({className: null}) will return
|
|
* 'xa12' in that case. Resolve keys you want to use once at startup time, then
|
|
* reuse those resolutions.
|
|
*/
|
|
var keyOf = function(oneKeyObj) {
|
|
var key;
|
|
for (key in oneKeyObj) {
|
|
if (!oneKeyObj.hasOwnProperty(key)) {
|
|
continue;
|
|
}
|
|
return key;
|
|
}
|
|
return null;
|
|
};
|
|
|
|
|
|
module.exports = keyOf;
|
|
|
|
},{}],192:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule mapObject
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
|
|
/**
|
|
* Executes the provided `callback` once for each enumerable own property in the
|
|
* object and constructs a new object from the results. The `callback` is
|
|
* invoked with three arguments:
|
|
*
|
|
* - the property value
|
|
* - the property name
|
|
* - the object being traversed
|
|
*
|
|
* Properties that are added after the call to `mapObject` will not be visited
|
|
* by `callback`. If the values of existing properties are changed, the value
|
|
* passed to `callback` will be the value at the time `mapObject` visits them.
|
|
* Properties that are deleted before being visited are not visited.
|
|
*
|
|
* @grep function objectMap()
|
|
* @grep function objMap()
|
|
*
|
|
* @param {?object} object
|
|
* @param {function} callback
|
|
* @param {*} context
|
|
* @return {?object}
|
|
*/
|
|
function mapObject(object, callback, context) {
|
|
if (!object) {
|
|
return null;
|
|
}
|
|
var result = {};
|
|
for (var name in object) {
|
|
if (hasOwnProperty.call(object, name)) {
|
|
result[name] = callback.call(context, object[name], name, object);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
module.exports = mapObject;
|
|
|
|
},{}],193:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule memoizeStringOnly
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* Memoizes the return value of a function that accepts one string argument.
|
|
*
|
|
* @param {function} callback
|
|
* @return {function}
|
|
*/
|
|
function memoizeStringOnly(callback) {
|
|
var cache = {};
|
|
return function(string) {
|
|
if (!cache.hasOwnProperty(string)) {
|
|
cache[string] = callback.call(this, string);
|
|
}
|
|
return cache[string];
|
|
};
|
|
}
|
|
|
|
module.exports = memoizeStringOnly;
|
|
|
|
},{}],194:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule onlyChild
|
|
*/
|
|
'use strict';
|
|
|
|
var ReactElement = require("./ReactElement");
|
|
|
|
var invariant = require("./invariant");
|
|
|
|
/**
|
|
* Returns the first child in a collection of children and verifies that there
|
|
* is only one child in the collection. The current implementation of this
|
|
* function assumes that a single child gets passed without a wrapper, but the
|
|
* purpose of this helper function is to abstract away the particular structure
|
|
* of children.
|
|
*
|
|
* @param {?object} children Child collection structure.
|
|
* @return {ReactComponent} The first and only `ReactComponent` contained in the
|
|
* structure.
|
|
*/
|
|
function onlyChild(children) {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
ReactElement.isValidElement(children),
|
|
'onlyChild must be passed a children with exactly one child.'
|
|
) : invariant(ReactElement.isValidElement(children)));
|
|
return children;
|
|
}
|
|
|
|
module.exports = onlyChild;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./ReactElement":107,"./invariant":185,"_process":1}],195:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule performance
|
|
* @typechecks
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
var ExecutionEnvironment = require("./ExecutionEnvironment");
|
|
|
|
var performance;
|
|
|
|
if (ExecutionEnvironment.canUseDOM) {
|
|
performance =
|
|
window.performance ||
|
|
window.msPerformance ||
|
|
window.webkitPerformance;
|
|
}
|
|
|
|
module.exports = performance || {};
|
|
|
|
},{"./ExecutionEnvironment":70}],196:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule performanceNow
|
|
* @typechecks
|
|
*/
|
|
|
|
var performance = require("./performance");
|
|
|
|
/**
|
|
* Detect if we can use `window.performance.now()` and gracefully fallback to
|
|
* `Date.now()` if it doesn't exist. We need to support Firefox < 15 for now
|
|
* because of Facebook's testing infrastructure.
|
|
*/
|
|
if (!performance || !performance.now) {
|
|
performance = Date;
|
|
}
|
|
|
|
var performanceNow = performance.now.bind(performance);
|
|
|
|
module.exports = performanceNow;
|
|
|
|
},{"./performance":195}],197:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule quoteAttributeValueForBrowser
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var escapeTextContentForBrowser = require("./escapeTextContentForBrowser");
|
|
|
|
/**
|
|
* Escapes attribute value to prevent scripting attacks.
|
|
*
|
|
* @param {*} value Value to escape.
|
|
* @return {string} An escaped string.
|
|
*/
|
|
function quoteAttributeValueForBrowser(value) {
|
|
return '"' + escapeTextContentForBrowser(value) + '"';
|
|
}
|
|
|
|
module.exports = quoteAttributeValueForBrowser;
|
|
|
|
},{"./escapeTextContentForBrowser":166}],198:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule setInnerHTML
|
|
*/
|
|
|
|
/* globals MSApp */
|
|
|
|
'use strict';
|
|
|
|
var ExecutionEnvironment = require("./ExecutionEnvironment");
|
|
|
|
var WHITESPACE_TEST = /^[ \r\n\t\f]/;
|
|
var NONVISIBLE_TEST = /<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/;
|
|
|
|
/**
|
|
* Set the innerHTML property of a node, ensuring that whitespace is preserved
|
|
* even in IE8.
|
|
*
|
|
* @param {DOMElement} node
|
|
* @param {string} html
|
|
* @internal
|
|
*/
|
|
var setInnerHTML = function(node, html) {
|
|
node.innerHTML = html;
|
|
};
|
|
|
|
// Win8 apps: Allow all html to be inserted
|
|
if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
|
|
setInnerHTML = function(node, html) {
|
|
MSApp.execUnsafeLocalFunction(function() {
|
|
node.innerHTML = html;
|
|
});
|
|
};
|
|
}
|
|
|
|
if (ExecutionEnvironment.canUseDOM) {
|
|
// IE8: When updating a just created node with innerHTML only leading
|
|
// whitespace is removed. When updating an existing node with innerHTML
|
|
// whitespace in root TextNodes is also collapsed.
|
|
// @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html
|
|
|
|
// Feature detection; only IE8 is known to behave improperly like this.
|
|
var testElement = document.createElement('div');
|
|
testElement.innerHTML = ' ';
|
|
if (testElement.innerHTML === '') {
|
|
setInnerHTML = function(node, html) {
|
|
// Magic theory: IE8 supposedly differentiates between added and updated
|
|
// nodes when processing innerHTML, innerHTML on updated nodes suffers
|
|
// from worse whitespace behavior. Re-adding a node like this triggers
|
|
// the initial and more favorable whitespace behavior.
|
|
// TODO: What to do on a detached node?
|
|
if (node.parentNode) {
|
|
node.parentNode.replaceChild(node, node);
|
|
}
|
|
|
|
// We also implement a workaround for non-visible tags disappearing into
|
|
// thin air on IE8, this only happens if there is no visible text
|
|
// in-front of the non-visible tags. Piggyback on the whitespace fix
|
|
// and simply check if any non-visible tags appear in the source.
|
|
if (WHITESPACE_TEST.test(html) ||
|
|
html[0] === '<' && NONVISIBLE_TEST.test(html)) {
|
|
// Recover leading whitespace by temporarily prepending any character.
|
|
// \uFEFF has the potential advantage of being zero-width/invisible.
|
|
node.innerHTML = '\uFEFF' + html;
|
|
|
|
// deleteData leaves an empty `TextNode` which offsets the index of all
|
|
// children. Definitely want to avoid this.
|
|
var textNode = node.firstChild;
|
|
if (textNode.data.length === 1) {
|
|
node.removeChild(textNode);
|
|
} else {
|
|
textNode.deleteData(0, 1);
|
|
}
|
|
} else {
|
|
node.innerHTML = html;
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
module.exports = setInnerHTML;
|
|
|
|
},{"./ExecutionEnvironment":70}],199:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule setTextContent
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ExecutionEnvironment = require("./ExecutionEnvironment");
|
|
var escapeTextContentForBrowser = require("./escapeTextContentForBrowser");
|
|
var setInnerHTML = require("./setInnerHTML");
|
|
|
|
/**
|
|
* Set the textContent property of a node, ensuring that whitespace is preserved
|
|
* even in IE8. innerText is a poor substitute for textContent and, among many
|
|
* issues, inserts <br> instead of the literal newline chars. innerHTML behaves
|
|
* as it should.
|
|
*
|
|
* @param {DOMElement} node
|
|
* @param {string} text
|
|
* @internal
|
|
*/
|
|
var setTextContent = function(node, text) {
|
|
node.textContent = text;
|
|
};
|
|
|
|
if (ExecutionEnvironment.canUseDOM) {
|
|
if (!('textContent' in document.documentElement)) {
|
|
setTextContent = function(node, text) {
|
|
setInnerHTML(node, escapeTextContentForBrowser(text));
|
|
};
|
|
}
|
|
}
|
|
|
|
module.exports = setTextContent;
|
|
|
|
},{"./ExecutionEnvironment":70,"./escapeTextContentForBrowser":166,"./setInnerHTML":198}],200:[function(require,module,exports){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule shallowEqual
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* Performs equality by iterating through keys on an object and returning
|
|
* false when any key has values which are not strictly equal between
|
|
* objA and objB. Returns true when the values of all keys are strictly equal.
|
|
*
|
|
* @return {boolean}
|
|
*/
|
|
function shallowEqual(objA, objB) {
|
|
if (objA === objB) {
|
|
return true;
|
|
}
|
|
var key;
|
|
// Test for A's keys different from B.
|
|
for (key in objA) {
|
|
if (objA.hasOwnProperty(key) &&
|
|
(!objB.hasOwnProperty(key) || objA[key] !== objB[key])) {
|
|
return false;
|
|
}
|
|
}
|
|
// Test for B's keys missing from A.
|
|
for (key in objB) {
|
|
if (objB.hasOwnProperty(key) && !objA.hasOwnProperty(key)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
module.exports = shallowEqual;
|
|
|
|
},{}],201:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule shouldUpdateReactComponent
|
|
* @typechecks static-only
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var warning = require("./warning");
|
|
|
|
/**
|
|
* Given a `prevElement` and `nextElement`, determines if the existing
|
|
* instance should be updated as opposed to being destroyed or replaced by a new
|
|
* instance. Both arguments are elements. This ensures that this logic can
|
|
* operate on stateless trees without any backing instance.
|
|
*
|
|
* @param {?object} prevElement
|
|
* @param {?object} nextElement
|
|
* @return {boolean} True if the existing instance should be updated.
|
|
* @protected
|
|
*/
|
|
function shouldUpdateReactComponent(prevElement, nextElement) {
|
|
if (prevElement != null && nextElement != null) {
|
|
var prevType = typeof prevElement;
|
|
var nextType = typeof nextElement;
|
|
if (prevType === 'string' || prevType === 'number') {
|
|
return (nextType === 'string' || nextType === 'number');
|
|
} else {
|
|
if (nextType === 'object' &&
|
|
prevElement.type === nextElement.type &&
|
|
prevElement.key === nextElement.key) {
|
|
var ownersMatch = prevElement._owner === nextElement._owner;
|
|
var prevName = null;
|
|
var nextName = null;
|
|
var nextDisplayName = null;
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
if (!ownersMatch) {
|
|
if (prevElement._owner != null &&
|
|
prevElement._owner.getPublicInstance() != null &&
|
|
prevElement._owner.getPublicInstance().constructor != null) {
|
|
prevName =
|
|
prevElement._owner.getPublicInstance().constructor.displayName;
|
|
}
|
|
if (nextElement._owner != null &&
|
|
nextElement._owner.getPublicInstance() != null &&
|
|
nextElement._owner.getPublicInstance().constructor != null) {
|
|
nextName =
|
|
nextElement._owner.getPublicInstance().constructor.displayName;
|
|
}
|
|
if (nextElement.type != null &&
|
|
nextElement.type.displayName != null) {
|
|
nextDisplayName = nextElement.type.displayName;
|
|
}
|
|
if (nextElement.type != null && typeof nextElement.type === 'string') {
|
|
nextDisplayName = nextElement.type;
|
|
}
|
|
if (typeof nextElement.type !== 'string' ||
|
|
nextElement.type === 'input' ||
|
|
nextElement.type === 'textarea') {
|
|
if ((prevElement._owner != null &&
|
|
prevElement._owner._isOwnerNecessary === false) ||
|
|
(nextElement._owner != null &&
|
|
nextElement._owner._isOwnerNecessary === false)) {
|
|
if (prevElement._owner != null) {
|
|
prevElement._owner._isOwnerNecessary = true;
|
|
}
|
|
if (nextElement._owner != null) {
|
|
nextElement._owner._isOwnerNecessary = true;
|
|
}
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
false,
|
|
'<%s /> is being rendered by both %s and %s using the same ' +
|
|
'key (%s) in the same place. Currently, this means that ' +
|
|
'they don\'t preserve state. This behavior should be very ' +
|
|
'rare so we\'re considering deprecating it. Please contact ' +
|
|
'the React team and explain your use case so that we can ' +
|
|
'take that into consideration.',
|
|
nextDisplayName || 'Unknown Component',
|
|
prevName || '[Unknown]',
|
|
nextName || '[Unknown]',
|
|
prevElement.key
|
|
) : null);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ownersMatch;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
module.exports = shouldUpdateReactComponent;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./warning":204,"_process":1}],202:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2014-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule toArray
|
|
* @typechecks
|
|
*/
|
|
|
|
var invariant = require("./invariant");
|
|
|
|
/**
|
|
* Convert array-like objects to arrays.
|
|
*
|
|
* This API assumes the caller knows the contents of the data type. For less
|
|
* well defined inputs use createArrayFromMixed.
|
|
*
|
|
* @param {object|function|filelist} obj
|
|
* @return {array}
|
|
*/
|
|
function toArray(obj) {
|
|
var length = obj.length;
|
|
|
|
// Some browse builtin objects can report typeof 'function' (e.g. NodeList in
|
|
// old versions of Safari).
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
!Array.isArray(obj) &&
|
|
(typeof obj === 'object' || typeof obj === 'function'),
|
|
'toArray: Array-like object expected'
|
|
) : invariant(!Array.isArray(obj) &&
|
|
(typeof obj === 'object' || typeof obj === 'function')));
|
|
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
typeof length === 'number',
|
|
'toArray: Object needs a length property'
|
|
) : invariant(typeof length === 'number'));
|
|
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
length === 0 ||
|
|
(length - 1) in obj,
|
|
'toArray: Object should have keys for indices'
|
|
) : invariant(length === 0 ||
|
|
(length - 1) in obj));
|
|
|
|
// Old IE doesn't give collections access to hasOwnProperty. Assume inputs
|
|
// without method will throw during the slice call and skip straight to the
|
|
// fallback.
|
|
if (obj.hasOwnProperty) {
|
|
try {
|
|
return Array.prototype.slice.call(obj);
|
|
} catch (e) {
|
|
// IE < 9 does not support Array#slice on collections objects
|
|
}
|
|
}
|
|
|
|
// Fall back to copying key by key. This assumes all keys have a value,
|
|
// so will not preserve sparsely populated inputs.
|
|
var ret = Array(length);
|
|
for (var ii = 0; ii < length; ii++) {
|
|
ret[ii] = obj[ii];
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
module.exports = toArray;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./invariant":185,"_process":1}],203:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2013-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule traverseAllChildren
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ReactElement = require("./ReactElement");
|
|
var ReactFragment = require("./ReactFragment");
|
|
var ReactInstanceHandles = require("./ReactInstanceHandles");
|
|
|
|
var getIteratorFn = require("./getIteratorFn");
|
|
var invariant = require("./invariant");
|
|
var warning = require("./warning");
|
|
|
|
var SEPARATOR = ReactInstanceHandles.SEPARATOR;
|
|
var SUBSEPARATOR = ':';
|
|
|
|
/**
|
|
* TODO: Test that a single child and an array with one item have the same key
|
|
* pattern.
|
|
*/
|
|
|
|
var userProvidedKeyEscaperLookup = {
|
|
'=': '=0',
|
|
'.': '=1',
|
|
':': '=2'
|
|
};
|
|
|
|
var userProvidedKeyEscapeRegex = /[=.:]/g;
|
|
|
|
var didWarnAboutMaps = false;
|
|
|
|
function userProvidedKeyEscaper(match) {
|
|
return userProvidedKeyEscaperLookup[match];
|
|
}
|
|
|
|
/**
|
|
* Generate a key string that identifies a component within a set.
|
|
*
|
|
* @param {*} component A component that could contain a manual key.
|
|
* @param {number} index Index that is used if a manual key is not provided.
|
|
* @return {string}
|
|
*/
|
|
function getComponentKey(component, index) {
|
|
if (component && component.key != null) {
|
|
// Explicit key
|
|
return wrapUserProvidedKey(component.key);
|
|
}
|
|
// Implicit key determined by the index in the set
|
|
return index.toString(36);
|
|
}
|
|
|
|
/**
|
|
* Escape a component key so that it is safe to use in a reactid.
|
|
*
|
|
* @param {*} key Component key to be escaped.
|
|
* @return {string} An escaped string.
|
|
*/
|
|
function escapeUserProvidedKey(text) {
|
|
return ('' + text).replace(
|
|
userProvidedKeyEscapeRegex,
|
|
userProvidedKeyEscaper
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Wrap a `key` value explicitly provided by the user to distinguish it from
|
|
* implicitly-generated keys generated by a component's index in its parent.
|
|
*
|
|
* @param {string} key Value of a user-provided `key` attribute
|
|
* @return {string}
|
|
*/
|
|
function wrapUserProvidedKey(key) {
|
|
return '$' + escapeUserProvidedKey(key);
|
|
}
|
|
|
|
/**
|
|
* @param {?*} children Children tree container.
|
|
* @param {!string} nameSoFar Name of the key path so far.
|
|
* @param {!number} indexSoFar Number of children encountered until this point.
|
|
* @param {!function} callback Callback to invoke with each child found.
|
|
* @param {?*} traverseContext Used to pass information throughout the traversal
|
|
* process.
|
|
* @return {!number} The number of children in this subtree.
|
|
*/
|
|
function traverseAllChildrenImpl(
|
|
children,
|
|
nameSoFar,
|
|
indexSoFar,
|
|
callback,
|
|
traverseContext
|
|
) {
|
|
var type = typeof children;
|
|
|
|
if (type === 'undefined' || type === 'boolean') {
|
|
// All of the above are perceived as null.
|
|
children = null;
|
|
}
|
|
|
|
if (children === null ||
|
|
type === 'string' ||
|
|
type === 'number' ||
|
|
ReactElement.isValidElement(children)) {
|
|
callback(
|
|
traverseContext,
|
|
children,
|
|
// If it's the only child, treat the name as if it was wrapped in an array
|
|
// so that it's consistent if the number of children grows.
|
|
nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar,
|
|
indexSoFar
|
|
);
|
|
return 1;
|
|
}
|
|
|
|
var child, nextName, nextIndex;
|
|
var subtreeCount = 0; // Count of children found in the current subtree.
|
|
|
|
if (Array.isArray(children)) {
|
|
for (var i = 0; i < children.length; i++) {
|
|
child = children[i];
|
|
nextName = (
|
|
(nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) +
|
|
getComponentKey(child, i)
|
|
);
|
|
nextIndex = indexSoFar + subtreeCount;
|
|
subtreeCount += traverseAllChildrenImpl(
|
|
child,
|
|
nextName,
|
|
nextIndex,
|
|
callback,
|
|
traverseContext
|
|
);
|
|
}
|
|
} else {
|
|
var iteratorFn = getIteratorFn(children);
|
|
if (iteratorFn) {
|
|
var iterator = iteratorFn.call(children);
|
|
var step;
|
|
if (iteratorFn !== children.entries) {
|
|
var ii = 0;
|
|
while (!(step = iterator.next()).done) {
|
|
child = step.value;
|
|
nextName = (
|
|
(nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) +
|
|
getComponentKey(child, ii++)
|
|
);
|
|
nextIndex = indexSoFar + subtreeCount;
|
|
subtreeCount += traverseAllChildrenImpl(
|
|
child,
|
|
nextName,
|
|
nextIndex,
|
|
callback,
|
|
traverseContext
|
|
);
|
|
}
|
|
} else {
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
("production" !== process.env.NODE_ENV ? warning(
|
|
didWarnAboutMaps,
|
|
'Using Maps as children is not yet fully supported. It is an ' +
|
|
'experimental feature that might be removed. Convert it to a ' +
|
|
'sequence / iterable of keyed ReactElements instead.'
|
|
) : null);
|
|
didWarnAboutMaps = true;
|
|
}
|
|
// Iterator will provide entry [k,v] tuples rather than values.
|
|
while (!(step = iterator.next()).done) {
|
|
var entry = step.value;
|
|
if (entry) {
|
|
child = entry[1];
|
|
nextName = (
|
|
(nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) +
|
|
wrapUserProvidedKey(entry[0]) + SUBSEPARATOR +
|
|
getComponentKey(child, 0)
|
|
);
|
|
nextIndex = indexSoFar + subtreeCount;
|
|
subtreeCount += traverseAllChildrenImpl(
|
|
child,
|
|
nextName,
|
|
nextIndex,
|
|
callback,
|
|
traverseContext
|
|
);
|
|
}
|
|
}
|
|
}
|
|
} else if (type === 'object') {
|
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
children.nodeType !== 1,
|
|
'traverseAllChildren(...): Encountered an invalid child; DOM ' +
|
|
'elements are not valid children of React components.'
|
|
) : invariant(children.nodeType !== 1));
|
|
var fragment = ReactFragment.extract(children);
|
|
for (var key in fragment) {
|
|
if (fragment.hasOwnProperty(key)) {
|
|
child = fragment[key];
|
|
nextName = (
|
|
(nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) +
|
|
wrapUserProvidedKey(key) + SUBSEPARATOR +
|
|
getComponentKey(child, 0)
|
|
);
|
|
nextIndex = indexSoFar + subtreeCount;
|
|
subtreeCount += traverseAllChildrenImpl(
|
|
child,
|
|
nextName,
|
|
nextIndex,
|
|
callback,
|
|
traverseContext
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return subtreeCount;
|
|
}
|
|
|
|
/**
|
|
* Traverses children that are typically specified as `props.children`, but
|
|
* might also be specified through attributes:
|
|
*
|
|
* - `traverseAllChildren(this.props.children, ...)`
|
|
* - `traverseAllChildren(this.props.leftPanelChildren, ...)`
|
|
*
|
|
* The `traverseContext` is an optional argument that is passed through the
|
|
* entire traversal. It can be used to store accumulations or anything else that
|
|
* the callback might find relevant.
|
|
*
|
|
* @param {?*} children Children tree object.
|
|
* @param {!function} callback To invoke upon traversing each child.
|
|
* @param {?*} traverseContext Context for traversal.
|
|
* @return {!number} The number of children in this subtree.
|
|
*/
|
|
function traverseAllChildren(children, callback, traverseContext) {
|
|
if (children == null) {
|
|
return 0;
|
|
}
|
|
|
|
return traverseAllChildrenImpl(children, '', 0, callback, traverseContext);
|
|
}
|
|
|
|
module.exports = traverseAllChildren;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./ReactElement":107,"./ReactFragment":113,"./ReactInstanceHandles":116,"./getIteratorFn":176,"./invariant":185,"./warning":204,"_process":1}],204:[function(require,module,exports){
|
|
(function (process){
|
|
/**
|
|
* Copyright 2014-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule warning
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
var emptyFunction = require("./emptyFunction");
|
|
|
|
/**
|
|
* Similar to invariant but only logs a warning if the condition is not met.
|
|
* This can be used to log issues in development environments in critical
|
|
* paths. Removing the logging code for production environments will keep the
|
|
* same logic and follow the same code paths.
|
|
*/
|
|
|
|
var warning = emptyFunction;
|
|
|
|
if ("production" !== process.env.NODE_ENV) {
|
|
warning = function(condition, format ) {for (var args=[],$__0=2,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]);
|
|
if (format === undefined) {
|
|
throw new Error(
|
|
'`warning(condition, format, ...args)` requires a warning ' +
|
|
'message argument'
|
|
);
|
|
}
|
|
|
|
if (format.length < 10 || /^[s\W]*$/.test(format)) {
|
|
throw new Error(
|
|
'The warning format should be able to uniquely identify this ' +
|
|
'warning. Please, use a more descriptive format than: ' + format
|
|
);
|
|
}
|
|
|
|
if (format.indexOf('Failed Composite propType: ') === 0) {
|
|
return; // Ignore CompositeComponent proptype check.
|
|
}
|
|
|
|
if (!condition) {
|
|
var argIndex = 0;
|
|
var message = 'Warning: ' + format.replace(/%s/g, function() {return args[argIndex++];});
|
|
console.warn(message);
|
|
try {
|
|
// --- Welcome to debugging React ---
|
|
// This error was thrown as a convenience so that you can use this stack
|
|
// to find the callsite that caused this warning to fire.
|
|
throw new Error(message);
|
|
} catch(x) {}
|
|
}
|
|
};
|
|
}
|
|
|
|
module.exports = warning;
|
|
|
|
}).call(this,require('_process'))
|
|
},{"./emptyFunction":164,"_process":1}],205:[function(require,module,exports){
|
|
module.exports = require('./lib/React');
|
|
|
|
},{"./lib/React":78}],206:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
exports.__esModule = true;
|
|
exports['default'] = createStore;
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _utilsIsPlainObject = require('./utils/isPlainObject');
|
|
|
|
var _utilsIsPlainObject2 = _interopRequireDefault(_utilsIsPlainObject);
|
|
|
|
/**
|
|
* These are private action types reserved by Redux.
|
|
* For any unknown actions, you must return the current state.
|
|
* If the current state is undefined, you must return the initial state.
|
|
* Do not reference these action types directly in your code.
|
|
*/
|
|
var ActionTypes = {
|
|
INIT: '@@redux/INIT'
|
|
};
|
|
|
|
exports.ActionTypes = ActionTypes;
|
|
/**
|
|
* Creates a Redux store that holds the state tree.
|
|
* The only way to change the data in the store is to call `dispatch()` on it.
|
|
*
|
|
* There should only be a single store in your app. To specify how different
|
|
* parts of the state tree respond to actions, you may combine several reducers
|
|
* into a single reducer function by using `combineReducers`.
|
|
*
|
|
* @param {Function} reducer A function that returns the next state tree, given
|
|
* the current state tree and the action to handle.
|
|
*
|
|
* @param {any} [initialState] The initial state. You may optionally specify it
|
|
* to hydrate the state from the server in universal apps, or to restore a
|
|
* previously serialized user session.
|
|
* If you use `combineReducers` to produce the root reducer function, this must be
|
|
* an object with the same shape as `combineReducers` keys.
|
|
*
|
|
* @returns {Store} A Redux store that lets you read the state, dispatch actions
|
|
* and subscribe to changes.
|
|
*/
|
|
|
|
function createStore(reducer, initialState) {
|
|
if (typeof reducer !== 'function') {
|
|
throw new Error('Expected the reducer to be a function.');
|
|
}
|
|
|
|
var currentReducer = reducer;
|
|
var currentState = initialState;
|
|
var listeners = [];
|
|
var isDispatching = false;
|
|
|
|
/**
|
|
* Reads the state tree managed by the store.
|
|
*
|
|
* @returns {any} The current state tree of your application.
|
|
*/
|
|
function getState() {
|
|
return currentState;
|
|
}
|
|
|
|
/**
|
|
* Adds a change listener. It will be called any time an action is dispatched,
|
|
* and some part of the state tree may potentially have changed. You may then
|
|
* call `getState()` to read the current state tree inside the callback.
|
|
*
|
|
* @param {Function} listener A callback to be invoked on every dispatch.
|
|
* @returns {Function} A function to remove this change listener.
|
|
*/
|
|
function subscribe(listener) {
|
|
listeners.push(listener);
|
|
|
|
return function unsubscribe() {
|
|
var index = listeners.indexOf(listener);
|
|
listeners.splice(index, 1);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Dispatches an action. It is the only way to trigger a state change.
|
|
*
|
|
* The `reducer` function, used to create the store, will be called with the
|
|
* current state tree and the given `action`. Its return value will
|
|
* be considered the **next** state of the tree, and the change listeners
|
|
* will be notified.
|
|
*
|
|
* The base implementation only supports plain object actions. If you want to
|
|
* dispatch a Promise, an Observable, a thunk, or something else, you need to
|
|
* wrap your store creating function into the corresponding middleware. For
|
|
* example, see the documentation for the `redux-thunk` package. Even the
|
|
* middleware will eventually dispatch plain object actions using this method.
|
|
*
|
|
* @param {Object} action A plain object representing “what changed”. It is
|
|
* a good idea to keep actions serializable so you can record and replay user
|
|
* sessions, or use the time travelling `redux-devtools`.
|
|
*
|
|
* @returns {Object} For convenience, the same action object you dispatched.
|
|
*
|
|
* Note that, if you use a custom middleware, it may wrap `dispatch()` to
|
|
* return something else (for example, a Promise you can await).
|
|
*/
|
|
function dispatch(action) {
|
|
if (!_utilsIsPlainObject2['default'](action)) {
|
|
throw new Error('Actions must be plain objects. Use custom middleware for async actions.');
|
|
}
|
|
|
|
if (isDispatching) {
|
|
throw new Error('Reducers may not dispatch actions.');
|
|
}
|
|
|
|
try {
|
|
isDispatching = true;
|
|
currentState = currentReducer(currentState, action);
|
|
} finally {
|
|
isDispatching = false;
|
|
}
|
|
|
|
listeners.slice().forEach(function (listener) {
|
|
return listener();
|
|
});
|
|
return action;
|
|
}
|
|
|
|
/**
|
|
* Returns the reducer currently used by the store to calculate the state.
|
|
*
|
|
* It is likely that you will only need this function if you implement a hot
|
|
* reloading mechanism for Redux.
|
|
*
|
|
* @returns {Function} The reducer used by the current store.
|
|
*/
|
|
function getReducer() {
|
|
return currentReducer;
|
|
}
|
|
|
|
/**
|
|
* Replaces the reducer currently used by the store to calculate the state.
|
|
*
|
|
* You might need this if your app implements code splitting and you want to
|
|
* load some of the reducers dynamically. You might also need this if you
|
|
* implement a hot reloading mechanism for Redux.
|
|
*
|
|
* @param {Function} nextReducer The reducer for the store to use instead.
|
|
* @returns {void}
|
|
*/
|
|
function replaceReducer(nextReducer) {
|
|
currentReducer = nextReducer;
|
|
dispatch({ type: ActionTypes.INIT });
|
|
}
|
|
|
|
// When a store is created, an "INIT" action is dispatched so that every
|
|
// reducer returns their initial state. This effectively populates
|
|
// the initial state tree.
|
|
dispatch({ type: ActionTypes.INIT });
|
|
|
|
return {
|
|
dispatch: dispatch,
|
|
subscribe: subscribe,
|
|
getState: getState,
|
|
getReducer: getReducer,
|
|
replaceReducer: replaceReducer
|
|
};
|
|
}
|
|
},{"./utils/isPlainObject":212}],207:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
exports.__esModule = true;
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _createStore = require('./createStore');
|
|
|
|
var _createStore2 = _interopRequireDefault(_createStore);
|
|
|
|
var _utilsCombineReducers = require('./utils/combineReducers');
|
|
|
|
var _utilsCombineReducers2 = _interopRequireDefault(_utilsCombineReducers);
|
|
|
|
var _utilsBindActionCreators = require('./utils/bindActionCreators');
|
|
|
|
var _utilsBindActionCreators2 = _interopRequireDefault(_utilsBindActionCreators);
|
|
|
|
var _utilsApplyMiddleware = require('./utils/applyMiddleware');
|
|
|
|
var _utilsApplyMiddleware2 = _interopRequireDefault(_utilsApplyMiddleware);
|
|
|
|
var _utilsCompose = require('./utils/compose');
|
|
|
|
var _utilsCompose2 = _interopRequireDefault(_utilsCompose);
|
|
|
|
exports.createStore = _createStore2['default'];
|
|
exports.combineReducers = _utilsCombineReducers2['default'];
|
|
exports.bindActionCreators = _utilsBindActionCreators2['default'];
|
|
exports.applyMiddleware = _utilsApplyMiddleware2['default'];
|
|
exports.compose = _utilsCompose2['default'];
|
|
},{"./createStore":206,"./utils/applyMiddleware":208,"./utils/bindActionCreators":209,"./utils/combineReducers":210,"./utils/compose":211}],208:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
|
|
|
exports['default'] = applyMiddleware;
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _compose = require('./compose');
|
|
|
|
var _compose2 = _interopRequireDefault(_compose);
|
|
|
|
/**
|
|
* Creates a store enhancer that applies middleware to the dispatch method
|
|
* of the Redux store. This is handy for a variety of tasks, such as expressing
|
|
* asynchronous actions in a concise manner, or logging every action payload.
|
|
*
|
|
* See `redux-thunk` package as an example of the Redux middleware.
|
|
*
|
|
* Because middleware is potentially asynchronous, this should be the first
|
|
* store enhancer in the composition chain.
|
|
*
|
|
* Note that each middleware will be given the `dispatch` and `getState` functions
|
|
* as named arguments.
|
|
*
|
|
* @param {...Function} middlewares The middleware chain to be applied.
|
|
* @returns {Function} A store enhancer applying the middleware.
|
|
*/
|
|
|
|
function applyMiddleware() {
|
|
for (var _len = arguments.length, middlewares = Array(_len), _key = 0; _key < _len; _key++) {
|
|
middlewares[_key] = arguments[_key];
|
|
}
|
|
|
|
return function (next) {
|
|
return function (reducer, initialState) {
|
|
var store = next(reducer, initialState);
|
|
var _dispatch = store.dispatch;
|
|
var chain = [];
|
|
|
|
var middlewareAPI = {
|
|
getState: store.getState,
|
|
dispatch: function dispatch(action) {
|
|
return _dispatch(action);
|
|
}
|
|
};
|
|
chain = middlewares.map(function (middleware) {
|
|
return middleware(middlewareAPI);
|
|
});
|
|
_dispatch = _compose2['default'].apply(undefined, chain.concat([store.dispatch]));
|
|
|
|
return _extends({}, store, {
|
|
dispatch: _dispatch
|
|
});
|
|
};
|
|
};
|
|
}
|
|
|
|
module.exports = exports['default'];
|
|
},{"./compose":211}],209:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
exports.__esModule = true;
|
|
exports['default'] = bindActionCreators;
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _utilsMapValues = require('../utils/mapValues');
|
|
|
|
var _utilsMapValues2 = _interopRequireDefault(_utilsMapValues);
|
|
|
|
function bindActionCreator(actionCreator, dispatch) {
|
|
return function () {
|
|
return dispatch(actionCreator.apply(undefined, arguments));
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Turns an object whose values are action creators, into an object with the
|
|
* same keys, but with every function wrapped into a `dispatch` call so they
|
|
* may be invoked directly. This is just a convenience method, as you can call
|
|
* `store.dispatch(MyActionCreators.doSomething())` yourself just fine.
|
|
*
|
|
* For convenience, you can also pass a single function as the first argument,
|
|
* and get a function in return.
|
|
*
|
|
* @param {Function|Object} actionCreators An object whose values are action
|
|
* creator functions. One handy way to obtain it is to use ES6 `import * as`
|
|
* syntax. You may also pass a single function.
|
|
*
|
|
* @param {Function} dispatch The `dispatch` function available on your Redux
|
|
* store.
|
|
*
|
|
* @returns {Function|Object} The object mimicking the original object, but with
|
|
* every action creator wrapped into the `dispatch` call. If you passed a
|
|
* function as `actionCreators`, the return value will also be a single
|
|
* function.
|
|
*/
|
|
|
|
function bindActionCreators(actionCreators, dispatch) {
|
|
if (typeof actionCreators === 'function') {
|
|
return bindActionCreator(actionCreators, dispatch);
|
|
}
|
|
|
|
if (typeof actionCreators !== 'object' || actionCreators == null) {
|
|
throw new Error('bindActionCreators expected an object or a function, instead received ' + typeof actionCreators + '. ' + 'Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?');
|
|
}
|
|
|
|
return _utilsMapValues2['default'](actionCreators, function (actionCreator) {
|
|
return bindActionCreator(actionCreator, dispatch);
|
|
});
|
|
}
|
|
|
|
module.exports = exports['default'];
|
|
},{"../utils/mapValues":213}],210:[function(require,module,exports){
|
|
(function (process){
|
|
'use strict';
|
|
|
|
exports.__esModule = true;
|
|
exports['default'] = combineReducers;
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _createStore = require('../createStore');
|
|
|
|
var _utilsIsPlainObject = require('../utils/isPlainObject');
|
|
|
|
var _utilsIsPlainObject2 = _interopRequireDefault(_utilsIsPlainObject);
|
|
|
|
var _utilsMapValues = require('../utils/mapValues');
|
|
|
|
var _utilsMapValues2 = _interopRequireDefault(_utilsMapValues);
|
|
|
|
var _utilsPick = require('../utils/pick');
|
|
|
|
var _utilsPick2 = _interopRequireDefault(_utilsPick);
|
|
|
|
function getErrorMessage(key, action) {
|
|
var actionType = action && action.type;
|
|
var actionName = actionType && '"' + actionType.toString() + '"' || 'an action';
|
|
|
|
return 'Reducer "' + key + '" returned undefined handling ' + actionName + '. ' + 'To ignore an action, you must explicitly return the previous state.';
|
|
}
|
|
|
|
function verifyStateShape(initialState, currentState) {
|
|
var reducerKeys = Object.keys(currentState);
|
|
|
|
if (reducerKeys.length === 0) {
|
|
console.error('Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.');
|
|
return;
|
|
}
|
|
|
|
if (!_utilsIsPlainObject2['default'](initialState)) {
|
|
console.error('initialState has unexpected type of "' + ({}).toString.call(initialState).match(/\s([a-z|A-Z]+)/)[1] + '". Expected initialState to be an object with the following ' + ('keys: "' + reducerKeys.join('", "') + '"'));
|
|
return;
|
|
}
|
|
|
|
var unexpectedKeys = Object.keys(initialState).filter(function (key) {
|
|
return reducerKeys.indexOf(key) < 0;
|
|
});
|
|
|
|
if (unexpectedKeys.length > 0) {
|
|
console.error('Unexpected ' + (unexpectedKeys.length > 1 ? 'keys' : 'key') + ' ' + ('"' + unexpectedKeys.join('", "') + '" in initialState will be ignored. ') + ('Expected to find one of the known reducer keys instead: "' + reducerKeys.join('", "') + '"'));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Turns an object whose values are different reducer functions, into a single
|
|
* reducer function. It will call every child reducer, and gather their results
|
|
* into a single state object, whose keys correspond to the keys of the passed
|
|
* reducer functions.
|
|
*
|
|
* @param {Object} reducers An object whose values correspond to different
|
|
* reducer functions that need to be combined into one. One handy way to obtain
|
|
* it is to use ES6 `import * as reducers` syntax. The reducers may never return
|
|
* undefined for any action. Instead, they should return their initial state
|
|
* if the state passed to them was undefined, and the current state for any
|
|
* unrecognized action.
|
|
*
|
|
* @returns {Function} A reducer function that invokes every reducer inside the
|
|
* passed object, and builds a state object with the same shape.
|
|
*/
|
|
|
|
function combineReducers(reducers) {
|
|
var finalReducers = _utilsPick2['default'](reducers, function (val) {
|
|
return typeof val === 'function';
|
|
});
|
|
|
|
Object.keys(finalReducers).forEach(function (key) {
|
|
var reducer = finalReducers[key];
|
|
if (typeof reducer(undefined, { type: _createStore.ActionTypes.INIT }) === 'undefined') {
|
|
throw new Error('Reducer "' + key + '" returned undefined during initialization. ' + 'If the state passed to the reducer is undefined, you must ' + 'explicitly return the initial state. The initial state may ' + 'not be undefined.');
|
|
}
|
|
|
|
var type = Math.random().toString(36).substring(7).split('').join('.');
|
|
if (typeof reducer(undefined, { type: type }) === 'undefined') {
|
|
throw new Error('Reducer "' + key + '" returned undefined when probed with a random type. ' + ('Don\'t try to handle ' + _createStore.ActionTypes.INIT + ' or other actions in "redux/*" ') + 'namespace. They are considered private. Instead, you must return the ' + 'current state for any unknown actions, unless it is undefined, ' + 'in which case you must return the initial state, regardless of the ' + 'action type. The initial state may not be undefined.');
|
|
}
|
|
});
|
|
|
|
var defaultState = _utilsMapValues2['default'](finalReducers, function () {
|
|
return undefined;
|
|
});
|
|
var stateShapeVerified;
|
|
|
|
return function combination(state, action) {
|
|
if (state === undefined) state = defaultState;
|
|
|
|
var finalState = _utilsMapValues2['default'](finalReducers, function (reducer, key) {
|
|
var newState = reducer(state[key], action);
|
|
if (typeof newState === 'undefined') {
|
|
throw new Error(getErrorMessage(key, action));
|
|
}
|
|
return newState;
|
|
});
|
|
|
|
if (
|
|
// Node-like CommonJS environments (Browserify, Webpack)
|
|
typeof process !== 'undefined' && typeof process.env !== 'undefined' && process.env.NODE_ENV !== 'production' ||
|
|
// React Native
|
|
typeof __DEV__ !== 'undefined' && __DEV__ //eslint-disable-line no-undef
|
|
) {
|
|
if (!stateShapeVerified) {
|
|
verifyStateShape(state, finalState);
|
|
stateShapeVerified = true;
|
|
}
|
|
}
|
|
|
|
return finalState;
|
|
};
|
|
}
|
|
|
|
module.exports = exports['default'];
|
|
}).call(this,require('_process'))
|
|
},{"../createStore":206,"../utils/isPlainObject":212,"../utils/mapValues":213,"../utils/pick":214,"_process":1}],211:[function(require,module,exports){
|
|
/**
|
|
* Composes functions from left to right.
|
|
*
|
|
* @param {...Function} funcs - The functions to compose. Each is expected to
|
|
* accept a function as an argument and to return a function.
|
|
* @returns {Function} A function obtained by composing functions from left to
|
|
* right.
|
|
*/
|
|
"use strict";
|
|
|
|
exports.__esModule = true;
|
|
exports["default"] = compose;
|
|
|
|
function compose() {
|
|
for (var _len = arguments.length, funcs = Array(_len), _key = 0; _key < _len; _key++) {
|
|
funcs[_key] = arguments[_key];
|
|
}
|
|
|
|
return funcs.reduceRight(function (composed, f) {
|
|
return f(composed);
|
|
});
|
|
}
|
|
|
|
module.exports = exports["default"];
|
|
},{}],212:[function(require,module,exports){
|
|
arguments[4][47][0].apply(exports,arguments)
|
|
},{"dup":47}],213:[function(require,module,exports){
|
|
/**
|
|
* Applies a function to every key-value pair inside an object.
|
|
*
|
|
* @param {Object} obj The source object.
|
|
* @param {Function} fn The mapper function taht receives the value and the key.
|
|
* @returns {Object} A new object that contains the mapped values for the keys.
|
|
*/
|
|
"use strict";
|
|
|
|
exports.__esModule = true;
|
|
exports["default"] = mapValues;
|
|
|
|
function mapValues(obj, fn) {
|
|
return Object.keys(obj).reduce(function (result, key) {
|
|
result[key] = fn(obj[key], key);
|
|
return result;
|
|
}, {});
|
|
}
|
|
|
|
module.exports = exports["default"];
|
|
},{}],214:[function(require,module,exports){
|
|
/**
|
|
* Picks key-value pairs from an object where values satisfy a predicate.
|
|
*
|
|
* @param {Object} obj The object to pick from.
|
|
* @param {Function} fn The predicate the values must satisfy to be copied.
|
|
* @returns {Object} The object with the values that satisfied the predicate.
|
|
*/
|
|
"use strict";
|
|
|
|
exports.__esModule = true;
|
|
exports["default"] = pick;
|
|
|
|
function pick(obj, fn) {
|
|
return Object.keys(obj).reduce(function (result, key) {
|
|
if (fn(obj[key])) {
|
|
result[key] = obj[key];
|
|
}
|
|
return result;
|
|
}, {});
|
|
}
|
|
|
|
module.exports = exports["default"];
|
|
},{}],215:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
exports['default'] = changedir;
|
|
|
|
var _actionsTypes = require('actions/types');
|
|
|
|
function changedir(dir) {
|
|
if (dir === 'sdcard') dir = '';
|
|
return {
|
|
type: _actionsTypes.CHANGE_DIRECTORY,
|
|
dir: dir
|
|
};
|
|
}
|
|
|
|
module.exports = exports['default'];
|
|
|
|
},{"actions/types":223}],216:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
|
|
|
exports.show = show;
|
|
exports.hide = hide;
|
|
exports.toggle = toggle;
|
|
exports.hideAll = hideAll;
|
|
|
|
var _actionsTypes = require('actions/types');
|
|
|
|
function show(id) {
|
|
var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
|
|
|
|
return _extends({
|
|
type: _actionsTypes.DIALOG,
|
|
active: true,
|
|
id: id }, props);
|
|
}
|
|
|
|
function hide(id) {
|
|
var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
|
|
|
|
return _extends({
|
|
type: _actionsTypes.DIALOG,
|
|
active: false,
|
|
id: id }, props);
|
|
}
|
|
|
|
function toggle(id) {
|
|
var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
|
|
|
|
return _extends({
|
|
type: _actionsTypes.DIALOG,
|
|
active: 'toggle',
|
|
id: id }, props);
|
|
}
|
|
|
|
function hideAll() {
|
|
var props = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
|
|
|
return _extends({
|
|
type: _actionsTypes.DIALOG,
|
|
active: false
|
|
}, props);
|
|
}
|
|
|
|
},{"actions/types":223}],217:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
exports.create = create;
|
|
exports.share = share;
|
|
exports.rename = rename;
|
|
exports.active = active;
|
|
exports.deleteFile = deleteFile;
|
|
|
|
var _actionsTypes = require('actions/types');
|
|
|
|
function create(path) {
|
|
var directory = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
|
|
|
|
return {
|
|
type: _actionsTypes.CREATE_FILE,
|
|
path: path, directory: directory
|
|
};
|
|
}
|
|
|
|
function share(path) {
|
|
return {
|
|
type: _actionsTypes.SHARE_FILE,
|
|
path: path
|
|
};
|
|
}
|
|
|
|
function rename(file, name) {
|
|
return {
|
|
type: _actionsTypes.RENAME_FILE,
|
|
file: file, name: name
|
|
};
|
|
}
|
|
|
|
function active(file) {
|
|
return {
|
|
type: _actionsTypes.ACTIVE_FILE,
|
|
file: file
|
|
};
|
|
}
|
|
|
|
function deleteFile(file) {
|
|
return {
|
|
type: _actionsTypes.DELETE_FILE,
|
|
file: file
|
|
};
|
|
}
|
|
|
|
},{"actions/types":223}],218:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
exports.refresh = refresh;
|
|
exports.toggle = toggle;
|
|
exports.details = details;
|
|
exports.list = list;
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _actionsTypes = require('actions/types');
|
|
|
|
var _store = require('store');
|
|
|
|
var _store2 = _interopRequireDefault(_store);
|
|
|
|
function refresh() {
|
|
return {
|
|
type: _actionsTypes.REFRESH
|
|
};
|
|
}
|
|
|
|
function toggle(state) {
|
|
return {
|
|
type: _actionsTypes.FILES_VIEW,
|
|
view: 'toggle'
|
|
};
|
|
}
|
|
|
|
function details(state) {
|
|
return {
|
|
type: _actionsTypes.FILES_VIEW,
|
|
view: 'details'
|
|
};
|
|
}
|
|
|
|
function list(state) {
|
|
return {
|
|
type: _actionsTypes.FILES_VIEW,
|
|
view: 'list'
|
|
};
|
|
}
|
|
|
|
},{"actions/types":223,"store":"store"}],219:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
exports['default'] = listFiles;
|
|
|
|
var _actionsTypes = require('actions/types');
|
|
|
|
function listFiles(files) {
|
|
return {
|
|
type: _actionsTypes.LIST_FILES,
|
|
files: files
|
|
};
|
|
}
|
|
|
|
module.exports = exports['default'];
|
|
|
|
},{"actions/types":223}],220:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
|
|
|
exports.show = show;
|
|
exports.hide = hide;
|
|
exports.toggle = toggle;
|
|
exports.hideAll = hideAll;
|
|
|
|
var _actionsTypes = require('actions/types');
|
|
|
|
function show(id) {
|
|
var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
|
|
|
|
return _extends({
|
|
type: _actionsTypes.MENU,
|
|
active: true,
|
|
id: id }, props);
|
|
}
|
|
|
|
function hide(id) {
|
|
var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
|
|
|
|
return _extends({
|
|
type: _actionsTypes.MENU,
|
|
active: false,
|
|
id: id }, props);
|
|
}
|
|
|
|
function toggle(id) {
|
|
var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
|
|
|
|
return _extends({
|
|
type: _actionsTypes.MENU,
|
|
active: 'toggle',
|
|
id: id }, props);
|
|
}
|
|
|
|
function hideAll() {
|
|
var props = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
|
|
|
return _extends({
|
|
type: _actionsTypes.MENU,
|
|
active: false
|
|
}, props);
|
|
}
|
|
|
|
},{"actions/types":223}],221:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
exports.show = show;
|
|
exports.hide = hide;
|
|
exports.toggle = toggle;
|
|
|
|
var _actionsTypes = require('actions/types');
|
|
|
|
function show() {
|
|
return {
|
|
type: _actionsTypes.NAVIGATION,
|
|
active: true
|
|
};
|
|
}
|
|
|
|
function hide() {
|
|
return {
|
|
type: _actionsTypes.NAVIGATION,
|
|
active: false
|
|
};
|
|
}
|
|
|
|
function toggle() {
|
|
return {
|
|
type: _actionsTypes.NAVIGATION,
|
|
active: _actionsTypes.TOGGLE
|
|
};
|
|
}
|
|
|
|
},{"actions/types":223}],222:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
|
|
|
var _actionsTypes = require('actions/types');
|
|
|
|
exports['default'] = function (props) {
|
|
return _extends({
|
|
type: _actionsTypes.SETTINGS
|
|
}, props);
|
|
};
|
|
|
|
module.exports = exports['default'];
|
|
|
|
},{"actions/types":223}],223:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
var TYPES = {
|
|
CHANGE_DIRECTORY: Symbol('CHANGE_DIRECTORY'),
|
|
|
|
LIST_FILES: Symbol('LIST_FILES'),
|
|
FILES_VIEW: Symbol('FILES_VIEW'),
|
|
|
|
NAVIGATION: Symbol('NAVIGATION'),
|
|
TOGGLE: Symbol('TOGGLE'),
|
|
REFRESH: Symbol('REFRESH'),
|
|
SORT: Symbol('SORT'),
|
|
|
|
NEW_FILE: Symbol('NEW_FILE'),
|
|
CREATE_FILE: Symbol('CREATE_FILE'),
|
|
SHARE_FILE: Symbol('SHARE_FILE'),
|
|
RENAME_FILE: Symbol('RENAME_FILE'),
|
|
ACTIVE_FILE: Symbol('ACTIVE_FILE'),
|
|
DELETE_FILE: Symbol('DELETE_FILE'),
|
|
|
|
MENU: Symbol('MENU'),
|
|
|
|
DIALOG: Symbol('DEBUG'),
|
|
|
|
SETTINGS: Symbol('SETTINGS'),
|
|
|
|
SEARCH: Symbol('SEARCH')
|
|
};
|
|
|
|
exports['default'] = TYPES;
|
|
module.exports = exports['default'];
|
|
|
|
},{}],224:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
exports.sdcard = sdcard;
|
|
|
|
var root = _asyncToGenerator(function* () {
|
|
if (ROOT_CACHE) return ROOT_CACHE;
|
|
|
|
ROOT_CACHE = yield sdcard().getRoot();
|
|
window.root = ROOT_CACHE;
|
|
return ROOT_CACHE;
|
|
});
|
|
|
|
exports.root = root;
|
|
|
|
var getFile = _asyncToGenerator(function* () {
|
|
var dir = arguments.length <= 0 || arguments[0] === undefined ? '/' : arguments[0];
|
|
|
|
var parent = yield root();
|
|
|
|
if (dir === '/' || !dir) return parent;
|
|
|
|
return yield parent.get(dir);
|
|
});
|
|
|
|
exports.getFile = getFile;
|
|
|
|
var children = _asyncToGenerator(function* (dir, gatherInfo) {
|
|
var parent = yield getFile(dir);
|
|
var childs = yield parent.getFilesAndDirectories();
|
|
|
|
if (gatherInfo) {
|
|
var _iteratorNormalCompletion = true;
|
|
var _didIteratorError = false;
|
|
var _iteratorError = undefined;
|
|
|
|
try {
|
|
for (var _iterator = childs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
var child = _step.value;
|
|
|
|
if ((0, _utils.type)(child) !== 'Directory') continue;
|
|
|
|
var subchildren = undefined;
|
|
try {
|
|
subchildren = yield child.getFilesAndDirectories();
|
|
} catch (e) {
|
|
subchildren = [];
|
|
}
|
|
|
|
child.children = subchildren.length;
|
|
}
|
|
} catch (err) {
|
|
_didIteratorError = true;
|
|
_iteratorError = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion && _iterator['return']) {
|
|
_iterator['return']();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError) {
|
|
throw _iteratorError;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return childs;
|
|
});
|
|
|
|
exports.children = children;
|
|
|
|
var readFile = _asyncToGenerator(function* (path) {
|
|
var file = yield getFile(path);
|
|
|
|
return new Promise(function (resolve, reject) {
|
|
var reader = new FileReader();
|
|
|
|
reader.onload = function () {
|
|
resolve(reader.result);
|
|
};
|
|
reader.onerror = reject;
|
|
reader.onabort = reject;
|
|
reader.readAsArrayBuffer(file);
|
|
});
|
|
});
|
|
|
|
exports.readFile = readFile;
|
|
|
|
var createFile = _asyncToGenerator(function* () {
|
|
var parent = yield root();
|
|
|
|
return yield parent.createFile.apply(parent, arguments);
|
|
});
|
|
|
|
exports.createFile = createFile;
|
|
|
|
var createDirectory = _asyncToGenerator(function* () {
|
|
var parent = yield root();
|
|
|
|
return parent.createDirectory.apply(parent, arguments);
|
|
});
|
|
|
|
exports.createDirectory = createDirectory;
|
|
|
|
var move = _asyncToGenerator(function* (file, newPath) {
|
|
var path = (file.path || '').replace(/^\//, ''); // remove starting slash
|
|
var oldPath = path + file.name;
|
|
|
|
newPath = newPath.replace(/^\//, '');
|
|
|
|
var target = yield getFile(oldPath);
|
|
var parent = yield root();
|
|
|
|
if ((0, _utils.type)(target) === 'Directory') {
|
|
yield parent.createDirectory(newPath);
|
|
var childs = yield target.getFilesAndDirectories();
|
|
|
|
var _iteratorNormalCompletion2 = true;
|
|
var _didIteratorError2 = false;
|
|
var _iteratorError2 = undefined;
|
|
|
|
try {
|
|
for (var _iterator2 = childs[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
|
var child = _step2.value;
|
|
|
|
if ((0, _utils.type)(child) === 'File') {
|
|
child.path = oldPath + '/';
|
|
}
|
|
|
|
yield move(child, newPath + '/' + child.name);
|
|
}
|
|
} catch (err) {
|
|
_didIteratorError2 = true;
|
|
_iteratorError2 = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion2 && _iterator2['return']) {
|
|
_iterator2['return']();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError2) {
|
|
throw _iteratorError2;
|
|
}
|
|
}
|
|
}
|
|
|
|
yield parent.remove(oldPath);
|
|
return;
|
|
} else {
|
|
var _ret = yield* (function* () {
|
|
var content = yield readFile(oldPath);
|
|
|
|
var blob = new Blob([content], { type: target.type });
|
|
|
|
return {
|
|
v: new Promise(function (resolve, reject) {
|
|
var request = sdcard().addNamed(blob, newPath);
|
|
request.onsuccess = resolve;
|
|
request.onerror = reject;
|
|
request.onabort = reject;
|
|
}).then(function () {
|
|
return sdcard()['delete'](oldPath);
|
|
})
|
|
};
|
|
})();
|
|
|
|
if (typeof _ret === 'object') return _ret.v;
|
|
}
|
|
});
|
|
|
|
exports.move = move;
|
|
|
|
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { var callNext = step.bind(null, 'next'); var callThrow = step.bind(null, 'throw'); function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(callNext, callThrow); } } callNext(); }); }; }
|
|
|
|
var _utils = require('utils');
|
|
|
|
var SD_CACHE = undefined;
|
|
|
|
function sdcard() {
|
|
if (SD_CACHE) return SD_CACHE;
|
|
|
|
SD_CACHE = navigator.getDeviceStorage('sdcard');
|
|
window.sdcard = SD_CACHE;
|
|
return SD_CACHE;
|
|
}
|
|
|
|
var ROOT_CACHE = undefined;
|
|
|
|
},{"utils":"utils"}],225:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
|
|
|
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var _react = require('react');
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _reactRedux = require('react-redux');
|
|
|
|
var _actionsChangedir = require('actions/changedir');
|
|
|
|
var _actionsChangedir2 = _interopRequireDefault(_actionsChangedir);
|
|
|
|
var _store = require('store');
|
|
|
|
// TODO: Fix history not working when clicking on sdcard
|
|
|
|
var Breadcrumb = (function (_Component) {
|
|
_inherits(Breadcrumb, _Component);
|
|
|
|
function Breadcrumb() {
|
|
_classCallCheck(this, _Breadcrumb);
|
|
|
|
_get(Object.getPrototypeOf(_Breadcrumb.prototype), 'constructor', this).apply(this, arguments);
|
|
}
|
|
|
|
_createClass(Breadcrumb, [{
|
|
key: 'render',
|
|
value: function render() {
|
|
var directories = this.props.cwd.split('/');
|
|
directories.unshift('sdcard');
|
|
|
|
var els = directories.map(function (dir, index, arr) {
|
|
var path = arr.slice(1, index + 1).join('/');
|
|
var slash = index > 0 ? '/' : '';
|
|
|
|
return _react2['default'].createElement(
|
|
'span',
|
|
{ key: index, onClick: (0, _store.bind)((0, _actionsChangedir2['default'])(path)) },
|
|
_react2['default'].createElement(
|
|
'i',
|
|
null,
|
|
slash
|
|
),
|
|
dir
|
|
);
|
|
});
|
|
|
|
var lastDirectories = this.props.lwd.split('/');
|
|
if (lastDirectories.length > directories.length - 1) {
|
|
lastDirectories.splice(0, directories.length - 1);
|
|
var _history = lastDirectories.map(function (dir, index, arr) {
|
|
var current = directories.slice(1).concat(arr.slice(0, index + 1));
|
|
var path = current.join('/');
|
|
|
|
return _react2['default'].createElement(
|
|
'span',
|
|
{ key: directories.length + index, className: 'history', onClick: (0, _store.bind)((0, _actionsChangedir2['default'])(path)) },
|
|
_react2['default'].createElement(
|
|
'i',
|
|
null,
|
|
'/'
|
|
),
|
|
dir
|
|
);
|
|
});
|
|
|
|
els = els.concat(_history);
|
|
}
|
|
|
|
return _react2['default'].createElement(
|
|
'div',
|
|
{ className: 'breadcrumb' },
|
|
els
|
|
);
|
|
}
|
|
}]);
|
|
|
|
var _Breadcrumb = Breadcrumb;
|
|
Breadcrumb = (0, _reactRedux.connect)(props)(Breadcrumb) || Breadcrumb;
|
|
return Breadcrumb;
|
|
})(_react.Component);
|
|
|
|
exports['default'] = Breadcrumb;
|
|
|
|
function props(state) {
|
|
return {
|
|
lwd: state.get('lwd'), // last working directory
|
|
cwd: state.get('cwd')
|
|
};
|
|
}
|
|
module.exports = exports['default'];
|
|
|
|
},{"actions/changedir":215,"react":205,"react-redux":45,"store":"store"}],226:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
|
|
|
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var _react = require('react');
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _utils = require('utils');
|
|
|
|
var Dialog = (function (_Component) {
|
|
_inherits(Dialog, _Component);
|
|
|
|
function Dialog() {
|
|
_classCallCheck(this, Dialog);
|
|
|
|
_get(Object.getPrototypeOf(Dialog.prototype), 'constructor', this).apply(this, arguments);
|
|
}
|
|
|
|
_createClass(Dialog, [{
|
|
key: 'render',
|
|
value: function render() {
|
|
var _this = this;
|
|
|
|
var _props = this.props;
|
|
var input = _props.input;
|
|
var title = _props.title;
|
|
var description = _props.description;
|
|
var active = _props.active;
|
|
|
|
var conditionalInput = input ? _react2['default'].createElement('input', { ref: 'input' }) : '';
|
|
|
|
var buttons = this.props.buttons.map(function (button, i) {
|
|
return _react2['default'].createElement(
|
|
'button',
|
|
{ className: button.className + ' btn', key: i,
|
|
onClick: button.action.bind(_this) },
|
|
button.text
|
|
);
|
|
});
|
|
|
|
var className = active ? 'dialog active' : 'dialog';
|
|
|
|
return _react2['default'].createElement(
|
|
'div',
|
|
{ className: className },
|
|
_react2['default'].createElement(
|
|
'p',
|
|
{ className: 'regular-medium' },
|
|
title
|
|
),
|
|
_react2['default'].createElement(
|
|
'p',
|
|
{ className: 'light-medium' },
|
|
description
|
|
),
|
|
conditionalInput,
|
|
_react2['default'].createElement(
|
|
'div',
|
|
{ className: 'foot' },
|
|
buttons
|
|
)
|
|
);
|
|
}
|
|
}]);
|
|
|
|
return Dialog;
|
|
})(_react.Component);
|
|
|
|
exports['default'] = Dialog;
|
|
module.exports = exports['default'];
|
|
|
|
},{"react":205,"utils":"utils"}],227:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
|
|
|
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var _react = require('react');
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _actionsChangedir = require('actions/changedir');
|
|
|
|
var _actionsChangedir2 = _interopRequireDefault(_actionsChangedir);
|
|
|
|
var _actionsMenu = require('actions/menu');
|
|
|
|
var _actionsFile = require('actions/file');
|
|
|
|
var _menu = require('./menu');
|
|
|
|
var _store = require('store');
|
|
|
|
var _store2 = _interopRequireDefault(_store);
|
|
|
|
var MENU_TOP_SPACE = 20;
|
|
|
|
var Directory = (function (_Component) {
|
|
_inherits(Directory, _Component);
|
|
|
|
function Directory() {
|
|
_classCallCheck(this, Directory);
|
|
|
|
_get(Object.getPrototypeOf(Directory.prototype), 'constructor', this).apply(this, arguments);
|
|
}
|
|
|
|
_createClass(Directory, [{
|
|
key: 'render',
|
|
value: function render() {
|
|
return _react2['default'].createElement(
|
|
'div',
|
|
{ className: 'directory', ref: 'container',
|
|
onClick: this.peek.bind(this),
|
|
onContextMenu: this.contextMenu.bind(this) },
|
|
_react2['default'].createElement('i', null),
|
|
_react2['default'].createElement(
|
|
'p',
|
|
null,
|
|
this.props.name
|
|
),
|
|
_react2['default'].createElement(
|
|
'span',
|
|
null,
|
|
this.props.children,
|
|
' items'
|
|
)
|
|
);
|
|
}
|
|
}, {
|
|
key: 'peek',
|
|
value: function peek() {
|
|
var file = _store2['default'].getState().get('files')[this.props.index];
|
|
|
|
_store2['default'].dispatch((0, _actionsChangedir2['default'])(file.path.slice(1) + file.name));
|
|
}
|
|
}, {
|
|
key: 'contextMenu',
|
|
value: function contextMenu(e) {
|
|
e.preventDefault();
|
|
|
|
var rect = _react2['default'].findDOMNode(this.refs.container).getBoundingClientRect();
|
|
var x = rect.x;
|
|
var y = rect.y;
|
|
var width = rect.width;
|
|
var height = rect.height;
|
|
|
|
var left = x + width / 2 - _menu.MENU_WIDTH / 2,
|
|
top = y + height / 2 + MENU_TOP_SPACE;
|
|
_store2['default'].dispatch((0, _actionsMenu.show)('directoryMenu', { style: { left: left, top: top } }));
|
|
_store2['default'].dispatch((0, _actionsFile.active)(this.props.index));
|
|
}
|
|
}]);
|
|
|
|
return Directory;
|
|
})(_react.Component);
|
|
|
|
exports['default'] = Directory;
|
|
module.exports = exports['default'];
|
|
|
|
},{"./menu":231,"actions/changedir":215,"actions/file":217,"actions/menu":220,"react":205,"store":"store"}],228:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
|
|
|
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
|
|
|
var getFiles = _asyncToGenerator(function* (dir) {
|
|
var storage = navigator.getDeviceStorage('sdcard');
|
|
var root = yield storage.get(dir);
|
|
|
|
return yield root.getFilesAndDirectories();
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { var callNext = step.bind(null, 'next'); var callThrow = step.bind(null, 'throw'); function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(callNext, callThrow); } } callNext(); }); }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var _react = require('react');
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _reactRedux = require('react-redux');
|
|
|
|
var _file = require('./file');
|
|
|
|
var _file2 = _interopRequireDefault(_file);
|
|
|
|
var _directory = require('./directory');
|
|
|
|
var _directory2 = _interopRequireDefault(_directory);
|
|
|
|
var _store = require('store');
|
|
|
|
var _store2 = _interopRequireDefault(_store);
|
|
|
|
var _utils = require('utils');
|
|
|
|
var FileList = (function (_Component) {
|
|
_inherits(FileList, _Component);
|
|
|
|
function FileList() {
|
|
_classCallCheck(this, _FileList);
|
|
|
|
_get(Object.getPrototypeOf(_FileList.prototype), 'constructor', this).call(this);
|
|
}
|
|
|
|
_createClass(FileList, [{
|
|
key: 'render',
|
|
value: function render() {
|
|
var files = this.props.files;
|
|
|
|
var settings = _store2['default'].getState().get('settings');
|
|
|
|
if (settings.showDirectoriesFirst) {
|
|
files = files.sort(function (a, b) {
|
|
if ((0, _utils.type)(a) === 'Directory') return -1;
|
|
if ((0, _utils.type)(b) === 'Directory') return 1;
|
|
return 0;
|
|
});
|
|
}
|
|
|
|
if (!settings.showHiddenFiles) {
|
|
files = files.filter(function (file) {
|
|
return file.name[0] !== '.';
|
|
});
|
|
}
|
|
|
|
var els = files.map(function (file, index) {
|
|
if ((0, _utils.type)(file) === 'File') {
|
|
return _react2['default'].createElement(_file2['default'], { key: index, index: index, name: file.name, size: file.size });
|
|
} else {
|
|
return _react2['default'].createElement(_directory2['default'], { key: index, index: index, name: file.name, children: file.children });
|
|
}
|
|
});
|
|
|
|
return _react2['default'].createElement(
|
|
'div',
|
|
{ className: 'file-list' },
|
|
els
|
|
);
|
|
}
|
|
}]);
|
|
|
|
var _FileList = FileList;
|
|
FileList = (0, _reactRedux.connect)(props)(FileList) || FileList;
|
|
return FileList;
|
|
})(_react.Component);
|
|
|
|
exports['default'] = FileList;
|
|
|
|
function props(state) {
|
|
return {
|
|
files: state.get('files')
|
|
};
|
|
}
|
|
|
|
module.exports = exports['default'];
|
|
|
|
},{"./directory":227,"./file":229,"react":205,"react-redux":45,"store":"store","utils":"utils"}],229:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
|
|
|
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var _react = require('react');
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _actionsMenu = require('actions/menu');
|
|
|
|
var _actionsFile = require('actions/file');
|
|
|
|
var _menu = require('./menu');
|
|
|
|
var _store = require('store');
|
|
|
|
var _store2 = _interopRequireDefault(_store);
|
|
|
|
var _utils = require('utils');
|
|
|
|
var MENU_TOP_SPACE = 20;
|
|
|
|
var File = (function (_Component) {
|
|
_inherits(File, _Component);
|
|
|
|
function File() {
|
|
_classCallCheck(this, File);
|
|
|
|
_get(Object.getPrototypeOf(File.prototype), 'constructor', this).call(this);
|
|
}
|
|
|
|
_createClass(File, [{
|
|
key: 'render',
|
|
value: function render() {
|
|
return _react2['default'].createElement(
|
|
'div',
|
|
{ className: 'file', ref: 'container',
|
|
onContextMenu: this.contextMenu.bind(this) },
|
|
_react2['default'].createElement('i', null),
|
|
_react2['default'].createElement(
|
|
'p',
|
|
null,
|
|
this.props.name
|
|
),
|
|
_react2['default'].createElement(
|
|
'span',
|
|
null,
|
|
(0, _utils.humanSize)(this.props.size)
|
|
)
|
|
);
|
|
}
|
|
}, {
|
|
key: 'contextMenu',
|
|
value: function contextMenu(e) {
|
|
e.preventDefault();
|
|
|
|
var rect = _react2['default'].findDOMNode(this.refs.container).getBoundingClientRect();
|
|
var x = rect.x;
|
|
var y = rect.y;
|
|
var width = rect.width;
|
|
var height = rect.height;
|
|
|
|
var left = x + width / 2 - _menu.MENU_WIDTH / 2,
|
|
top = y + height / 2 + MENU_TOP_SPACE;
|
|
_store2['default'].dispatch((0, _actionsMenu.show)('fileMenu', { style: { left: left, top: top } }));
|
|
_store2['default'].dispatch((0, _actionsFile.active)(this.props.index));
|
|
}
|
|
}]);
|
|
|
|
return File;
|
|
})(_react.Component);
|
|
|
|
exports['default'] = File;
|
|
module.exports = exports['default'];
|
|
|
|
},{"./menu":231,"actions/file":217,"actions/menu":220,"react":205,"store":"store","utils":"utils"}],230:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
|
|
|
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var _react = require('react');
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _actionsNavigation = require('actions/navigation');
|
|
|
|
var _store = require('store');
|
|
|
|
var _store2 = _interopRequireDefault(_store);
|
|
|
|
var Header = (function (_Component) {
|
|
_inherits(Header, _Component);
|
|
|
|
function Header() {
|
|
_classCallCheck(this, Header);
|
|
|
|
_get(Object.getPrototypeOf(Header.prototype), 'constructor', this).apply(this, arguments);
|
|
}
|
|
|
|
_createClass(Header, [{
|
|
key: 'render',
|
|
value: function render() {
|
|
return _react2['default'].createElement(
|
|
'header',
|
|
null,
|
|
_react2['default'].createElement('button', { className: 'drawer', onClick: this.toggleNavigation.bind(this) }),
|
|
_react2['default'].createElement(
|
|
'h1',
|
|
{ className: 'regular-medium' },
|
|
'Hawk'
|
|
)
|
|
);
|
|
}
|
|
}, {
|
|
key: 'toggleNavigation',
|
|
value: function toggleNavigation() {
|
|
_store2['default'].dispatch((0, _actionsNavigation.toggle)());
|
|
}
|
|
}]);
|
|
|
|
return Header;
|
|
})(_react.Component);
|
|
|
|
exports['default'] = Header;
|
|
module.exports = exports['default'];
|
|
|
|
},{"actions/navigation":221,"react":205,"store":"store"}],231:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
|
|
|
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var _react = require('react');
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var MENU_WIDTH = 245;
|
|
|
|
exports.MENU_WIDTH = MENU_WIDTH;
|
|
|
|
var Menu = (function (_Component) {
|
|
_inherits(Menu, _Component);
|
|
|
|
function Menu() {
|
|
_classCallCheck(this, Menu);
|
|
|
|
_get(Object.getPrototypeOf(Menu.prototype), 'constructor', this).apply(this, arguments);
|
|
}
|
|
|
|
_createClass(Menu, [{
|
|
key: 'render',
|
|
value: function render() {
|
|
var _this = this;
|
|
|
|
var _props = this.props;
|
|
var items = _props.items;
|
|
var active = _props.active;
|
|
var style = _props.style;
|
|
|
|
items = items || [];
|
|
|
|
var els = items.map(function (item, index) {
|
|
return _react2['default'].createElement(
|
|
'li',
|
|
{ key: index, onClick: item.action.bind(_this) },
|
|
item.name
|
|
);
|
|
});
|
|
var className = 'menu ' + (active ? 'active' : '');
|
|
|
|
return _react2['default'].createElement(
|
|
'div',
|
|
{ className: className, style: style },
|
|
_react2['default'].createElement(
|
|
'ul',
|
|
null,
|
|
els
|
|
)
|
|
);
|
|
}
|
|
}]);
|
|
|
|
return Menu;
|
|
})(_react.Component);
|
|
|
|
exports['default'] = Menu;
|
|
|
|
},{"react":205}],232:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
|
|
|
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var _react = require('react');
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _reactRedux = require('react-redux');
|
|
|
|
var _actionsNavigation = require('actions/navigation');
|
|
|
|
var _lodashStringCamelCase = require('lodash/string/camelCase');
|
|
|
|
var _lodashStringCamelCase2 = _interopRequireDefault(_lodashStringCamelCase);
|
|
|
|
var _actionsSettings = require('actions/settings');
|
|
|
|
var _actionsSettings2 = _interopRequireDefault(_actionsSettings);
|
|
|
|
var _store = require('store');
|
|
|
|
var _store2 = _interopRequireDefault(_store);
|
|
|
|
var Navigation = (function (_Component) {
|
|
_inherits(Navigation, _Component);
|
|
|
|
function Navigation() {
|
|
_classCallCheck(this, _Navigation);
|
|
|
|
_get(Object.getPrototypeOf(_Navigation.prototype), 'constructor', this).apply(this, arguments);
|
|
}
|
|
|
|
_createClass(Navigation, [{
|
|
key: 'render',
|
|
value: function render() {
|
|
var settings = this.props.settings;
|
|
|
|
return _react2['default'].createElement(
|
|
'nav',
|
|
{ className: this.props.active ? 'active' : '' },
|
|
_react2['default'].createElement('i', { onClick: this.hide.bind(this) }),
|
|
_react2['default'].createElement(
|
|
'p',
|
|
null,
|
|
'Filter'
|
|
),
|
|
_react2['default'].createElement(
|
|
'ul',
|
|
null,
|
|
_react2['default'].createElement(
|
|
'li',
|
|
null,
|
|
'Picture'
|
|
),
|
|
_react2['default'].createElement(
|
|
'li',
|
|
null,
|
|
'Video'
|
|
),
|
|
_react2['default'].createElement(
|
|
'li',
|
|
null,
|
|
'Audio'
|
|
)
|
|
),
|
|
_react2['default'].createElement(
|
|
'p',
|
|
null,
|
|
'Tools'
|
|
),
|
|
_react2['default'].createElement(
|
|
'ul',
|
|
null,
|
|
_react2['default'].createElement(
|
|
'li',
|
|
null,
|
|
'FTP Browser'
|
|
)
|
|
),
|
|
_react2['default'].createElement(
|
|
'p',
|
|
null,
|
|
'Preferences'
|
|
),
|
|
_react2['default'].createElement(
|
|
'ul',
|
|
{ onChange: this.onChange.bind(this) },
|
|
_react2['default'].createElement(
|
|
'li',
|
|
null,
|
|
_react2['default'].createElement('input', { type: 'checkbox', id: 'showHiddenFiles', defaultChecked: settings.showHiddenFiles }),
|
|
_react2['default'].createElement(
|
|
'label',
|
|
{ htmlFor: 'showHiddenFiles' },
|
|
'Show Hidden Files'
|
|
)
|
|
),
|
|
_react2['default'].createElement(
|
|
'li',
|
|
null,
|
|
_react2['default'].createElement('input', { id: 'showDirectoriesFirst', type: 'checkbox', defaultChecked: settings.showDirectoriesFirst }),
|
|
_react2['default'].createElement(
|
|
'label',
|
|
{ htmlFor: 'showDirectoriesFirst' },
|
|
'Show Directories First'
|
|
)
|
|
),
|
|
_react2['default'].createElement(
|
|
'li',
|
|
null,
|
|
'Advanced Preferences'
|
|
)
|
|
)
|
|
);
|
|
}
|
|
}, {
|
|
key: 'hide',
|
|
value: function hide() {
|
|
this.props.dispatch((0, _actionsNavigation.hide)());
|
|
}
|
|
}, {
|
|
key: 'onChange',
|
|
value: function onChange(e) {
|
|
if (e.target.nodeName.toLowerCase() !== 'input') return;
|
|
|
|
var key = e.target.id;
|
|
var value = this.props.settings[key];
|
|
|
|
var action = (0, _actionsSettings2['default'])(_defineProperty({}, key, e.target.checked));
|
|
|
|
_store2['default'].dispatch(action);
|
|
}
|
|
}]);
|
|
|
|
var _Navigation = Navigation;
|
|
Navigation = (0, _reactRedux.connect)(props)(Navigation) || Navigation;
|
|
return Navigation;
|
|
})(_react.Component);
|
|
|
|
exports['default'] = Navigation;
|
|
|
|
function props(store) {
|
|
return {
|
|
active: store.get('navigation'),
|
|
settings: store.get('settings')
|
|
};
|
|
}
|
|
module.exports = exports['default'];
|
|
|
|
},{"actions/navigation":221,"actions/settings":222,"lodash/string/camelCase":38,"react":205,"react-redux":45,"store":"store"}],233:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
|
|
|
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var _react = require('react');
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _componentsFileList = require('components/file-list');
|
|
|
|
var _componentsFileList2 = _interopRequireDefault(_componentsFileList);
|
|
|
|
var _componentsNavigation = require('components/navigation');
|
|
|
|
var _componentsNavigation2 = _interopRequireDefault(_componentsNavigation);
|
|
|
|
var _componentsHeader = require('components/header');
|
|
|
|
var _componentsHeader2 = _interopRequireDefault(_componentsHeader);
|
|
|
|
var _componentsBreadcrumb = require('components/breadcrumb');
|
|
|
|
var _componentsBreadcrumb2 = _interopRequireDefault(_componentsBreadcrumb);
|
|
|
|
var _componentsToolbar = require('components/toolbar');
|
|
|
|
var _componentsToolbar2 = _interopRequireDefault(_componentsToolbar);
|
|
|
|
var _componentsMenu = require('components/menu');
|
|
|
|
var _componentsMenu2 = _interopRequireDefault(_componentsMenu);
|
|
|
|
var _componentsDialog = require('components/dialog');
|
|
|
|
var _componentsDialog2 = _interopRequireDefault(_componentsDialog);
|
|
|
|
var _reactRedux = require('react-redux');
|
|
|
|
var _actionsMenu = require('actions/menu');
|
|
|
|
var _actionsDialog = require('actions/dialog');
|
|
|
|
var _actionsChangedir = require('actions/changedir');
|
|
|
|
var _actionsChangedir2 = _interopRequireDefault(_actionsChangedir);
|
|
|
|
var _store = require('store');
|
|
|
|
var _store2 = _interopRequireDefault(_store);
|
|
|
|
window.store = _store2['default'];
|
|
window.changedir = _actionsChangedir2['default'];
|
|
|
|
var FileMenu = (0, _reactRedux.connect)(function (state) {
|
|
return state.get('fileMenu');
|
|
})(_componentsMenu2['default']);
|
|
var DirectoryMenu = (0, _reactRedux.connect)(function (state) {
|
|
return state.get('directoryMenu');
|
|
})(_componentsMenu2['default']);
|
|
|
|
var RenameDialog = (0, _reactRedux.connect)(function (state) {
|
|
return state.get('renameDialog');
|
|
})(_componentsDialog2['default']);
|
|
var DeleteDialog = (0, _reactRedux.connect)(function (state) {
|
|
return state.get('deleteDialog');
|
|
})(_componentsDialog2['default']);
|
|
var ErrorDialog = (0, _reactRedux.connect)(function (state) {
|
|
return state.get('errorDialog');
|
|
})(_componentsDialog2['default']);
|
|
var CreateDialog = (0, _reactRedux.connect)(function (state) {
|
|
return state.get('createDialog');
|
|
})(_componentsDialog2['default']);
|
|
|
|
var Root = (function (_Component) {
|
|
_inherits(Root, _Component);
|
|
|
|
function Root() {
|
|
_classCallCheck(this, Root);
|
|
|
|
_get(Object.getPrototypeOf(Root.prototype), 'constructor', this).apply(this, arguments);
|
|
}
|
|
|
|
_createClass(Root, [{
|
|
key: 'render',
|
|
value: function render() {
|
|
return _react2['default'].createElement(
|
|
'div',
|
|
{ onTouchStart: this.touchStart.bind(this) },
|
|
_react2['default'].createElement(_componentsHeader2['default'], null),
|
|
_react2['default'].createElement(_componentsBreadcrumb2['default'], null),
|
|
_react2['default'].createElement(_componentsNavigation2['default'], null),
|
|
_react2['default'].createElement(_componentsFileList2['default'], null),
|
|
_react2['default'].createElement(_componentsToolbar2['default'], null),
|
|
_react2['default'].createElement(FileMenu, null),
|
|
_react2['default'].createElement(DirectoryMenu, null),
|
|
_react2['default'].createElement(RenameDialog, null),
|
|
_react2['default'].createElement(DeleteDialog, null),
|
|
_react2['default'].createElement(ErrorDialog, null),
|
|
_react2['default'].createElement(CreateDialog, null)
|
|
);
|
|
}
|
|
}, {
|
|
key: 'touchStart',
|
|
value: function touchStart(e) {
|
|
if (!e.target.closest('.menu')) {
|
|
_store2['default'].dispatch((0, _actionsMenu.hideAll)());
|
|
_store2['default'].dispatch((0, _actionsDialog.hideAll)());
|
|
}
|
|
}
|
|
}]);
|
|
|
|
return Root;
|
|
})(_react.Component);
|
|
|
|
exports['default'] = Root;
|
|
module.exports = exports['default'];
|
|
|
|
},{"actions/changedir":215,"actions/dialog":216,"actions/menu":220,"components/breadcrumb":225,"components/dialog":226,"components/file-list":228,"components/header":230,"components/menu":231,"components/navigation":232,"components/toolbar":234,"react":205,"react-redux":45,"store":"store"}],234:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
|
|
|
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var _react = require('react');
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _actionsFilesView = require('actions/files-view');
|
|
|
|
var _actionsDialog = require('actions/dialog');
|
|
|
|
var _store = require('store');
|
|
|
|
var _store2 = _interopRequireDefault(_store);
|
|
|
|
var Toolbar = (function (_Component) {
|
|
_inherits(Toolbar, _Component);
|
|
|
|
function Toolbar() {
|
|
_classCallCheck(this, Toolbar);
|
|
|
|
_get(Object.getPrototypeOf(Toolbar.prototype), 'constructor', this).apply(this, arguments);
|
|
}
|
|
|
|
_createClass(Toolbar, [{
|
|
key: 'render',
|
|
value: function render() {
|
|
return _react2['default'].createElement(
|
|
'div',
|
|
{ className: 'toolbar' },
|
|
_react2['default'].createElement('button', { className: 'icon-plus', onClick: this.newFile }),
|
|
_react2['default'].createElement('button', { className: 'icon-view', onClick: (0, _store.bind)((0, _actionsFilesView.toggle)()) }),
|
|
_react2['default'].createElement('button', { className: 'icon-refresh', onClick: (0, _store.bind)((0, _actionsFilesView.refresh)()) }),
|
|
_react2['default'].createElement('button', { className: 'icon-share', onClick: this.share }),
|
|
_react2['default'].createElement('button', { className: 'icon-more', onClick: this.showMore })
|
|
);
|
|
}
|
|
}, {
|
|
key: 'showMore',
|
|
value: function showMore() {}
|
|
}, {
|
|
key: 'newFile',
|
|
value: function newFile() {
|
|
var cwd = _store2['default'].getState().get('cwd');
|
|
var action = (0, _actionsDialog.show)('createDialog', {
|
|
description: 'Enter a name for the new file to be created in ' + cwd
|
|
});
|
|
_store2['default'].dispatch(action);
|
|
}
|
|
}]);
|
|
|
|
return Toolbar;
|
|
})(_react.Component);
|
|
|
|
exports['default'] = Toolbar;
|
|
module.exports = exports['default'];
|
|
|
|
},{"actions/dialog":216,"actions/files-view":218,"react":205,"store":"store"}],235:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _react = require('react');
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _actionsDialog = require('actions/dialog');
|
|
|
|
var _actionsFile = require('actions/file');
|
|
|
|
var _store = require('store');
|
|
|
|
var _store2 = _interopRequireDefault(_store);
|
|
|
|
exports['default'] = {
|
|
createDialog: {
|
|
title: 'Create',
|
|
description: 'Enter a name for the new file',
|
|
input: true,
|
|
buttons: [{
|
|
text: 'File',
|
|
action: function action() {
|
|
var input = _react2['default'].findDOMNode(this.refs.input);
|
|
|
|
var cwd = _store2['default'].getState().get('cwd');
|
|
var action = (0, _actionsFile.create)(cwd + input.value);
|
|
this.props.dispatch(action);
|
|
this.props.dispatch((0, _actionsDialog.hideAll)());
|
|
}
|
|
}, {
|
|
text: 'Directory',
|
|
action: function action() {
|
|
var input = _react2['default'].findDOMNode(this.refs.input);
|
|
|
|
var cwd = _store2['default'].getState().get('cwd');
|
|
var action = (0, _actionsFile.create)(cwd + input.value, true);
|
|
this.props.dispatch(action);
|
|
this.props.dispatch((0, _actionsDialog.hideAll)());
|
|
}
|
|
}]
|
|
},
|
|
renameDialog: {
|
|
title: 'Rename',
|
|
description: 'Enter the new name',
|
|
input: true,
|
|
buttons: [{
|
|
text: 'Cancel',
|
|
action: (0, _store.bind)((0, _actionsDialog.hideAll)())
|
|
}, {
|
|
text: 'Rename',
|
|
action: function action() {
|
|
var input = _react2['default'].findDOMNode(this.refs.input);
|
|
|
|
var activeFile = _store2['default'].getState().get('activeFile');
|
|
this.props.dispatch((0, _actionsFile.rename)(activeFile, input.value));
|
|
this.props.dispatch((0, _actionsDialog.hideAll)());
|
|
},
|
|
className: 'success'
|
|
}]
|
|
},
|
|
deleteDialog: {
|
|
title: 'Delete',
|
|
description: 'Are you sure you want to remove this file?',
|
|
buttons: [{
|
|
text: 'No',
|
|
action: (0, _store.bind)((0, _actionsDialog.hideAll)())
|
|
}, {
|
|
text: 'Yes',
|
|
action: function action() {
|
|
var activeFile = _store2['default'].getState().get('activeFile');
|
|
this.props.dispatch((0, _actionsFile.deleteFile)(activeFile));
|
|
this.props.dispatch((0, _actionsDialog.hideAll)());
|
|
},
|
|
className: 'success'
|
|
}]
|
|
},
|
|
errorDialog: {
|
|
title: 'Error',
|
|
buttons: [{
|
|
text: 'Continue',
|
|
action: (0, _store.bind)((0, _actionsDialog.hideAll)())
|
|
}]
|
|
}
|
|
};
|
|
module.exports = exports['default'];
|
|
|
|
},{"actions/dialog":216,"actions/file":217,"react":205,"store":"store"}],236:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _react = require('react');
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _componentsRoot = require('components/root');
|
|
|
|
var _componentsRoot2 = _interopRequireDefault(_componentsRoot);
|
|
|
|
var _store = require('store');
|
|
|
|
var _store2 = _interopRequireDefault(_store);
|
|
|
|
var _reactRedux = require('react-redux');
|
|
|
|
var wrapper = document.getElementById('wrapper');
|
|
_react2['default'].render(_react2['default'].createElement(
|
|
_reactRedux.Provider,
|
|
{ store: _store2['default'] },
|
|
function () {
|
|
return _react2['default'].createElement(_componentsRoot2['default'], null);
|
|
}
|
|
), wrapper);
|
|
|
|
},{"components/root":233,"react":205,"react-redux":45,"store":"store"}],237:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _actionsMenu = require('actions/menu');
|
|
|
|
var _actionsDialog = require('actions/dialog');
|
|
|
|
var _store = require('store');
|
|
|
|
var _store2 = _interopRequireDefault(_store);
|
|
|
|
var entryMenu = {
|
|
items: [{
|
|
name: 'Rename',
|
|
action: function action() {
|
|
var files = _store2['default'].getState().get('files');
|
|
var active = _store2['default'].getState().get('activeFile');
|
|
var name = files[active].name;
|
|
var description = 'Are you sure you want to remove ' + name + '?';
|
|
|
|
_store2['default'].dispatch((0, _actionsMenu.hideAll)());
|
|
_store2['default'].dispatch((0, _actionsDialog.show)('renameDialog', { description: description }));
|
|
}
|
|
}, {
|
|
name: 'Delete',
|
|
action: function action() {
|
|
var files = _store2['default'].getState().get('files');
|
|
var active = _store2['default'].getState().get('activeFile');
|
|
var name = files[active].name;
|
|
var description = 'Are you sure you want to remove ' + name + '?';
|
|
_store2['default'].dispatch((0, _actionsMenu.hideAll)());
|
|
_store2['default'].dispatch((0, _actionsDialog.show)('deleteDialog', { description: description }));
|
|
}
|
|
}]
|
|
};
|
|
|
|
exports['default'] = {
|
|
fileMenu: Object.assign({}, entryMenu),
|
|
directoryMenu: Object.assign({}, entryMenu)
|
|
};
|
|
module.exports = exports['default'];
|
|
|
|
},{"actions/dialog":216,"actions/menu":220,"store":"store"}],238:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
var _actionsTypes = require('actions/types');
|
|
|
|
exports['default'] = function (state, action) {
|
|
if (state === undefined) state = -1;
|
|
|
|
if (action.type === _actionsTypes.ACTIVE_FILE) {
|
|
return action.file;
|
|
}
|
|
|
|
return state;
|
|
};
|
|
|
|
module.exports = exports['default'];
|
|
|
|
},{"actions/types":223}],239:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _immutable = require('immutable');
|
|
|
|
var _immutable2 = _interopRequireDefault(_immutable);
|
|
|
|
var _cwd = require('./cwd');
|
|
|
|
var _cwd2 = _interopRequireDefault(_cwd);
|
|
|
|
var _lwd = require('./lwd');
|
|
|
|
var _lwd2 = _interopRequireDefault(_lwd);
|
|
|
|
var _files = require('./files');
|
|
|
|
var _files2 = _interopRequireDefault(_files);
|
|
|
|
var _navigation = require('./navigation');
|
|
|
|
var _navigation2 = _interopRequireDefault(_navigation);
|
|
|
|
var _activeFile = require('./active-file');
|
|
|
|
var _activeFile2 = _interopRequireDefault(_activeFile);
|
|
|
|
var _menu = require('./menu');
|
|
|
|
var _menu2 = _interopRequireDefault(_menu);
|
|
|
|
var _dialog = require('./dialog');
|
|
|
|
var _dialog2 = _interopRequireDefault(_dialog);
|
|
|
|
var _settings = require('./settings');
|
|
|
|
var _settings2 = _interopRequireDefault(_settings);
|
|
|
|
exports['default'] = function (state, action) {
|
|
if (state === undefined) state = new _immutable2['default'].Map();
|
|
|
|
console.log('action', action);
|
|
return new _immutable2['default'].Map({
|
|
lwd: (0, _lwd2['default'])(state, action), // last working directory
|
|
cwd: (0, _cwd2['default'])(state.get('cwd'), action),
|
|
files: (0, _files2['default'])(state.get('files'), action),
|
|
activeFile: (0, _activeFile2['default'])(state.get('activeFile'), action),
|
|
navigation: (0, _navigation2['default'])(state.get('navigation'), action),
|
|
settings: (0, _settings2['default'])(state.get('settings'), action),
|
|
fileMenu: (0, _menu2['default'])(state, action, 'fileMenu'),
|
|
directoryMenu: (0, _menu2['default'])(state, action, 'directoryMenu'),
|
|
renameDialog: (0, _dialog2['default'])(state, action, 'renameDialog'),
|
|
deleteDialog: (0, _dialog2['default'])(state, action, 'deleteDialog'),
|
|
errorDialog: (0, _dialog2['default'])(state, action, 'errorDialog'),
|
|
createDialog: (0, _dialog2['default'])(state, action, 'createDialog')
|
|
});
|
|
};
|
|
|
|
module.exports = exports['default'];
|
|
|
|
},{"./active-file":238,"./cwd":240,"./dialog":241,"./files":242,"./lwd":243,"./menu":244,"./navigation":245,"./settings":246,"immutable":247}],240:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _actionsTypes = require('actions/types');
|
|
|
|
var _actionsListFiles = require('actions/list-files');
|
|
|
|
var _actionsListFiles2 = _interopRequireDefault(_actionsListFiles);
|
|
|
|
var _apiFiles = require('api/files');
|
|
|
|
var _store = require('store');
|
|
|
|
var _store2 = _interopRequireDefault(_store);
|
|
|
|
var _utils = require('utils');
|
|
|
|
exports['default'] = function (state, action) {
|
|
if (state === undefined) state = '';
|
|
|
|
if (action.type === _actionsTypes.CHANGE_DIRECTORY) {
|
|
changeTo(action.dir);
|
|
|
|
return action.dir;
|
|
}
|
|
|
|
if (action.type === _actionsTypes.REFRESH || action.type === _actionsTypes.SETTINGS) {
|
|
changeTo(state);
|
|
|
|
return state;
|
|
}
|
|
|
|
return state;
|
|
};
|
|
|
|
function changeTo(dir) {
|
|
(0, _apiFiles.children)(dir, true).then(function (files) {
|
|
_store2['default'].dispatch((0, _actionsListFiles2['default'])(files));
|
|
}, _utils.reportError);
|
|
}
|
|
module.exports = exports['default'];
|
|
|
|
},{"actions/list-files":219,"actions/types":223,"api/files":224,"store":"store","utils":"utils"}],241:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _actionsTypes = require('actions/types');
|
|
|
|
var _immutable = require('immutable');
|
|
|
|
var _immutable2 = _interopRequireDefault(_immutable);
|
|
|
|
var _lodashObjectOmit = require('lodash/object/omit');
|
|
|
|
var _lodashObjectOmit2 = _interopRequireDefault(_lodashObjectOmit);
|
|
|
|
exports['default'] = function (state, action, id) {
|
|
if (state === undefined) state = new _immutable2['default'].Map({});
|
|
|
|
if (action.type === _actionsTypes.DIALOG) {
|
|
var useful = (0, _lodashObjectOmit2['default'])(action, ['id', 'type']);
|
|
// action applied to all dialogs
|
|
if (!action.id) {
|
|
return Object.assign({}, state.get(id), useful);
|
|
}
|
|
|
|
if (action.id !== id) return state.get(id);
|
|
|
|
var target = state.get(action.id);
|
|
var active = action.active === 'toggle' ? !target.get('active') : action.active;
|
|
|
|
return Object.assign({}, target, useful);
|
|
} else {
|
|
return state.get(id);
|
|
}
|
|
};
|
|
|
|
module.exports = exports['default'];
|
|
|
|
},{"actions/types":223,"immutable":247,"lodash/object/omit":37}],242:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _actionsTypes = require('actions/types');
|
|
|
|
var _actionsFilesView = require('actions/files-view');
|
|
|
|
var _apiFiles = require('api/files');
|
|
|
|
var _actionsDialog = require('actions/dialog');
|
|
|
|
var _store = require('store');
|
|
|
|
var _store2 = _interopRequireDefault(_store);
|
|
|
|
var _utils = require('utils');
|
|
|
|
var boundRefresh = (0, _store.bind)((0, _actionsFilesView.refresh)());
|
|
|
|
exports['default'] = function (state, action) {
|
|
if (state === undefined) state = [];
|
|
|
|
if (action.type === _actionsTypes.LIST_FILES) {
|
|
return action.files;
|
|
}
|
|
|
|
if (action.type === _actionsTypes.CREATE_FILE) {
|
|
var fn = action.directory ? _apiFiles.createDirectory : _apiFiles.createFile;
|
|
fn(action.path).then(boundRefresh, _utils.reportError);
|
|
|
|
return state;
|
|
}
|
|
|
|
if (action.type === _actionsTypes.RENAME_FILE) {
|
|
var file = state[action.file];
|
|
|
|
(0, _apiFiles.move)(file, (file.path || '') + action.name).then(boundRefresh, _utils.reportError);
|
|
|
|
return state;
|
|
}
|
|
|
|
if (action.type === _actionsTypes.DELETE_FILE) {
|
|
var file = state[action.file];
|
|
|
|
(0, _apiFiles.sdcard)()['delete']((file.path || '') + '/' + file.name);
|
|
var copy = state.slice(0);
|
|
copy.splice(action.file, 1);
|
|
return copy;
|
|
}
|
|
|
|
return state;
|
|
};
|
|
|
|
module.exports = exports['default'];
|
|
|
|
},{"actions/dialog":216,"actions/files-view":218,"actions/types":223,"api/files":224,"store":"store","utils":"utils"}],243:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
var _actionsTypes = require('actions/types');
|
|
|
|
exports['default'] = function (state, action) {
|
|
if (state === undefined) state = '';
|
|
|
|
if (action.type === _actionsTypes.CHANGE_DIRECTORY) {
|
|
return state.get('cwd');
|
|
}
|
|
return state.get('lwd');
|
|
};
|
|
|
|
module.exports = exports['default'];
|
|
|
|
},{"actions/types":223}],244:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _actionsTypes = require('actions/types');
|
|
|
|
var _immutable = require('immutable');
|
|
|
|
var _immutable2 = _interopRequireDefault(_immutable);
|
|
|
|
var _lodashObjectOmit = require('lodash/object/omit');
|
|
|
|
var _lodashObjectOmit2 = _interopRequireDefault(_lodashObjectOmit);
|
|
|
|
exports['default'] = function (state, action, id) {
|
|
if (state === undefined) state = new _immutable2['default'].Map({});
|
|
|
|
if (action.type === _actionsTypes.MENU) {
|
|
var useful = (0, _lodashObjectOmit2['default'])(action, ['id', 'type']);
|
|
// action applied to all menus
|
|
if (!action.id) {
|
|
return Object.assign({}, state.get(id), useful);
|
|
}
|
|
|
|
if (action.id !== id) return state.get(id);
|
|
|
|
var target = state.get(action.id);
|
|
var active = action.active === 'toggle' ? !target.get('active') : action.active;
|
|
|
|
return Object.assign({}, target, useful);
|
|
} else {
|
|
return state.get(id);
|
|
}
|
|
};
|
|
|
|
module.exports = exports['default'];
|
|
|
|
},{"actions/types":223,"immutable":247,"lodash/object/omit":37}],245:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
var _actionsTypes = require('actions/types');
|
|
|
|
exports['default'] = function (state, action) {
|
|
if (state === undefined) state = false;
|
|
|
|
if (action.type === _actionsTypes.NAVIGATION) {
|
|
return action.active === _actionsTypes.TOGGLE ? !state : action.active;
|
|
}
|
|
|
|
return state;
|
|
};
|
|
|
|
module.exports = exports['default'];
|
|
|
|
},{"actions/types":223}],246:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _actionsTypes = require('actions/types');
|
|
|
|
var _lodashObjectOmit = require('lodash/object/omit');
|
|
|
|
var _lodashObjectOmit2 = _interopRequireDefault(_lodashObjectOmit);
|
|
|
|
var DEFAULT = {
|
|
showHiddenFiles: false,
|
|
showDirectoriesFirst: true
|
|
};
|
|
|
|
exports['default'] = function (state, action) {
|
|
if (state === undefined) state = DEFAULT;
|
|
|
|
if (action.type === _actionsTypes.SETTINGS) {
|
|
return Object.assign({}, state, (0, _lodashObjectOmit2['default'])(action, 'type'));
|
|
}
|
|
|
|
return state;
|
|
};
|
|
|
|
module.exports = exports['default'];
|
|
|
|
},{"actions/types":223,"lodash/object/omit":37}],247:[function(require,module,exports){
|
|
/**
|
|
* Copyright (c) 2014-2015, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*/
|
|
(function (global, factory) {
|
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
typeof define === 'function' && define.amd ? define(factory) :
|
|
global.Immutable = factory()
|
|
}(this, function () { 'use strict';var SLICE$0 = Array.prototype.slice;
|
|
|
|
function createClass(ctor, superClass) {
|
|
if (superClass) {
|
|
ctor.prototype = Object.create(superClass.prototype);
|
|
}
|
|
ctor.prototype.constructor = ctor;
|
|
}
|
|
|
|
// Used for setting prototype methods that IE8 chokes on.
|
|
var DELETE = 'delete';
|
|
|
|
// Constants describing the size of trie nodes.
|
|
var SHIFT = 5; // Resulted in best performance after ______?
|
|
var SIZE = 1 << SHIFT;
|
|
var MASK = SIZE - 1;
|
|
|
|
// A consistent shared value representing "not set" which equals nothing other
|
|
// than itself, and nothing that could be provided externally.
|
|
var NOT_SET = {};
|
|
|
|
// Boolean references, Rough equivalent of `bool &`.
|
|
var CHANGE_LENGTH = { value: false };
|
|
var DID_ALTER = { value: false };
|
|
|
|
function MakeRef(ref) {
|
|
ref.value = false;
|
|
return ref;
|
|
}
|
|
|
|
function SetRef(ref) {
|
|
ref && (ref.value = true);
|
|
}
|
|
|
|
// A function which returns a value representing an "owner" for transient writes
|
|
// to tries. The return value will only ever equal itself, and will not equal
|
|
// the return of any subsequent call of this function.
|
|
function OwnerID() {}
|
|
|
|
// http://jsperf.com/copy-array-inline
|
|
function arrCopy(arr, offset) {
|
|
offset = offset || 0;
|
|
var len = Math.max(0, arr.length - offset);
|
|
var newArr = new Array(len);
|
|
for (var ii = 0; ii < len; ii++) {
|
|
newArr[ii] = arr[ii + offset];
|
|
}
|
|
return newArr;
|
|
}
|
|
|
|
function ensureSize(iter) {
|
|
if (iter.size === undefined) {
|
|
iter.size = iter.__iterate(returnTrue);
|
|
}
|
|
return iter.size;
|
|
}
|
|
|
|
function wrapIndex(iter, index) {
|
|
return index >= 0 ? (+index) : ensureSize(iter) + (+index);
|
|
}
|
|
|
|
function returnTrue() {
|
|
return true;
|
|
}
|
|
|
|
function wholeSlice(begin, end, size) {
|
|
return (begin === 0 || (size !== undefined && begin <= -size)) &&
|
|
(end === undefined || (size !== undefined && end >= size));
|
|
}
|
|
|
|
function resolveBegin(begin, size) {
|
|
return resolveIndex(begin, size, 0);
|
|
}
|
|
|
|
function resolveEnd(end, size) {
|
|
return resolveIndex(end, size, size);
|
|
}
|
|
|
|
function resolveIndex(index, size, defaultIndex) {
|
|
return index === undefined ?
|
|
defaultIndex :
|
|
index < 0 ?
|
|
Math.max(0, size + index) :
|
|
size === undefined ?
|
|
index :
|
|
Math.min(size, index);
|
|
}
|
|
|
|
function Iterable(value) {
|
|
return isIterable(value) ? value : Seq(value);
|
|
}
|
|
|
|
|
|
createClass(KeyedIterable, Iterable);
|
|
function KeyedIterable(value) {
|
|
return isKeyed(value) ? value : KeyedSeq(value);
|
|
}
|
|
|
|
|
|
createClass(IndexedIterable, Iterable);
|
|
function IndexedIterable(value) {
|
|
return isIndexed(value) ? value : IndexedSeq(value);
|
|
}
|
|
|
|
|
|
createClass(SetIterable, Iterable);
|
|
function SetIterable(value) {
|
|
return isIterable(value) && !isAssociative(value) ? value : SetSeq(value);
|
|
}
|
|
|
|
|
|
|
|
function isIterable(maybeIterable) {
|
|
return !!(maybeIterable && maybeIterable[IS_ITERABLE_SENTINEL]);
|
|
}
|
|
|
|
function isKeyed(maybeKeyed) {
|
|
return !!(maybeKeyed && maybeKeyed[IS_KEYED_SENTINEL]);
|
|
}
|
|
|
|
function isIndexed(maybeIndexed) {
|
|
return !!(maybeIndexed && maybeIndexed[IS_INDEXED_SENTINEL]);
|
|
}
|
|
|
|
function isAssociative(maybeAssociative) {
|
|
return isKeyed(maybeAssociative) || isIndexed(maybeAssociative);
|
|
}
|
|
|
|
function isOrdered(maybeOrdered) {
|
|
return !!(maybeOrdered && maybeOrdered[IS_ORDERED_SENTINEL]);
|
|
}
|
|
|
|
Iterable.isIterable = isIterable;
|
|
Iterable.isKeyed = isKeyed;
|
|
Iterable.isIndexed = isIndexed;
|
|
Iterable.isAssociative = isAssociative;
|
|
Iterable.isOrdered = isOrdered;
|
|
|
|
Iterable.Keyed = KeyedIterable;
|
|
Iterable.Indexed = IndexedIterable;
|
|
Iterable.Set = SetIterable;
|
|
|
|
|
|
var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@';
|
|
var IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@';
|
|
var IS_INDEXED_SENTINEL = '@@__IMMUTABLE_INDEXED__@@';
|
|
var IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@';
|
|
|
|
/* global Symbol */
|
|
|
|
var ITERATE_KEYS = 0;
|
|
var ITERATE_VALUES = 1;
|
|
var ITERATE_ENTRIES = 2;
|
|
|
|
var REAL_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
|
|
var FAUX_ITERATOR_SYMBOL = '@@iterator';
|
|
|
|
var ITERATOR_SYMBOL = REAL_ITERATOR_SYMBOL || FAUX_ITERATOR_SYMBOL;
|
|
|
|
|
|
function src_Iterator__Iterator(next) {
|
|
this.next = next;
|
|
}
|
|
|
|
src_Iterator__Iterator.prototype.toString = function() {
|
|
return '[Iterator]';
|
|
};
|
|
|
|
|
|
src_Iterator__Iterator.KEYS = ITERATE_KEYS;
|
|
src_Iterator__Iterator.VALUES = ITERATE_VALUES;
|
|
src_Iterator__Iterator.ENTRIES = ITERATE_ENTRIES;
|
|
|
|
src_Iterator__Iterator.prototype.inspect =
|
|
src_Iterator__Iterator.prototype.toSource = function () { return this.toString(); }
|
|
src_Iterator__Iterator.prototype[ITERATOR_SYMBOL] = function () {
|
|
return this;
|
|
};
|
|
|
|
|
|
function iteratorValue(type, k, v, iteratorResult) {
|
|
var value = type === 0 ? k : type === 1 ? v : [k, v];
|
|
iteratorResult ? (iteratorResult.value = value) : (iteratorResult = {
|
|
value: value, done: false
|
|
});
|
|
return iteratorResult;
|
|
}
|
|
|
|
function iteratorDone() {
|
|
return { value: undefined, done: true };
|
|
}
|
|
|
|
function hasIterator(maybeIterable) {
|
|
return !!getIteratorFn(maybeIterable);
|
|
}
|
|
|
|
function isIterator(maybeIterator) {
|
|
return maybeIterator && typeof maybeIterator.next === 'function';
|
|
}
|
|
|
|
function getIterator(iterable) {
|
|
var iteratorFn = getIteratorFn(iterable);
|
|
return iteratorFn && iteratorFn.call(iterable);
|
|
}
|
|
|
|
function getIteratorFn(iterable) {
|
|
var iteratorFn = iterable && (
|
|
(REAL_ITERATOR_SYMBOL && iterable[REAL_ITERATOR_SYMBOL]) ||
|
|
iterable[FAUX_ITERATOR_SYMBOL]
|
|
);
|
|
if (typeof iteratorFn === 'function') {
|
|
return iteratorFn;
|
|
}
|
|
}
|
|
|
|
function isArrayLike(value) {
|
|
return value && typeof value.length === 'number';
|
|
}
|
|
|
|
createClass(Seq, Iterable);
|
|
function Seq(value) {
|
|
return value === null || value === undefined ? emptySequence() :
|
|
isIterable(value) ? value.toSeq() : seqFromValue(value);
|
|
}
|
|
|
|
Seq.of = function(/*...values*/) {
|
|
return Seq(arguments);
|
|
};
|
|
|
|
Seq.prototype.toSeq = function() {
|
|
return this;
|
|
};
|
|
|
|
Seq.prototype.toString = function() {
|
|
return this.__toString('Seq {', '}');
|
|
};
|
|
|
|
Seq.prototype.cacheResult = function() {
|
|
if (!this._cache && this.__iterateUncached) {
|
|
this._cache = this.entrySeq().toArray();
|
|
this.size = this._cache.length;
|
|
}
|
|
return this;
|
|
};
|
|
|
|
// abstract __iterateUncached(fn, reverse)
|
|
|
|
Seq.prototype.__iterate = function(fn, reverse) {
|
|
return seqIterate(this, fn, reverse, true);
|
|
};
|
|
|
|
// abstract __iteratorUncached(type, reverse)
|
|
|
|
Seq.prototype.__iterator = function(type, reverse) {
|
|
return seqIterator(this, type, reverse, true);
|
|
};
|
|
|
|
|
|
|
|
createClass(KeyedSeq, Seq);
|
|
function KeyedSeq(value) {
|
|
return value === null || value === undefined ?
|
|
emptySequence().toKeyedSeq() :
|
|
isIterable(value) ?
|
|
(isKeyed(value) ? value.toSeq() : value.fromEntrySeq()) :
|
|
keyedSeqFromValue(value);
|
|
}
|
|
|
|
KeyedSeq.prototype.toKeyedSeq = function() {
|
|
return this;
|
|
};
|
|
|
|
|
|
|
|
createClass(IndexedSeq, Seq);
|
|
function IndexedSeq(value) {
|
|
return value === null || value === undefined ? emptySequence() :
|
|
!isIterable(value) ? indexedSeqFromValue(value) :
|
|
isKeyed(value) ? value.entrySeq() : value.toIndexedSeq();
|
|
}
|
|
|
|
IndexedSeq.of = function(/*...values*/) {
|
|
return IndexedSeq(arguments);
|
|
};
|
|
|
|
IndexedSeq.prototype.toIndexedSeq = function() {
|
|
return this;
|
|
};
|
|
|
|
IndexedSeq.prototype.toString = function() {
|
|
return this.__toString('Seq [', ']');
|
|
};
|
|
|
|
IndexedSeq.prototype.__iterate = function(fn, reverse) {
|
|
return seqIterate(this, fn, reverse, false);
|
|
};
|
|
|
|
IndexedSeq.prototype.__iterator = function(type, reverse) {
|
|
return seqIterator(this, type, reverse, false);
|
|
};
|
|
|
|
|
|
|
|
createClass(SetSeq, Seq);
|
|
function SetSeq(value) {
|
|
return (
|
|
value === null || value === undefined ? emptySequence() :
|
|
!isIterable(value) ? indexedSeqFromValue(value) :
|
|
isKeyed(value) ? value.entrySeq() : value
|
|
).toSetSeq();
|
|
}
|
|
|
|
SetSeq.of = function(/*...values*/) {
|
|
return SetSeq(arguments);
|
|
};
|
|
|
|
SetSeq.prototype.toSetSeq = function() {
|
|
return this;
|
|
};
|
|
|
|
|
|
|
|
Seq.isSeq = isSeq;
|
|
Seq.Keyed = KeyedSeq;
|
|
Seq.Set = SetSeq;
|
|
Seq.Indexed = IndexedSeq;
|
|
|
|
var IS_SEQ_SENTINEL = '@@__IMMUTABLE_SEQ__@@';
|
|
|
|
Seq.prototype[IS_SEQ_SENTINEL] = true;
|
|
|
|
|
|
|
|
// #pragma Root Sequences
|
|
|
|
createClass(ArraySeq, IndexedSeq);
|
|
function ArraySeq(array) {
|
|
this._array = array;
|
|
this.size = array.length;
|
|
}
|
|
|
|
ArraySeq.prototype.get = function(index, notSetValue) {
|
|
return this.has(index) ? this._array[wrapIndex(this, index)] : notSetValue;
|
|
};
|
|
|
|
ArraySeq.prototype.__iterate = function(fn, reverse) {
|
|
var array = this._array;
|
|
var maxIndex = array.length - 1;
|
|
for (var ii = 0; ii <= maxIndex; ii++) {
|
|
if (fn(array[reverse ? maxIndex - ii : ii], ii, this) === false) {
|
|
return ii + 1;
|
|
}
|
|
}
|
|
return ii;
|
|
};
|
|
|
|
ArraySeq.prototype.__iterator = function(type, reverse) {
|
|
var array = this._array;
|
|
var maxIndex = array.length - 1;
|
|
var ii = 0;
|
|
return new src_Iterator__Iterator(function()
|
|
{return ii > maxIndex ?
|
|
iteratorDone() :
|
|
iteratorValue(type, ii, array[reverse ? maxIndex - ii++ : ii++])}
|
|
);
|
|
};
|
|
|
|
|
|
|
|
createClass(ObjectSeq, KeyedSeq);
|
|
function ObjectSeq(object) {
|
|
var keys = Object.keys(object);
|
|
this._object = object;
|
|
this._keys = keys;
|
|
this.size = keys.length;
|
|
}
|
|
|
|
ObjectSeq.prototype.get = function(key, notSetValue) {
|
|
if (notSetValue !== undefined && !this.has(key)) {
|
|
return notSetValue;
|
|
}
|
|
return this._object[key];
|
|
};
|
|
|
|
ObjectSeq.prototype.has = function(key) {
|
|
return this._object.hasOwnProperty(key);
|
|
};
|
|
|
|
ObjectSeq.prototype.__iterate = function(fn, reverse) {
|
|
var object = this._object;
|
|
var keys = this._keys;
|
|
var maxIndex = keys.length - 1;
|
|
for (var ii = 0; ii <= maxIndex; ii++) {
|
|
var key = keys[reverse ? maxIndex - ii : ii];
|
|
if (fn(object[key], key, this) === false) {
|
|
return ii + 1;
|
|
}
|
|
}
|
|
return ii;
|
|
};
|
|
|
|
ObjectSeq.prototype.__iterator = function(type, reverse) {
|
|
var object = this._object;
|
|
var keys = this._keys;
|
|
var maxIndex = keys.length - 1;
|
|
var ii = 0;
|
|
return new src_Iterator__Iterator(function() {
|
|
var key = keys[reverse ? maxIndex - ii : ii];
|
|
return ii++ > maxIndex ?
|
|
iteratorDone() :
|
|
iteratorValue(type, key, object[key]);
|
|
});
|
|
};
|
|
|
|
ObjectSeq.prototype[IS_ORDERED_SENTINEL] = true;
|
|
|
|
|
|
createClass(IterableSeq, IndexedSeq);
|
|
function IterableSeq(iterable) {
|
|
this._iterable = iterable;
|
|
this.size = iterable.length || iterable.size;
|
|
}
|
|
|
|
IterableSeq.prototype.__iterateUncached = function(fn, reverse) {
|
|
if (reverse) {
|
|
return this.cacheResult().__iterate(fn, reverse);
|
|
}
|
|
var iterable = this._iterable;
|
|
var iterator = getIterator(iterable);
|
|
var iterations = 0;
|
|
if (isIterator(iterator)) {
|
|
var step;
|
|
while (!(step = iterator.next()).done) {
|
|
if (fn(step.value, iterations++, this) === false) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return iterations;
|
|
};
|
|
|
|
IterableSeq.prototype.__iteratorUncached = function(type, reverse) {
|
|
if (reverse) {
|
|
return this.cacheResult().__iterator(type, reverse);
|
|
}
|
|
var iterable = this._iterable;
|
|
var iterator = getIterator(iterable);
|
|
if (!isIterator(iterator)) {
|
|
return new src_Iterator__Iterator(iteratorDone);
|
|
}
|
|
var iterations = 0;
|
|
return new src_Iterator__Iterator(function() {
|
|
var step = iterator.next();
|
|
return step.done ? step : iteratorValue(type, iterations++, step.value);
|
|
});
|
|
};
|
|
|
|
|
|
|
|
createClass(IteratorSeq, IndexedSeq);
|
|
function IteratorSeq(iterator) {
|
|
this._iterator = iterator;
|
|
this._iteratorCache = [];
|
|
}
|
|
|
|
IteratorSeq.prototype.__iterateUncached = function(fn, reverse) {
|
|
if (reverse) {
|
|
return this.cacheResult().__iterate(fn, reverse);
|
|
}
|
|
var iterator = this._iterator;
|
|
var cache = this._iteratorCache;
|
|
var iterations = 0;
|
|
while (iterations < cache.length) {
|
|
if (fn(cache[iterations], iterations++, this) === false) {
|
|
return iterations;
|
|
}
|
|
}
|
|
var step;
|
|
while (!(step = iterator.next()).done) {
|
|
var val = step.value;
|
|
cache[iterations] = val;
|
|
if (fn(val, iterations++, this) === false) {
|
|
break;
|
|
}
|
|
}
|
|
return iterations;
|
|
};
|
|
|
|
IteratorSeq.prototype.__iteratorUncached = function(type, reverse) {
|
|
if (reverse) {
|
|
return this.cacheResult().__iterator(type, reverse);
|
|
}
|
|
var iterator = this._iterator;
|
|
var cache = this._iteratorCache;
|
|
var iterations = 0;
|
|
return new src_Iterator__Iterator(function() {
|
|
if (iterations >= cache.length) {
|
|
var step = iterator.next();
|
|
if (step.done) {
|
|
return step;
|
|
}
|
|
cache[iterations] = step.value;
|
|
}
|
|
return iteratorValue(type, iterations, cache[iterations++]);
|
|
});
|
|
};
|
|
|
|
|
|
|
|
|
|
// # pragma Helper functions
|
|
|
|
function isSeq(maybeSeq) {
|
|
return !!(maybeSeq && maybeSeq[IS_SEQ_SENTINEL]);
|
|
}
|
|
|
|
var EMPTY_SEQ;
|
|
|
|
function emptySequence() {
|
|
return EMPTY_SEQ || (EMPTY_SEQ = new ArraySeq([]));
|
|
}
|
|
|
|
function keyedSeqFromValue(value) {
|
|
var seq =
|
|
Array.isArray(value) ? new ArraySeq(value).fromEntrySeq() :
|
|
isIterator(value) ? new IteratorSeq(value).fromEntrySeq() :
|
|
hasIterator(value) ? new IterableSeq(value).fromEntrySeq() :
|
|
typeof value === 'object' ? new ObjectSeq(value) :
|
|
undefined;
|
|
if (!seq) {
|
|
throw new TypeError(
|
|
'Expected Array or iterable object of [k, v] entries, '+
|
|
'or keyed object: ' + value
|
|
);
|
|
}
|
|
return seq;
|
|
}
|
|
|
|
function indexedSeqFromValue(value) {
|
|
var seq = maybeIndexedSeqFromValue(value);
|
|
if (!seq) {
|
|
throw new TypeError(
|
|
'Expected Array or iterable object of values: ' + value
|
|
);
|
|
}
|
|
return seq;
|
|
}
|
|
|
|
function seqFromValue(value) {
|
|
var seq = maybeIndexedSeqFromValue(value) ||
|
|
(typeof value === 'object' && new ObjectSeq(value));
|
|
if (!seq) {
|
|
throw new TypeError(
|
|
'Expected Array or iterable object of values, or keyed object: ' + value
|
|
);
|
|
}
|
|
return seq;
|
|
}
|
|
|
|
function maybeIndexedSeqFromValue(value) {
|
|
return (
|
|
isArrayLike(value) ? new ArraySeq(value) :
|
|
isIterator(value) ? new IteratorSeq(value) :
|
|
hasIterator(value) ? new IterableSeq(value) :
|
|
undefined
|
|
);
|
|
}
|
|
|
|
function seqIterate(seq, fn, reverse, useKeys) {
|
|
var cache = seq._cache;
|
|
if (cache) {
|
|
var maxIndex = cache.length - 1;
|
|
for (var ii = 0; ii <= maxIndex; ii++) {
|
|
var entry = cache[reverse ? maxIndex - ii : ii];
|
|
if (fn(entry[1], useKeys ? entry[0] : ii, seq) === false) {
|
|
return ii + 1;
|
|
}
|
|
}
|
|
return ii;
|
|
}
|
|
return seq.__iterateUncached(fn, reverse);
|
|
}
|
|
|
|
function seqIterator(seq, type, reverse, useKeys) {
|
|
var cache = seq._cache;
|
|
if (cache) {
|
|
var maxIndex = cache.length - 1;
|
|
var ii = 0;
|
|
return new src_Iterator__Iterator(function() {
|
|
var entry = cache[reverse ? maxIndex - ii : ii];
|
|
return ii++ > maxIndex ?
|
|
iteratorDone() :
|
|
iteratorValue(type, useKeys ? entry[0] : ii - 1, entry[1]);
|
|
});
|
|
}
|
|
return seq.__iteratorUncached(type, reverse);
|
|
}
|
|
|
|
createClass(Collection, Iterable);
|
|
function Collection() {
|
|
throw TypeError('Abstract');
|
|
}
|
|
|
|
|
|
createClass(KeyedCollection, Collection);function KeyedCollection() {}
|
|
|
|
createClass(IndexedCollection, Collection);function IndexedCollection() {}
|
|
|
|
createClass(SetCollection, Collection);function SetCollection() {}
|
|
|
|
|
|
Collection.Keyed = KeyedCollection;
|
|
Collection.Indexed = IndexedCollection;
|
|
Collection.Set = SetCollection;
|
|
|
|
/**
|
|
* An extension of the "same-value" algorithm as [described for use by ES6 Map
|
|
* and Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#Key_equality)
|
|
*
|
|
* NaN is considered the same as NaN, however -0 and 0 are considered the same
|
|
* value, which is different from the algorithm described by
|
|
* [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is).
|
|
*
|
|
* This is extended further to allow Objects to describe the values they
|
|
* represent, by way of `valueOf` or `equals` (and `hashCode`).
|
|
*
|
|
* Note: because of this extension, the key equality of Immutable.Map and the
|
|
* value equality of Immutable.Set will differ from ES6 Map and Set.
|
|
*
|
|
* ### Defining custom values
|
|
*
|
|
* The easiest way to describe the value an object represents is by implementing
|
|
* `valueOf`. For example, `Date` represents a value by returning a unix
|
|
* timestamp for `valueOf`:
|
|
*
|
|
* var date1 = new Date(1234567890000); // Fri Feb 13 2009 ...
|
|
* var date2 = new Date(1234567890000);
|
|
* date1.valueOf(); // 1234567890000
|
|
* assert( date1 !== date2 );
|
|
* assert( Immutable.is( date1, date2 ) );
|
|
*
|
|
* Note: overriding `valueOf` may have other implications if you use this object
|
|
* where JavaScript expects a primitive, such as implicit string coercion.
|
|
*
|
|
* For more complex types, especially collections, implementing `valueOf` may
|
|
* not be performant. An alternative is to implement `equals` and `hashCode`.
|
|
*
|
|
* `equals` takes another object, presumably of similar type, and returns true
|
|
* if the it is equal. Equality is symmetrical, so the same result should be
|
|
* returned if this and the argument are flipped.
|
|
*
|
|
* assert( a.equals(b) === b.equals(a) );
|
|
*
|
|
* `hashCode` returns a 32bit integer number representing the object which will
|
|
* be used to determine how to store the value object in a Map or Set. You must
|
|
* provide both or neither methods, one must not exist without the other.
|
|
*
|
|
* Also, an important relationship between these methods must be upheld: if two
|
|
* values are equal, they *must* return the same hashCode. If the values are not
|
|
* equal, they might have the same hashCode; this is called a hash collision,
|
|
* and while undesirable for performance reasons, it is acceptable.
|
|
*
|
|
* if (a.equals(b)) {
|
|
* assert( a.hashCode() === b.hashCode() );
|
|
* }
|
|
*
|
|
* All Immutable collections implement `equals` and `hashCode`.
|
|
*
|
|
*/
|
|
function is(valueA, valueB) {
|
|
if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) {
|
|
return true;
|
|
}
|
|
if (!valueA || !valueB) {
|
|
return false;
|
|
}
|
|
if (typeof valueA.valueOf === 'function' &&
|
|
typeof valueB.valueOf === 'function') {
|
|
valueA = valueA.valueOf();
|
|
valueB = valueB.valueOf();
|
|
if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) {
|
|
return true;
|
|
}
|
|
if (!valueA || !valueB) {
|
|
return false;
|
|
}
|
|
}
|
|
if (typeof valueA.equals === 'function' &&
|
|
typeof valueB.equals === 'function' &&
|
|
valueA.equals(valueB)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function fromJS(json, converter) {
|
|
return converter ?
|
|
fromJSWith(converter, json, '', {'': json}) :
|
|
fromJSDefault(json);
|
|
}
|
|
|
|
function fromJSWith(converter, json, key, parentJSON) {
|
|
if (Array.isArray(json)) {
|
|
return converter.call(parentJSON, key, IndexedSeq(json).map(function(v, k) {return fromJSWith(converter, v, k, json)}));
|
|
}
|
|
if (isPlainObj(json)) {
|
|
return converter.call(parentJSON, key, KeyedSeq(json).map(function(v, k) {return fromJSWith(converter, v, k, json)}));
|
|
}
|
|
return json;
|
|
}
|
|
|
|
function fromJSDefault(json) {
|
|
if (Array.isArray(json)) {
|
|
return IndexedSeq(json).map(fromJSDefault).toList();
|
|
}
|
|
if (isPlainObj(json)) {
|
|
return KeyedSeq(json).map(fromJSDefault).toMap();
|
|
}
|
|
return json;
|
|
}
|
|
|
|
function isPlainObj(value) {
|
|
return value && (value.constructor === Object || value.constructor === undefined);
|
|
}
|
|
|
|
var src_Math__imul =
|
|
typeof Math.imul === 'function' && Math.imul(0xffffffff, 2) === -2 ?
|
|
Math.imul :
|
|
function src_Math__imul(a, b) {
|
|
a = a | 0; // int
|
|
b = b | 0; // int
|
|
var c = a & 0xffff;
|
|
var d = b & 0xffff;
|
|
// Shift by 0 fixes the sign on the high part.
|
|
return (c * d) + ((((a >>> 16) * d + c * (b >>> 16)) << 16) >>> 0) | 0; // int
|
|
};
|
|
|
|
// v8 has an optimization for storing 31-bit signed numbers.
|
|
// Values which have either 00 or 11 as the high order bits qualify.
|
|
// This function drops the highest order bit in a signed number, maintaining
|
|
// the sign bit.
|
|
function smi(i32) {
|
|
return ((i32 >>> 1) & 0x40000000) | (i32 & 0xBFFFFFFF);
|
|
}
|
|
|
|
function hash(o) {
|
|
if (o === false || o === null || o === undefined) {
|
|
return 0;
|
|
}
|
|
if (typeof o.valueOf === 'function') {
|
|
o = o.valueOf();
|
|
if (o === false || o === null || o === undefined) {
|
|
return 0;
|
|
}
|
|
}
|
|
if (o === true) {
|
|
return 1;
|
|
}
|
|
var type = typeof o;
|
|
if (type === 'number') {
|
|
var h = o | 0;
|
|
if (h !== o) {
|
|
h ^= o * 0xFFFFFFFF;
|
|
}
|
|
while (o > 0xFFFFFFFF) {
|
|
o /= 0xFFFFFFFF;
|
|
h ^= o;
|
|
}
|
|
return smi(h);
|
|
}
|
|
if (type === 'string') {
|
|
return o.length > STRING_HASH_CACHE_MIN_STRLEN ? cachedHashString(o) : hashString(o);
|
|
}
|
|
if (typeof o.hashCode === 'function') {
|
|
return o.hashCode();
|
|
}
|
|
return hashJSObj(o);
|
|
}
|
|
|
|
function cachedHashString(string) {
|
|
var hash = stringHashCache[string];
|
|
if (hash === undefined) {
|
|
hash = hashString(string);
|
|
if (STRING_HASH_CACHE_SIZE === STRING_HASH_CACHE_MAX_SIZE) {
|
|
STRING_HASH_CACHE_SIZE = 0;
|
|
stringHashCache = {};
|
|
}
|
|
STRING_HASH_CACHE_SIZE++;
|
|
stringHashCache[string] = hash;
|
|
}
|
|
return hash;
|
|
}
|
|
|
|
// http://jsperf.com/hashing-strings
|
|
function hashString(string) {
|
|
// This is the hash from JVM
|
|
// The hash code for a string is computed as
|
|
// s[0] * 31 ^ (n - 1) + s[1] * 31 ^ (n - 2) + ... + s[n - 1],
|
|
// where s[i] is the ith character of the string and n is the length of
|
|
// the string. We "mod" the result to make it between 0 (inclusive) and 2^31
|
|
// (exclusive) by dropping high bits.
|
|
var hash = 0;
|
|
for (var ii = 0; ii < string.length; ii++) {
|
|
hash = 31 * hash + string.charCodeAt(ii) | 0;
|
|
}
|
|
return smi(hash);
|
|
}
|
|
|
|
function hashJSObj(obj) {
|
|
var hash;
|
|
if (usingWeakMap) {
|
|
hash = weakMap.get(obj);
|
|
if (hash !== undefined) {
|
|
return hash;
|
|
}
|
|
}
|
|
|
|
hash = obj[UID_HASH_KEY];
|
|
if (hash !== undefined) {
|
|
return hash;
|
|
}
|
|
|
|
if (!canDefineProperty) {
|
|
hash = obj.propertyIsEnumerable && obj.propertyIsEnumerable[UID_HASH_KEY];
|
|
if (hash !== undefined) {
|
|
return hash;
|
|
}
|
|
|
|
hash = getIENodeHash(obj);
|
|
if (hash !== undefined) {
|
|
return hash;
|
|
}
|
|
}
|
|
|
|
hash = ++objHashUID;
|
|
if (objHashUID & 0x40000000) {
|
|
objHashUID = 0;
|
|
}
|
|
|
|
if (usingWeakMap) {
|
|
weakMap.set(obj, hash);
|
|
} else if (isExtensible !== undefined && isExtensible(obj) === false) {
|
|
throw new Error('Non-extensible objects are not allowed as keys.');
|
|
} else if (canDefineProperty) {
|
|
Object.defineProperty(obj, UID_HASH_KEY, {
|
|
'enumerable': false,
|
|
'configurable': false,
|
|
'writable': false,
|
|
'value': hash
|
|
});
|
|
} else if (obj.propertyIsEnumerable !== undefined &&
|
|
obj.propertyIsEnumerable === obj.constructor.prototype.propertyIsEnumerable) {
|
|
// Since we can't define a non-enumerable property on the object
|
|
// we'll hijack one of the less-used non-enumerable properties to
|
|
// save our hash on it. Since this is a function it will not show up in
|
|
// `JSON.stringify` which is what we want.
|
|
obj.propertyIsEnumerable = function() {
|
|
return this.constructor.prototype.propertyIsEnumerable.apply(this, arguments);
|
|
};
|
|
obj.propertyIsEnumerable[UID_HASH_KEY] = hash;
|
|
} else if (obj.nodeType !== undefined) {
|
|
// At this point we couldn't get the IE `uniqueID` to use as a hash
|
|
// and we couldn't use a non-enumerable property to exploit the
|
|
// dontEnum bug so we simply add the `UID_HASH_KEY` on the node
|
|
// itself.
|
|
obj[UID_HASH_KEY] = hash;
|
|
} else {
|
|
throw new Error('Unable to set a non-enumerable property on object.');
|
|
}
|
|
|
|
return hash;
|
|
}
|
|
|
|
// Get references to ES5 object methods.
|
|
var isExtensible = Object.isExtensible;
|
|
|
|
// True if Object.defineProperty works as expected. IE8 fails this test.
|
|
var canDefineProperty = (function() {
|
|
try {
|
|
Object.defineProperty({}, '@', {});
|
|
return true;
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
}());
|
|
|
|
// IE has a `uniqueID` property on DOM nodes. We can construct the hash from it
|
|
// and avoid memory leaks from the IE cloneNode bug.
|
|
function getIENodeHash(node) {
|
|
if (node && node.nodeType > 0) {
|
|
switch (node.nodeType) {
|
|
case 1: // Element
|
|
return node.uniqueID;
|
|
case 9: // Document
|
|
return node.documentElement && node.documentElement.uniqueID;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If possible, use a WeakMap.
|
|
var usingWeakMap = typeof WeakMap === 'function';
|
|
var weakMap;
|
|
if (usingWeakMap) {
|
|
weakMap = new WeakMap();
|
|
}
|
|
|
|
var objHashUID = 0;
|
|
|
|
var UID_HASH_KEY = '__immutablehash__';
|
|
if (typeof Symbol === 'function') {
|
|
UID_HASH_KEY = Symbol(UID_HASH_KEY);
|
|
}
|
|
|
|
var STRING_HASH_CACHE_MIN_STRLEN = 16;
|
|
var STRING_HASH_CACHE_MAX_SIZE = 255;
|
|
var STRING_HASH_CACHE_SIZE = 0;
|
|
var stringHashCache = {};
|
|
|
|
function invariant(condition, error) {
|
|
if (!condition) throw new Error(error);
|
|
}
|
|
|
|
function assertNotInfinite(size) {
|
|
invariant(
|
|
size !== Infinity,
|
|
'Cannot perform this action with an infinite size.'
|
|
);
|
|
}
|
|
|
|
createClass(ToKeyedSequence, KeyedSeq);
|
|
function ToKeyedSequence(indexed, useKeys) {
|
|
this._iter = indexed;
|
|
this._useKeys = useKeys;
|
|
this.size = indexed.size;
|
|
}
|
|
|
|
ToKeyedSequence.prototype.get = function(key, notSetValue) {
|
|
return this._iter.get(key, notSetValue);
|
|
};
|
|
|
|
ToKeyedSequence.prototype.has = function(key) {
|
|
return this._iter.has(key);
|
|
};
|
|
|
|
ToKeyedSequence.prototype.valueSeq = function() {
|
|
return this._iter.valueSeq();
|
|
};
|
|
|
|
ToKeyedSequence.prototype.reverse = function() {var this$0 = this;
|
|
var reversedSequence = reverseFactory(this, true);
|
|
if (!this._useKeys) {
|
|
reversedSequence.valueSeq = function() {return this$0._iter.toSeq().reverse()};
|
|
}
|
|
return reversedSequence;
|
|
};
|
|
|
|
ToKeyedSequence.prototype.map = function(mapper, context) {var this$0 = this;
|
|
var mappedSequence = mapFactory(this, mapper, context);
|
|
if (!this._useKeys) {
|
|
mappedSequence.valueSeq = function() {return this$0._iter.toSeq().map(mapper, context)};
|
|
}
|
|
return mappedSequence;
|
|
};
|
|
|
|
ToKeyedSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;
|
|
var ii;
|
|
return this._iter.__iterate(
|
|
this._useKeys ?
|
|
function(v, k) {return fn(v, k, this$0)} :
|
|
((ii = reverse ? resolveSize(this) : 0),
|
|
function(v ) {return fn(v, reverse ? --ii : ii++, this$0)}),
|
|
reverse
|
|
);
|
|
};
|
|
|
|
ToKeyedSequence.prototype.__iterator = function(type, reverse) {
|
|
if (this._useKeys) {
|
|
return this._iter.__iterator(type, reverse);
|
|
}
|
|
var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);
|
|
var ii = reverse ? resolveSize(this) : 0;
|
|
return new src_Iterator__Iterator(function() {
|
|
var step = iterator.next();
|
|
return step.done ? step :
|
|
iteratorValue(type, reverse ? --ii : ii++, step.value, step);
|
|
});
|
|
};
|
|
|
|
ToKeyedSequence.prototype[IS_ORDERED_SENTINEL] = true;
|
|
|
|
|
|
createClass(ToIndexedSequence, IndexedSeq);
|
|
function ToIndexedSequence(iter) {
|
|
this._iter = iter;
|
|
this.size = iter.size;
|
|
}
|
|
|
|
ToIndexedSequence.prototype.includes = function(value) {
|
|
return this._iter.includes(value);
|
|
};
|
|
|
|
ToIndexedSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;
|
|
var iterations = 0;
|
|
return this._iter.__iterate(function(v ) {return fn(v, iterations++, this$0)}, reverse);
|
|
};
|
|
|
|
ToIndexedSequence.prototype.__iterator = function(type, reverse) {
|
|
var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);
|
|
var iterations = 0;
|
|
return new src_Iterator__Iterator(function() {
|
|
var step = iterator.next();
|
|
return step.done ? step :
|
|
iteratorValue(type, iterations++, step.value, step)
|
|
});
|
|
};
|
|
|
|
|
|
|
|
createClass(ToSetSequence, SetSeq);
|
|
function ToSetSequence(iter) {
|
|
this._iter = iter;
|
|
this.size = iter.size;
|
|
}
|
|
|
|
ToSetSequence.prototype.has = function(key) {
|
|
return this._iter.includes(key);
|
|
};
|
|
|
|
ToSetSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;
|
|
return this._iter.__iterate(function(v ) {return fn(v, v, this$0)}, reverse);
|
|
};
|
|
|
|
ToSetSequence.prototype.__iterator = function(type, reverse) {
|
|
var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);
|
|
return new src_Iterator__Iterator(function() {
|
|
var step = iterator.next();
|
|
return step.done ? step :
|
|
iteratorValue(type, step.value, step.value, step);
|
|
});
|
|
};
|
|
|
|
|
|
|
|
createClass(FromEntriesSequence, KeyedSeq);
|
|
function FromEntriesSequence(entries) {
|
|
this._iter = entries;
|
|
this.size = entries.size;
|
|
}
|
|
|
|
FromEntriesSequence.prototype.entrySeq = function() {
|
|
return this._iter.toSeq();
|
|
};
|
|
|
|
FromEntriesSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;
|
|
return this._iter.__iterate(function(entry ) {
|
|
// Check if entry exists first so array access doesn't throw for holes
|
|
// in the parent iteration.
|
|
if (entry) {
|
|
validateEntry(entry);
|
|
var indexedIterable = isIterable(entry);
|
|
return fn(
|
|
indexedIterable ? entry.get(1) : entry[1],
|
|
indexedIterable ? entry.get(0) : entry[0],
|
|
this$0
|
|
);
|
|
}
|
|
}, reverse);
|
|
};
|
|
|
|
FromEntriesSequence.prototype.__iterator = function(type, reverse) {
|
|
var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);
|
|
return new src_Iterator__Iterator(function() {
|
|
while (true) {
|
|
var step = iterator.next();
|
|
if (step.done) {
|
|
return step;
|
|
}
|
|
var entry = step.value;
|
|
// Check if entry exists first so array access doesn't throw for holes
|
|
// in the parent iteration.
|
|
if (entry) {
|
|
validateEntry(entry);
|
|
var indexedIterable = isIterable(entry);
|
|
return iteratorValue(
|
|
type,
|
|
indexedIterable ? entry.get(0) : entry[0],
|
|
indexedIterable ? entry.get(1) : entry[1],
|
|
step
|
|
);
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
|
|
ToIndexedSequence.prototype.cacheResult =
|
|
ToKeyedSequence.prototype.cacheResult =
|
|
ToSetSequence.prototype.cacheResult =
|
|
FromEntriesSequence.prototype.cacheResult =
|
|
cacheResultThrough;
|
|
|
|
|
|
function flipFactory(iterable) {
|
|
var flipSequence = makeSequence(iterable);
|
|
flipSequence._iter = iterable;
|
|
flipSequence.size = iterable.size;
|
|
flipSequence.flip = function() {return iterable};
|
|
flipSequence.reverse = function () {
|
|
var reversedSequence = iterable.reverse.apply(this); // super.reverse()
|
|
reversedSequence.flip = function() {return iterable.reverse()};
|
|
return reversedSequence;
|
|
};
|
|
flipSequence.has = function(key ) {return iterable.includes(key)};
|
|
flipSequence.includes = function(key ) {return iterable.has(key)};
|
|
flipSequence.cacheResult = cacheResultThrough;
|
|
flipSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;
|
|
return iterable.__iterate(function(v, k) {return fn(k, v, this$0) !== false}, reverse);
|
|
}
|
|
flipSequence.__iteratorUncached = function(type, reverse) {
|
|
if (type === ITERATE_ENTRIES) {
|
|
var iterator = iterable.__iterator(type, reverse);
|
|
return new src_Iterator__Iterator(function() {
|
|
var step = iterator.next();
|
|
if (!step.done) {
|
|
var k = step.value[0];
|
|
step.value[0] = step.value[1];
|
|
step.value[1] = k;
|
|
}
|
|
return step;
|
|
});
|
|
}
|
|
return iterable.__iterator(
|
|
type === ITERATE_VALUES ? ITERATE_KEYS : ITERATE_VALUES,
|
|
reverse
|
|
);
|
|
}
|
|
return flipSequence;
|
|
}
|
|
|
|
|
|
function mapFactory(iterable, mapper, context) {
|
|
var mappedSequence = makeSequence(iterable);
|
|
mappedSequence.size = iterable.size;
|
|
mappedSequence.has = function(key ) {return iterable.has(key)};
|
|
mappedSequence.get = function(key, notSetValue) {
|
|
var v = iterable.get(key, NOT_SET);
|
|
return v === NOT_SET ?
|
|
notSetValue :
|
|
mapper.call(context, v, key, iterable);
|
|
};
|
|
mappedSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;
|
|
return iterable.__iterate(
|
|
function(v, k, c) {return fn(mapper.call(context, v, k, c), k, this$0) !== false},
|
|
reverse
|
|
);
|
|
}
|
|
mappedSequence.__iteratorUncached = function (type, reverse) {
|
|
var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);
|
|
return new src_Iterator__Iterator(function() {
|
|
var step = iterator.next();
|
|
if (step.done) {
|
|
return step;
|
|
}
|
|
var entry = step.value;
|
|
var key = entry[0];
|
|
return iteratorValue(
|
|
type,
|
|
key,
|
|
mapper.call(context, entry[1], key, iterable),
|
|
step
|
|
);
|
|
});
|
|
}
|
|
return mappedSequence;
|
|
}
|
|
|
|
|
|
function reverseFactory(iterable, useKeys) {
|
|
var reversedSequence = makeSequence(iterable);
|
|
reversedSequence._iter = iterable;
|
|
reversedSequence.size = iterable.size;
|
|
reversedSequence.reverse = function() {return iterable};
|
|
if (iterable.flip) {
|
|
reversedSequence.flip = function () {
|
|
var flipSequence = flipFactory(iterable);
|
|
flipSequence.reverse = function() {return iterable.flip()};
|
|
return flipSequence;
|
|
};
|
|
}
|
|
reversedSequence.get = function(key, notSetValue)
|
|
{return iterable.get(useKeys ? key : -1 - key, notSetValue)};
|
|
reversedSequence.has = function(key )
|
|
{return iterable.has(useKeys ? key : -1 - key)};
|
|
reversedSequence.includes = function(value ) {return iterable.includes(value)};
|
|
reversedSequence.cacheResult = cacheResultThrough;
|
|
reversedSequence.__iterate = function (fn, reverse) {var this$0 = this;
|
|
return iterable.__iterate(function(v, k) {return fn(v, k, this$0)}, !reverse);
|
|
};
|
|
reversedSequence.__iterator =
|
|
function(type, reverse) {return iterable.__iterator(type, !reverse)};
|
|
return reversedSequence;
|
|
}
|
|
|
|
|
|
function filterFactory(iterable, predicate, context, useKeys) {
|
|
var filterSequence = makeSequence(iterable);
|
|
if (useKeys) {
|
|
filterSequence.has = function(key ) {
|
|
var v = iterable.get(key, NOT_SET);
|
|
return v !== NOT_SET && !!predicate.call(context, v, key, iterable);
|
|
};
|
|
filterSequence.get = function(key, notSetValue) {
|
|
var v = iterable.get(key, NOT_SET);
|
|
return v !== NOT_SET && predicate.call(context, v, key, iterable) ?
|
|
v : notSetValue;
|
|
};
|
|
}
|
|
filterSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;
|
|
var iterations = 0;
|
|
iterable.__iterate(function(v, k, c) {
|
|
if (predicate.call(context, v, k, c)) {
|
|
iterations++;
|
|
return fn(v, useKeys ? k : iterations - 1, this$0);
|
|
}
|
|
}, reverse);
|
|
return iterations;
|
|
};
|
|
filterSequence.__iteratorUncached = function (type, reverse) {
|
|
var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);
|
|
var iterations = 0;
|
|
return new src_Iterator__Iterator(function() {
|
|
while (true) {
|
|
var step = iterator.next();
|
|
if (step.done) {
|
|
return step;
|
|
}
|
|
var entry = step.value;
|
|
var key = entry[0];
|
|
var value = entry[1];
|
|
if (predicate.call(context, value, key, iterable)) {
|
|
return iteratorValue(type, useKeys ? key : iterations++, value, step);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
return filterSequence;
|
|
}
|
|
|
|
|
|
function countByFactory(iterable, grouper, context) {
|
|
var groups = src_Map__Map().asMutable();
|
|
iterable.__iterate(function(v, k) {
|
|
groups.update(
|
|
grouper.call(context, v, k, iterable),
|
|
0,
|
|
function(a ) {return a + 1}
|
|
);
|
|
});
|
|
return groups.asImmutable();
|
|
}
|
|
|
|
|
|
function groupByFactory(iterable, grouper, context) {
|
|
var isKeyedIter = isKeyed(iterable);
|
|
var groups = (isOrdered(iterable) ? OrderedMap() : src_Map__Map()).asMutable();
|
|
iterable.__iterate(function(v, k) {
|
|
groups.update(
|
|
grouper.call(context, v, k, iterable),
|
|
function(a ) {return (a = a || [], a.push(isKeyedIter ? [k, v] : v), a)}
|
|
);
|
|
});
|
|
var coerce = iterableClass(iterable);
|
|
return groups.map(function(arr ) {return reify(iterable, coerce(arr))});
|
|
}
|
|
|
|
|
|
function sliceFactory(iterable, begin, end, useKeys) {
|
|
var originalSize = iterable.size;
|
|
|
|
if (wholeSlice(begin, end, originalSize)) {
|
|
return iterable;
|
|
}
|
|
|
|
var resolvedBegin = resolveBegin(begin, originalSize);
|
|
var resolvedEnd = resolveEnd(end, originalSize);
|
|
|
|
// begin or end will be NaN if they were provided as negative numbers and
|
|
// this iterable's size is unknown. In that case, cache first so there is
|
|
// a known size and these do not resolve to NaN.
|
|
if (resolvedBegin !== resolvedBegin || resolvedEnd !== resolvedEnd) {
|
|
return sliceFactory(iterable.toSeq().cacheResult(), begin, end, useKeys);
|
|
}
|
|
|
|
// Note: resolvedEnd is undefined when the original sequence's length is
|
|
// unknown and this slice did not supply an end and should contain all
|
|
// elements after resolvedBegin.
|
|
// In that case, resolvedSize will be NaN and sliceSize will remain undefined.
|
|
var resolvedSize = resolvedEnd - resolvedBegin;
|
|
var sliceSize;
|
|
if (resolvedSize === resolvedSize) {
|
|
sliceSize = resolvedSize < 0 ? 0 : resolvedSize;
|
|
}
|
|
|
|
var sliceSeq = makeSequence(iterable);
|
|
|
|
sliceSeq.size = sliceSize;
|
|
|
|
if (!useKeys && isSeq(iterable) && sliceSize >= 0) {
|
|
sliceSeq.get = function (index, notSetValue) {
|
|
index = wrapIndex(this, index);
|
|
return index >= 0 && index < sliceSize ?
|
|
iterable.get(index + resolvedBegin, notSetValue) :
|
|
notSetValue;
|
|
}
|
|
}
|
|
|
|
sliceSeq.__iterateUncached = function(fn, reverse) {var this$0 = this;
|
|
if (sliceSize === 0) {
|
|
return 0;
|
|
}
|
|
if (reverse) {
|
|
return this.cacheResult().__iterate(fn, reverse);
|
|
}
|
|
var skipped = 0;
|
|
var isSkipping = true;
|
|
var iterations = 0;
|
|
iterable.__iterate(function(v, k) {
|
|
if (!(isSkipping && (isSkipping = skipped++ < resolvedBegin))) {
|
|
iterations++;
|
|
return fn(v, useKeys ? k : iterations - 1, this$0) !== false &&
|
|
iterations !== sliceSize;
|
|
}
|
|
});
|
|
return iterations;
|
|
};
|
|
|
|
sliceSeq.__iteratorUncached = function(type, reverse) {
|
|
if (sliceSize !== 0 && reverse) {
|
|
return this.cacheResult().__iterator(type, reverse);
|
|
}
|
|
// Don't bother instantiating parent iterator if taking 0.
|
|
var iterator = sliceSize !== 0 && iterable.__iterator(type, reverse);
|
|
var skipped = 0;
|
|
var iterations = 0;
|
|
return new src_Iterator__Iterator(function() {
|
|
while (skipped++ < resolvedBegin) {
|
|
iterator.next();
|
|
}
|
|
if (++iterations > sliceSize) {
|
|
return iteratorDone();
|
|
}
|
|
var step = iterator.next();
|
|
if (useKeys || type === ITERATE_VALUES) {
|
|
return step;
|
|
} else if (type === ITERATE_KEYS) {
|
|
return iteratorValue(type, iterations - 1, undefined, step);
|
|
} else {
|
|
return iteratorValue(type, iterations - 1, step.value[1], step);
|
|
}
|
|
});
|
|
}
|
|
|
|
return sliceSeq;
|
|
}
|
|
|
|
|
|
function takeWhileFactory(iterable, predicate, context) {
|
|
var takeSequence = makeSequence(iterable);
|
|
takeSequence.__iterateUncached = function(fn, reverse) {var this$0 = this;
|
|
if (reverse) {
|
|
return this.cacheResult().__iterate(fn, reverse);
|
|
}
|
|
var iterations = 0;
|
|
iterable.__iterate(function(v, k, c)
|
|
{return predicate.call(context, v, k, c) && ++iterations && fn(v, k, this$0)}
|
|
);
|
|
return iterations;
|
|
};
|
|
takeSequence.__iteratorUncached = function(type, reverse) {var this$0 = this;
|
|
if (reverse) {
|
|
return this.cacheResult().__iterator(type, reverse);
|
|
}
|
|
var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);
|
|
var iterating = true;
|
|
return new src_Iterator__Iterator(function() {
|
|
if (!iterating) {
|
|
return iteratorDone();
|
|
}
|
|
var step = iterator.next();
|
|
if (step.done) {
|
|
return step;
|
|
}
|
|
var entry = step.value;
|
|
var k = entry[0];
|
|
var v = entry[1];
|
|
if (!predicate.call(context, v, k, this$0)) {
|
|
iterating = false;
|
|
return iteratorDone();
|
|
}
|
|
return type === ITERATE_ENTRIES ? step :
|
|
iteratorValue(type, k, v, step);
|
|
});
|
|
};
|
|
return takeSequence;
|
|
}
|
|
|
|
|
|
function skipWhileFactory(iterable, predicate, context, useKeys) {
|
|
var skipSequence = makeSequence(iterable);
|
|
skipSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;
|
|
if (reverse) {
|
|
return this.cacheResult().__iterate(fn, reverse);
|
|
}
|
|
var isSkipping = true;
|
|
var iterations = 0;
|
|
iterable.__iterate(function(v, k, c) {
|
|
if (!(isSkipping && (isSkipping = predicate.call(context, v, k, c)))) {
|
|
iterations++;
|
|
return fn(v, useKeys ? k : iterations - 1, this$0);
|
|
}
|
|
});
|
|
return iterations;
|
|
};
|
|
skipSequence.__iteratorUncached = function(type, reverse) {var this$0 = this;
|
|
if (reverse) {
|
|
return this.cacheResult().__iterator(type, reverse);
|
|
}
|
|
var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);
|
|
var skipping = true;
|
|
var iterations = 0;
|
|
return new src_Iterator__Iterator(function() {
|
|
var step, k, v;
|
|
do {
|
|
step = iterator.next();
|
|
if (step.done) {
|
|
if (useKeys || type === ITERATE_VALUES) {
|
|
return step;
|
|
} else if (type === ITERATE_KEYS) {
|
|
return iteratorValue(type, iterations++, undefined, step);
|
|
} else {
|
|
return iteratorValue(type, iterations++, step.value[1], step);
|
|
}
|
|
}
|
|
var entry = step.value;
|
|
k = entry[0];
|
|
v = entry[1];
|
|
skipping && (skipping = predicate.call(context, v, k, this$0));
|
|
} while (skipping);
|
|
return type === ITERATE_ENTRIES ? step :
|
|
iteratorValue(type, k, v, step);
|
|
});
|
|
};
|
|
return skipSequence;
|
|
}
|
|
|
|
|
|
function concatFactory(iterable, values) {
|
|
var isKeyedIterable = isKeyed(iterable);
|
|
var iters = [iterable].concat(values).map(function(v ) {
|
|
if (!isIterable(v)) {
|
|
v = isKeyedIterable ?
|
|
keyedSeqFromValue(v) :
|
|
indexedSeqFromValue(Array.isArray(v) ? v : [v]);
|
|
} else if (isKeyedIterable) {
|
|
v = KeyedIterable(v);
|
|
}
|
|
return v;
|
|
}).filter(function(v ) {return v.size !== 0});
|
|
|
|
if (iters.length === 0) {
|
|
return iterable;
|
|
}
|
|
|
|
if (iters.length === 1) {
|
|
var singleton = iters[0];
|
|
if (singleton === iterable ||
|
|
isKeyedIterable && isKeyed(singleton) ||
|
|
isIndexed(iterable) && isIndexed(singleton)) {
|
|
return singleton;
|
|
}
|
|
}
|
|
|
|
var concatSeq = new ArraySeq(iters);
|
|
if (isKeyedIterable) {
|
|
concatSeq = concatSeq.toKeyedSeq();
|
|
} else if (!isIndexed(iterable)) {
|
|
concatSeq = concatSeq.toSetSeq();
|
|
}
|
|
concatSeq = concatSeq.flatten(true);
|
|
concatSeq.size = iters.reduce(
|
|
function(sum, seq) {
|
|
if (sum !== undefined) {
|
|
var size = seq.size;
|
|
if (size !== undefined) {
|
|
return sum + size;
|
|
}
|
|
}
|
|
},
|
|
0
|
|
);
|
|
return concatSeq;
|
|
}
|
|
|
|
|
|
function flattenFactory(iterable, depth, useKeys) {
|
|
var flatSequence = makeSequence(iterable);
|
|
flatSequence.__iterateUncached = function(fn, reverse) {
|
|
var iterations = 0;
|
|
var stopped = false;
|
|
function flatDeep(iter, currentDepth) {var this$0 = this;
|
|
iter.__iterate(function(v, k) {
|
|
if ((!depth || currentDepth < depth) && isIterable(v)) {
|
|
flatDeep(v, currentDepth + 1);
|
|
} else if (fn(v, useKeys ? k : iterations++, this$0) === false) {
|
|
stopped = true;
|
|
}
|
|
return !stopped;
|
|
}, reverse);
|
|
}
|
|
flatDeep(iterable, 0);
|
|
return iterations;
|
|
}
|
|
flatSequence.__iteratorUncached = function(type, reverse) {
|
|
var iterator = iterable.__iterator(type, reverse);
|
|
var stack = [];
|
|
var iterations = 0;
|
|
return new src_Iterator__Iterator(function() {
|
|
while (iterator) {
|
|
var step = iterator.next();
|
|
if (step.done !== false) {
|
|
iterator = stack.pop();
|
|
continue;
|
|
}
|
|
var v = step.value;
|
|
if (type === ITERATE_ENTRIES) {
|
|
v = v[1];
|
|
}
|
|
if ((!depth || stack.length < depth) && isIterable(v)) {
|
|
stack.push(iterator);
|
|
iterator = v.__iterator(type, reverse);
|
|
} else {
|
|
return useKeys ? step : iteratorValue(type, iterations++, v, step);
|
|
}
|
|
}
|
|
return iteratorDone();
|
|
});
|
|
}
|
|
return flatSequence;
|
|
}
|
|
|
|
|
|
function flatMapFactory(iterable, mapper, context) {
|
|
var coerce = iterableClass(iterable);
|
|
return iterable.toSeq().map(
|
|
function(v, k) {return coerce(mapper.call(context, v, k, iterable))}
|
|
).flatten(true);
|
|
}
|
|
|
|
|
|
function interposeFactory(iterable, separator) {
|
|
var interposedSequence = makeSequence(iterable);
|
|
interposedSequence.size = iterable.size && iterable.size * 2 -1;
|
|
interposedSequence.__iterateUncached = function(fn, reverse) {var this$0 = this;
|
|
var iterations = 0;
|
|
iterable.__iterate(function(v, k)
|
|
{return (!iterations || fn(separator, iterations++, this$0) !== false) &&
|
|
fn(v, iterations++, this$0) !== false},
|
|
reverse
|
|
);
|
|
return iterations;
|
|
};
|
|
interposedSequence.__iteratorUncached = function(type, reverse) {
|
|
var iterator = iterable.__iterator(ITERATE_VALUES, reverse);
|
|
var iterations = 0;
|
|
var step;
|
|
return new src_Iterator__Iterator(function() {
|
|
if (!step || iterations % 2) {
|
|
step = iterator.next();
|
|
if (step.done) {
|
|
return step;
|
|
}
|
|
}
|
|
return iterations % 2 ?
|
|
iteratorValue(type, iterations++, separator) :
|
|
iteratorValue(type, iterations++, step.value, step);
|
|
});
|
|
};
|
|
return interposedSequence;
|
|
}
|
|
|
|
|
|
function sortFactory(iterable, comparator, mapper) {
|
|
if (!comparator) {
|
|
comparator = defaultComparator;
|
|
}
|
|
var isKeyedIterable = isKeyed(iterable);
|
|
var index = 0;
|
|
var entries = iterable.toSeq().map(
|
|
function(v, k) {return [k, v, index++, mapper ? mapper(v, k, iterable) : v]}
|
|
).toArray();
|
|
entries.sort(function(a, b) {return comparator(a[3], b[3]) || a[2] - b[2]}).forEach(
|
|
isKeyedIterable ?
|
|
function(v, i) { entries[i].length = 2; } :
|
|
function(v, i) { entries[i] = v[1]; }
|
|
);
|
|
return isKeyedIterable ? KeyedSeq(entries) :
|
|
isIndexed(iterable) ? IndexedSeq(entries) :
|
|
SetSeq(entries);
|
|
}
|
|
|
|
|
|
function maxFactory(iterable, comparator, mapper) {
|
|
if (!comparator) {
|
|
comparator = defaultComparator;
|
|
}
|
|
if (mapper) {
|
|
var entry = iterable.toSeq()
|
|
.map(function(v, k) {return [v, mapper(v, k, iterable)]})
|
|
.reduce(function(a, b) {return maxCompare(comparator, a[1], b[1]) ? b : a});
|
|
return entry && entry[0];
|
|
} else {
|
|
return iterable.reduce(function(a, b) {return maxCompare(comparator, a, b) ? b : a});
|
|
}
|
|
}
|
|
|
|
function maxCompare(comparator, a, b) {
|
|
var comp = comparator(b, a);
|
|
// b is considered the new max if the comparator declares them equal, but
|
|
// they are not equal and b is in fact a nullish value.
|
|
return (comp === 0 && b !== a && (b === undefined || b === null || b !== b)) || comp > 0;
|
|
}
|
|
|
|
|
|
function zipWithFactory(keyIter, zipper, iters) {
|
|
var zipSequence = makeSequence(keyIter);
|
|
zipSequence.size = new ArraySeq(iters).map(function(i ) {return i.size}).min();
|
|
// Note: this a generic base implementation of __iterate in terms of
|
|
// __iterator which may be more generically useful in the future.
|
|
zipSequence.__iterate = function(fn, reverse) {
|
|
/* generic:
|
|
var iterator = this.__iterator(ITERATE_ENTRIES, reverse);
|
|
var step;
|
|
var iterations = 0;
|
|
while (!(step = iterator.next()).done) {
|
|
iterations++;
|
|
if (fn(step.value[1], step.value[0], this) === false) {
|
|
break;
|
|
}
|
|
}
|
|
return iterations;
|
|
*/
|
|
// indexed:
|
|
var iterator = this.__iterator(ITERATE_VALUES, reverse);
|
|
var step;
|
|
var iterations = 0;
|
|
while (!(step = iterator.next()).done) {
|
|
if (fn(step.value, iterations++, this) === false) {
|
|
break;
|
|
}
|
|
}
|
|
return iterations;
|
|
};
|
|
zipSequence.__iteratorUncached = function(type, reverse) {
|
|
var iterators = iters.map(function(i )
|
|
{return (i = Iterable(i), getIterator(reverse ? i.reverse() : i))}
|
|
);
|
|
var iterations = 0;
|
|
var isDone = false;
|
|
return new src_Iterator__Iterator(function() {
|
|
var steps;
|
|
if (!isDone) {
|
|
steps = iterators.map(function(i ) {return i.next()});
|
|
isDone = steps.some(function(s ) {return s.done});
|
|
}
|
|
if (isDone) {
|
|
return iteratorDone();
|
|
}
|
|
return iteratorValue(
|
|
type,
|
|
iterations++,
|
|
zipper.apply(null, steps.map(function(s ) {return s.value}))
|
|
);
|
|
});
|
|
};
|
|
return zipSequence
|
|
}
|
|
|
|
|
|
// #pragma Helper Functions
|
|
|
|
function reify(iter, seq) {
|
|
return isSeq(iter) ? seq : iter.constructor(seq);
|
|
}
|
|
|
|
function validateEntry(entry) {
|
|
if (entry !== Object(entry)) {
|
|
throw new TypeError('Expected [K, V] tuple: ' + entry);
|
|
}
|
|
}
|
|
|
|
function resolveSize(iter) {
|
|
assertNotInfinite(iter.size);
|
|
return ensureSize(iter);
|
|
}
|
|
|
|
function iterableClass(iterable) {
|
|
return isKeyed(iterable) ? KeyedIterable :
|
|
isIndexed(iterable) ? IndexedIterable :
|
|
SetIterable;
|
|
}
|
|
|
|
function makeSequence(iterable) {
|
|
return Object.create(
|
|
(
|
|
isKeyed(iterable) ? KeyedSeq :
|
|
isIndexed(iterable) ? IndexedSeq :
|
|
SetSeq
|
|
).prototype
|
|
);
|
|
}
|
|
|
|
function cacheResultThrough() {
|
|
if (this._iter.cacheResult) {
|
|
this._iter.cacheResult();
|
|
this.size = this._iter.size;
|
|
return this;
|
|
} else {
|
|
return Seq.prototype.cacheResult.call(this);
|
|
}
|
|
}
|
|
|
|
function defaultComparator(a, b) {
|
|
return a > b ? 1 : a < b ? -1 : 0;
|
|
}
|
|
|
|
function forceIterator(keyPath) {
|
|
var iter = getIterator(keyPath);
|
|
if (!iter) {
|
|
// Array might not be iterable in this environment, so we need a fallback
|
|
// to our wrapped type.
|
|
if (!isArrayLike(keyPath)) {
|
|
throw new TypeError('Expected iterable or array-like: ' + keyPath);
|
|
}
|
|
iter = getIterator(Iterable(keyPath));
|
|
}
|
|
return iter;
|
|
}
|
|
|
|
createClass(src_Map__Map, KeyedCollection);
|
|
|
|
// @pragma Construction
|
|
|
|
function src_Map__Map(value) {
|
|
return value === null || value === undefined ? emptyMap() :
|
|
isMap(value) ? value :
|
|
emptyMap().withMutations(function(map ) {
|
|
var iter = KeyedIterable(value);
|
|
assertNotInfinite(iter.size);
|
|
iter.forEach(function(v, k) {return map.set(k, v)});
|
|
});
|
|
}
|
|
|
|
src_Map__Map.prototype.toString = function() {
|
|
return this.__toString('Map {', '}');
|
|
};
|
|
|
|
// @pragma Access
|
|
|
|
src_Map__Map.prototype.get = function(k, notSetValue) {
|
|
return this._root ?
|
|
this._root.get(0, undefined, k, notSetValue) :
|
|
notSetValue;
|
|
};
|
|
|
|
// @pragma Modification
|
|
|
|
src_Map__Map.prototype.set = function(k, v) {
|
|
return updateMap(this, k, v);
|
|
};
|
|
|
|
src_Map__Map.prototype.setIn = function(keyPath, v) {
|
|
return this.updateIn(keyPath, NOT_SET, function() {return v});
|
|
};
|
|
|
|
src_Map__Map.prototype.remove = function(k) {
|
|
return updateMap(this, k, NOT_SET);
|
|
};
|
|
|
|
src_Map__Map.prototype.deleteIn = function(keyPath) {
|
|
return this.updateIn(keyPath, function() {return NOT_SET});
|
|
};
|
|
|
|
src_Map__Map.prototype.update = function(k, notSetValue, updater) {
|
|
return arguments.length === 1 ?
|
|
k(this) :
|
|
this.updateIn([k], notSetValue, updater);
|
|
};
|
|
|
|
src_Map__Map.prototype.updateIn = function(keyPath, notSetValue, updater) {
|
|
if (!updater) {
|
|
updater = notSetValue;
|
|
notSetValue = undefined;
|
|
}
|
|
var updatedValue = updateInDeepMap(
|
|
this,
|
|
forceIterator(keyPath),
|
|
notSetValue,
|
|
updater
|
|
);
|
|
return updatedValue === NOT_SET ? undefined : updatedValue;
|
|
};
|
|
|
|
src_Map__Map.prototype.clear = function() {
|
|
if (this.size === 0) {
|
|
return this;
|
|
}
|
|
if (this.__ownerID) {
|
|
this.size = 0;
|
|
this._root = null;
|
|
this.__hash = undefined;
|
|
this.__altered = true;
|
|
return this;
|
|
}
|
|
return emptyMap();
|
|
};
|
|
|
|
// @pragma Composition
|
|
|
|
src_Map__Map.prototype.merge = function(/*...iters*/) {
|
|
return mergeIntoMapWith(this, undefined, arguments);
|
|
};
|
|
|
|
src_Map__Map.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1);
|
|
return mergeIntoMapWith(this, merger, iters);
|
|
};
|
|
|
|
src_Map__Map.prototype.mergeIn = function(keyPath) {var iters = SLICE$0.call(arguments, 1);
|
|
return this.updateIn(
|
|
keyPath,
|
|
emptyMap(),
|
|
function(m ) {return typeof m.merge === 'function' ?
|
|
m.merge.apply(m, iters) :
|
|
iters[iters.length - 1]}
|
|
);
|
|
};
|
|
|
|
src_Map__Map.prototype.mergeDeep = function(/*...iters*/) {
|
|
return mergeIntoMapWith(this, deepMerger(undefined), arguments);
|
|
};
|
|
|
|
src_Map__Map.prototype.mergeDeepWith = function(merger) {var iters = SLICE$0.call(arguments, 1);
|
|
return mergeIntoMapWith(this, deepMerger(merger), iters);
|
|
};
|
|
|
|
src_Map__Map.prototype.mergeDeepIn = function(keyPath) {var iters = SLICE$0.call(arguments, 1);
|
|
return this.updateIn(
|
|
keyPath,
|
|
emptyMap(),
|
|
function(m ) {return typeof m.mergeDeep === 'function' ?
|
|
m.mergeDeep.apply(m, iters) :
|
|
iters[iters.length - 1]}
|
|
);
|
|
};
|
|
|
|
src_Map__Map.prototype.sort = function(comparator) {
|
|
// Late binding
|
|
return OrderedMap(sortFactory(this, comparator));
|
|
};
|
|
|
|
src_Map__Map.prototype.sortBy = function(mapper, comparator) {
|
|
// Late binding
|
|
return OrderedMap(sortFactory(this, comparator, mapper));
|
|
};
|
|
|
|
// @pragma Mutability
|
|
|
|
src_Map__Map.prototype.withMutations = function(fn) {
|
|
var mutable = this.asMutable();
|
|
fn(mutable);
|
|
return mutable.wasAltered() ? mutable.__ensureOwner(this.__ownerID) : this;
|
|
};
|
|
|
|
src_Map__Map.prototype.asMutable = function() {
|
|
return this.__ownerID ? this : this.__ensureOwner(new OwnerID());
|
|
};
|
|
|
|
src_Map__Map.prototype.asImmutable = function() {
|
|
return this.__ensureOwner();
|
|
};
|
|
|
|
src_Map__Map.prototype.wasAltered = function() {
|
|
return this.__altered;
|
|
};
|
|
|
|
src_Map__Map.prototype.__iterator = function(type, reverse) {
|
|
return new MapIterator(this, type, reverse);
|
|
};
|
|
|
|
src_Map__Map.prototype.__iterate = function(fn, reverse) {var this$0 = this;
|
|
var iterations = 0;
|
|
this._root && this._root.iterate(function(entry ) {
|
|
iterations++;
|
|
return fn(entry[1], entry[0], this$0);
|
|
}, reverse);
|
|
return iterations;
|
|
};
|
|
|
|
src_Map__Map.prototype.__ensureOwner = function(ownerID) {
|
|
if (ownerID === this.__ownerID) {
|
|
return this;
|
|
}
|
|
if (!ownerID) {
|
|
this.__ownerID = ownerID;
|
|
this.__altered = false;
|
|
return this;
|
|
}
|
|
return makeMap(this.size, this._root, ownerID, this.__hash);
|
|
};
|
|
|
|
|
|
function isMap(maybeMap) {
|
|
return !!(maybeMap && maybeMap[IS_MAP_SENTINEL]);
|
|
}
|
|
|
|
src_Map__Map.isMap = isMap;
|
|
|
|
var IS_MAP_SENTINEL = '@@__IMMUTABLE_MAP__@@';
|
|
|
|
var MapPrototype = src_Map__Map.prototype;
|
|
MapPrototype[IS_MAP_SENTINEL] = true;
|
|
MapPrototype[DELETE] = MapPrototype.remove;
|
|
MapPrototype.removeIn = MapPrototype.deleteIn;
|
|
|
|
|
|
// #pragma Trie Nodes
|
|
|
|
|
|
|
|
function ArrayMapNode(ownerID, entries) {
|
|
this.ownerID = ownerID;
|
|
this.entries = entries;
|
|
}
|
|
|
|
ArrayMapNode.prototype.get = function(shift, keyHash, key, notSetValue) {
|
|
var entries = this.entries;
|
|
for (var ii = 0, len = entries.length; ii < len; ii++) {
|
|
if (is(key, entries[ii][0])) {
|
|
return entries[ii][1];
|
|
}
|
|
}
|
|
return notSetValue;
|
|
};
|
|
|
|
ArrayMapNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
|
|
var removed = value === NOT_SET;
|
|
|
|
var entries = this.entries;
|
|
var idx = 0;
|
|
for (var len = entries.length; idx < len; idx++) {
|
|
if (is(key, entries[idx][0])) {
|
|
break;
|
|
}
|
|
}
|
|
var exists = idx < len;
|
|
|
|
if (exists ? entries[idx][1] === value : removed) {
|
|
return this;
|
|
}
|
|
|
|
SetRef(didAlter);
|
|
(removed || !exists) && SetRef(didChangeSize);
|
|
|
|
if (removed && entries.length === 1) {
|
|
return; // undefined
|
|
}
|
|
|
|
if (!exists && !removed && entries.length >= MAX_ARRAY_MAP_SIZE) {
|
|
return createNodes(ownerID, entries, key, value);
|
|
}
|
|
|
|
var isEditable = ownerID && ownerID === this.ownerID;
|
|
var newEntries = isEditable ? entries : arrCopy(entries);
|
|
|
|
if (exists) {
|
|
if (removed) {
|
|
idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop());
|
|
} else {
|
|
newEntries[idx] = [key, value];
|
|
}
|
|
} else {
|
|
newEntries.push([key, value]);
|
|
}
|
|
|
|
if (isEditable) {
|
|
this.entries = newEntries;
|
|
return this;
|
|
}
|
|
|
|
return new ArrayMapNode(ownerID, newEntries);
|
|
};
|
|
|
|
|
|
|
|
|
|
function BitmapIndexedNode(ownerID, bitmap, nodes) {
|
|
this.ownerID = ownerID;
|
|
this.bitmap = bitmap;
|
|
this.nodes = nodes;
|
|
}
|
|
|
|
BitmapIndexedNode.prototype.get = function(shift, keyHash, key, notSetValue) {
|
|
if (keyHash === undefined) {
|
|
keyHash = hash(key);
|
|
}
|
|
var bit = (1 << ((shift === 0 ? keyHash : keyHash >>> shift) & MASK));
|
|
var bitmap = this.bitmap;
|
|
return (bitmap & bit) === 0 ? notSetValue :
|
|
this.nodes[popCount(bitmap & (bit - 1))].get(shift + SHIFT, keyHash, key, notSetValue);
|
|
};
|
|
|
|
BitmapIndexedNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
|
|
if (keyHash === undefined) {
|
|
keyHash = hash(key);
|
|
}
|
|
var keyHashFrag = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;
|
|
var bit = 1 << keyHashFrag;
|
|
var bitmap = this.bitmap;
|
|
var exists = (bitmap & bit) !== 0;
|
|
|
|
if (!exists && value === NOT_SET) {
|
|
return this;
|
|
}
|
|
|
|
var idx = popCount(bitmap & (bit - 1));
|
|
var nodes = this.nodes;
|
|
var node = exists ? nodes[idx] : undefined;
|
|
var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter);
|
|
|
|
if (newNode === node) {
|
|
return this;
|
|
}
|
|
|
|
if (!exists && newNode && nodes.length >= MAX_BITMAP_INDEXED_SIZE) {
|
|
return expandNodes(ownerID, nodes, bitmap, keyHashFrag, newNode);
|
|
}
|
|
|
|
if (exists && !newNode && nodes.length === 2 && isLeafNode(nodes[idx ^ 1])) {
|
|
return nodes[idx ^ 1];
|
|
}
|
|
|
|
if (exists && newNode && nodes.length === 1 && isLeafNode(newNode)) {
|
|
return newNode;
|
|
}
|
|
|
|
var isEditable = ownerID && ownerID === this.ownerID;
|
|
var newBitmap = exists ? newNode ? bitmap : bitmap ^ bit : bitmap | bit;
|
|
var newNodes = exists ? newNode ?
|
|
setIn(nodes, idx, newNode, isEditable) :
|
|
spliceOut(nodes, idx, isEditable) :
|
|
spliceIn(nodes, idx, newNode, isEditable);
|
|
|
|
if (isEditable) {
|
|
this.bitmap = newBitmap;
|
|
this.nodes = newNodes;
|
|
return this;
|
|
}
|
|
|
|
return new BitmapIndexedNode(ownerID, newBitmap, newNodes);
|
|
};
|
|
|
|
|
|
|
|
|
|
function HashArrayMapNode(ownerID, count, nodes) {
|
|
this.ownerID = ownerID;
|
|
this.count = count;
|
|
this.nodes = nodes;
|
|
}
|
|
|
|
HashArrayMapNode.prototype.get = function(shift, keyHash, key, notSetValue) {
|
|
if (keyHash === undefined) {
|
|
keyHash = hash(key);
|
|
}
|
|
var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;
|
|
var node = this.nodes[idx];
|
|
return node ? node.get(shift + SHIFT, keyHash, key, notSetValue) : notSetValue;
|
|
};
|
|
|
|
HashArrayMapNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
|
|
if (keyHash === undefined) {
|
|
keyHash = hash(key);
|
|
}
|
|
var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;
|
|
var removed = value === NOT_SET;
|
|
var nodes = this.nodes;
|
|
var node = nodes[idx];
|
|
|
|
if (removed && !node) {
|
|
return this;
|
|
}
|
|
|
|
var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter);
|
|
if (newNode === node) {
|
|
return this;
|
|
}
|
|
|
|
var newCount = this.count;
|
|
if (!node) {
|
|
newCount++;
|
|
} else if (!newNode) {
|
|
newCount--;
|
|
if (newCount < MIN_HASH_ARRAY_MAP_SIZE) {
|
|
return packNodes(ownerID, nodes, newCount, idx);
|
|
}
|
|
}
|
|
|
|
var isEditable = ownerID && ownerID === this.ownerID;
|
|
var newNodes = setIn(nodes, idx, newNode, isEditable);
|
|
|
|
if (isEditable) {
|
|
this.count = newCount;
|
|
this.nodes = newNodes;
|
|
return this;
|
|
}
|
|
|
|
return new HashArrayMapNode(ownerID, newCount, newNodes);
|
|
};
|
|
|
|
|
|
|
|
|
|
function HashCollisionNode(ownerID, keyHash, entries) {
|
|
this.ownerID = ownerID;
|
|
this.keyHash = keyHash;
|
|
this.entries = entries;
|
|
}
|
|
|
|
HashCollisionNode.prototype.get = function(shift, keyHash, key, notSetValue) {
|
|
var entries = this.entries;
|
|
for (var ii = 0, len = entries.length; ii < len; ii++) {
|
|
if (is(key, entries[ii][0])) {
|
|
return entries[ii][1];
|
|
}
|
|
}
|
|
return notSetValue;
|
|
};
|
|
|
|
HashCollisionNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
|
|
if (keyHash === undefined) {
|
|
keyHash = hash(key);
|
|
}
|
|
|
|
var removed = value === NOT_SET;
|
|
|
|
if (keyHash !== this.keyHash) {
|
|
if (removed) {
|
|
return this;
|
|
}
|
|
SetRef(didAlter);
|
|
SetRef(didChangeSize);
|
|
return mergeIntoNode(this, ownerID, shift, keyHash, [key, value]);
|
|
}
|
|
|
|
var entries = this.entries;
|
|
var idx = 0;
|
|
for (var len = entries.length; idx < len; idx++) {
|
|
if (is(key, entries[idx][0])) {
|
|
break;
|
|
}
|
|
}
|
|
var exists = idx < len;
|
|
|
|
if (exists ? entries[idx][1] === value : removed) {
|
|
return this;
|
|
}
|
|
|
|
SetRef(didAlter);
|
|
(removed || !exists) && SetRef(didChangeSize);
|
|
|
|
if (removed && len === 2) {
|
|
return new ValueNode(ownerID, this.keyHash, entries[idx ^ 1]);
|
|
}
|
|
|
|
var isEditable = ownerID && ownerID === this.ownerID;
|
|
var newEntries = isEditable ? entries : arrCopy(entries);
|
|
|
|
if (exists) {
|
|
if (removed) {
|
|
idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop());
|
|
} else {
|
|
newEntries[idx] = [key, value];
|
|
}
|
|
} else {
|
|
newEntries.push([key, value]);
|
|
}
|
|
|
|
if (isEditable) {
|
|
this.entries = newEntries;
|
|
return this;
|
|
}
|
|
|
|
return new HashCollisionNode(ownerID, this.keyHash, newEntries);
|
|
};
|
|
|
|
|
|
|
|
|
|
function ValueNode(ownerID, keyHash, entry) {
|
|
this.ownerID = ownerID;
|
|
this.keyHash = keyHash;
|
|
this.entry = entry;
|
|
}
|
|
|
|
ValueNode.prototype.get = function(shift, keyHash, key, notSetValue) {
|
|
return is(key, this.entry[0]) ? this.entry[1] : notSetValue;
|
|
};
|
|
|
|
ValueNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
|
|
var removed = value === NOT_SET;
|
|
var keyMatch = is(key, this.entry[0]);
|
|
if (keyMatch ? value === this.entry[1] : removed) {
|
|
return this;
|
|
}
|
|
|
|
SetRef(didAlter);
|
|
|
|
if (removed) {
|
|
SetRef(didChangeSize);
|
|
return; // undefined
|
|
}
|
|
|
|
if (keyMatch) {
|
|
if (ownerID && ownerID === this.ownerID) {
|
|
this.entry[1] = value;
|
|
return this;
|
|
}
|
|
return new ValueNode(ownerID, this.keyHash, [key, value]);
|
|
}
|
|
|
|
SetRef(didChangeSize);
|
|
return mergeIntoNode(this, ownerID, shift, hash(key), [key, value]);
|
|
};
|
|
|
|
|
|
|
|
// #pragma Iterators
|
|
|
|
ArrayMapNode.prototype.iterate =
|
|
HashCollisionNode.prototype.iterate = function (fn, reverse) {
|
|
var entries = this.entries;
|
|
for (var ii = 0, maxIndex = entries.length - 1; ii <= maxIndex; ii++) {
|
|
if (fn(entries[reverse ? maxIndex - ii : ii]) === false) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
BitmapIndexedNode.prototype.iterate =
|
|
HashArrayMapNode.prototype.iterate = function (fn, reverse) {
|
|
var nodes = this.nodes;
|
|
for (var ii = 0, maxIndex = nodes.length - 1; ii <= maxIndex; ii++) {
|
|
var node = nodes[reverse ? maxIndex - ii : ii];
|
|
if (node && node.iterate(fn, reverse) === false) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
ValueNode.prototype.iterate = function (fn, reverse) {
|
|
return fn(this.entry);
|
|
}
|
|
|
|
createClass(MapIterator, src_Iterator__Iterator);
|
|
|
|
function MapIterator(map, type, reverse) {
|
|
this._type = type;
|
|
this._reverse = reverse;
|
|
this._stack = map._root && mapIteratorFrame(map._root);
|
|
}
|
|
|
|
MapIterator.prototype.next = function() {
|
|
var type = this._type;
|
|
var stack = this._stack;
|
|
while (stack) {
|
|
var node = stack.node;
|
|
var index = stack.index++;
|
|
var maxIndex;
|
|
if (node.entry) {
|
|
if (index === 0) {
|
|
return mapIteratorValue(type, node.entry);
|
|
}
|
|
} else if (node.entries) {
|
|
maxIndex = node.entries.length - 1;
|
|
if (index <= maxIndex) {
|
|
return mapIteratorValue(type, node.entries[this._reverse ? maxIndex - index : index]);
|
|
}
|
|
} else {
|
|
maxIndex = node.nodes.length - 1;
|
|
if (index <= maxIndex) {
|
|
var subNode = node.nodes[this._reverse ? maxIndex - index : index];
|
|
if (subNode) {
|
|
if (subNode.entry) {
|
|
return mapIteratorValue(type, subNode.entry);
|
|
}
|
|
stack = this._stack = mapIteratorFrame(subNode, stack);
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
stack = this._stack = this._stack.__prev;
|
|
}
|
|
return iteratorDone();
|
|
};
|
|
|
|
|
|
function mapIteratorValue(type, entry) {
|
|
return iteratorValue(type, entry[0], entry[1]);
|
|
}
|
|
|
|
function mapIteratorFrame(node, prev) {
|
|
return {
|
|
node: node,
|
|
index: 0,
|
|
__prev: prev
|
|
};
|
|
}
|
|
|
|
function makeMap(size, root, ownerID, hash) {
|
|
var map = Object.create(MapPrototype);
|
|
map.size = size;
|
|
map._root = root;
|
|
map.__ownerID = ownerID;
|
|
map.__hash = hash;
|
|
map.__altered = false;
|
|
return map;
|
|
}
|
|
|
|
var EMPTY_MAP;
|
|
function emptyMap() {
|
|
return EMPTY_MAP || (EMPTY_MAP = makeMap(0));
|
|
}
|
|
|
|
function updateMap(map, k, v) {
|
|
var newRoot;
|
|
var newSize;
|
|
if (!map._root) {
|
|
if (v === NOT_SET) {
|
|
return map;
|
|
}
|
|
newSize = 1;
|
|
newRoot = new ArrayMapNode(map.__ownerID, [[k, v]]);
|
|
} else {
|
|
var didChangeSize = MakeRef(CHANGE_LENGTH);
|
|
var didAlter = MakeRef(DID_ALTER);
|
|
newRoot = updateNode(map._root, map.__ownerID, 0, undefined, k, v, didChangeSize, didAlter);
|
|
if (!didAlter.value) {
|
|
return map;
|
|
}
|
|
newSize = map.size + (didChangeSize.value ? v === NOT_SET ? -1 : 1 : 0);
|
|
}
|
|
if (map.__ownerID) {
|
|
map.size = newSize;
|
|
map._root = newRoot;
|
|
map.__hash = undefined;
|
|
map.__altered = true;
|
|
return map;
|
|
}
|
|
return newRoot ? makeMap(newSize, newRoot) : emptyMap();
|
|
}
|
|
|
|
function updateNode(node, ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
|
|
if (!node) {
|
|
if (value === NOT_SET) {
|
|
return node;
|
|
}
|
|
SetRef(didAlter);
|
|
SetRef(didChangeSize);
|
|
return new ValueNode(ownerID, keyHash, [key, value]);
|
|
}
|
|
return node.update(ownerID, shift, keyHash, key, value, didChangeSize, didAlter);
|
|
}
|
|
|
|
function isLeafNode(node) {
|
|
return node.constructor === ValueNode || node.constructor === HashCollisionNode;
|
|
}
|
|
|
|
function mergeIntoNode(node, ownerID, shift, keyHash, entry) {
|
|
if (node.keyHash === keyHash) {
|
|
return new HashCollisionNode(ownerID, keyHash, [node.entry, entry]);
|
|
}
|
|
|
|
var idx1 = (shift === 0 ? node.keyHash : node.keyHash >>> shift) & MASK;
|
|
var idx2 = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;
|
|
|
|
var newNode;
|
|
var nodes = idx1 === idx2 ?
|
|
[mergeIntoNode(node, ownerID, shift + SHIFT, keyHash, entry)] :
|
|
((newNode = new ValueNode(ownerID, keyHash, entry)), idx1 < idx2 ? [node, newNode] : [newNode, node]);
|
|
|
|
return new BitmapIndexedNode(ownerID, (1 << idx1) | (1 << idx2), nodes);
|
|
}
|
|
|
|
function createNodes(ownerID, entries, key, value) {
|
|
if (!ownerID) {
|
|
ownerID = new OwnerID();
|
|
}
|
|
var node = new ValueNode(ownerID, hash(key), [key, value]);
|
|
for (var ii = 0; ii < entries.length; ii++) {
|
|
var entry = entries[ii];
|
|
node = node.update(ownerID, 0, undefined, entry[0], entry[1]);
|
|
}
|
|
return node;
|
|
}
|
|
|
|
function packNodes(ownerID, nodes, count, excluding) {
|
|
var bitmap = 0;
|
|
var packedII = 0;
|
|
var packedNodes = new Array(count);
|
|
for (var ii = 0, bit = 1, len = nodes.length; ii < len; ii++, bit <<= 1) {
|
|
var node = nodes[ii];
|
|
if (node !== undefined && ii !== excluding) {
|
|
bitmap |= bit;
|
|
packedNodes[packedII++] = node;
|
|
}
|
|
}
|
|
return new BitmapIndexedNode(ownerID, bitmap, packedNodes);
|
|
}
|
|
|
|
function expandNodes(ownerID, nodes, bitmap, including, node) {
|
|
var count = 0;
|
|
var expandedNodes = new Array(SIZE);
|
|
for (var ii = 0; bitmap !== 0; ii++, bitmap >>>= 1) {
|
|
expandedNodes[ii] = bitmap & 1 ? nodes[count++] : undefined;
|
|
}
|
|
expandedNodes[including] = node;
|
|
return new HashArrayMapNode(ownerID, count + 1, expandedNodes);
|
|
}
|
|
|
|
function mergeIntoMapWith(map, merger, iterables) {
|
|
var iters = [];
|
|
for (var ii = 0; ii < iterables.length; ii++) {
|
|
var value = iterables[ii];
|
|
var iter = KeyedIterable(value);
|
|
if (!isIterable(value)) {
|
|
iter = iter.map(function(v ) {return fromJS(v)});
|
|
}
|
|
iters.push(iter);
|
|
}
|
|
return mergeIntoCollectionWith(map, merger, iters);
|
|
}
|
|
|
|
function deepMerger(merger) {
|
|
return function(existing, value, key)
|
|
{return existing && existing.mergeDeepWith && isIterable(value) ?
|
|
existing.mergeDeepWith(merger, value) :
|
|
merger ? merger(existing, value, key) : value};
|
|
}
|
|
|
|
function mergeIntoCollectionWith(collection, merger, iters) {
|
|
iters = iters.filter(function(x ) {return x.size !== 0});
|
|
if (iters.length === 0) {
|
|
return collection;
|
|
}
|
|
if (collection.size === 0 && !collection.__ownerID && iters.length === 1) {
|
|
return collection.constructor(iters[0]);
|
|
}
|
|
return collection.withMutations(function(collection ) {
|
|
var mergeIntoMap = merger ?
|
|
function(value, key) {
|
|
collection.update(key, NOT_SET, function(existing )
|
|
{return existing === NOT_SET ? value : merger(existing, value, key)}
|
|
);
|
|
} :
|
|
function(value, key) {
|
|
collection.set(key, value);
|
|
}
|
|
for (var ii = 0; ii < iters.length; ii++) {
|
|
iters[ii].forEach(mergeIntoMap);
|
|
}
|
|
});
|
|
}
|
|
|
|
function updateInDeepMap(existing, keyPathIter, notSetValue, updater) {
|
|
var isNotSet = existing === NOT_SET;
|
|
var step = keyPathIter.next();
|
|
if (step.done) {
|
|
var existingValue = isNotSet ? notSetValue : existing;
|
|
var newValue = updater(existingValue);
|
|
return newValue === existingValue ? existing : newValue;
|
|
}
|
|
invariant(
|
|
isNotSet || (existing && existing.set),
|
|
'invalid keyPath'
|
|
);
|
|
var key = step.value;
|
|
var nextExisting = isNotSet ? NOT_SET : existing.get(key, NOT_SET);
|
|
var nextUpdated = updateInDeepMap(
|
|
nextExisting,
|
|
keyPathIter,
|
|
notSetValue,
|
|
updater
|
|
);
|
|
return nextUpdated === nextExisting ? existing :
|
|
nextUpdated === NOT_SET ? existing.remove(key) :
|
|
(isNotSet ? emptyMap() : existing).set(key, nextUpdated);
|
|
}
|
|
|
|
function popCount(x) {
|
|
x = x - ((x >> 1) & 0x55555555);
|
|
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
|
|
x = (x + (x >> 4)) & 0x0f0f0f0f;
|
|
x = x + (x >> 8);
|
|
x = x + (x >> 16);
|
|
return x & 0x7f;
|
|
}
|
|
|
|
function setIn(array, idx, val, canEdit) {
|
|
var newArray = canEdit ? array : arrCopy(array);
|
|
newArray[idx] = val;
|
|
return newArray;
|
|
}
|
|
|
|
function spliceIn(array, idx, val, canEdit) {
|
|
var newLen = array.length + 1;
|
|
if (canEdit && idx + 1 === newLen) {
|
|
array[idx] = val;
|
|
return array;
|
|
}
|
|
var newArray = new Array(newLen);
|
|
var after = 0;
|
|
for (var ii = 0; ii < newLen; ii++) {
|
|
if (ii === idx) {
|
|
newArray[ii] = val;
|
|
after = -1;
|
|
} else {
|
|
newArray[ii] = array[ii + after];
|
|
}
|
|
}
|
|
return newArray;
|
|
}
|
|
|
|
function spliceOut(array, idx, canEdit) {
|
|
var newLen = array.length - 1;
|
|
if (canEdit && idx === newLen) {
|
|
array.pop();
|
|
return array;
|
|
}
|
|
var newArray = new Array(newLen);
|
|
var after = 0;
|
|
for (var ii = 0; ii < newLen; ii++) {
|
|
if (ii === idx) {
|
|
after = 1;
|
|
}
|
|
newArray[ii] = array[ii + after];
|
|
}
|
|
return newArray;
|
|
}
|
|
|
|
var MAX_ARRAY_MAP_SIZE = SIZE / 4;
|
|
var MAX_BITMAP_INDEXED_SIZE = SIZE / 2;
|
|
var MIN_HASH_ARRAY_MAP_SIZE = SIZE / 4;
|
|
|
|
createClass(List, IndexedCollection);
|
|
|
|
// @pragma Construction
|
|
|
|
function List(value) {
|
|
var empty = emptyList();
|
|
if (value === null || value === undefined) {
|
|
return empty;
|
|
}
|
|
if (isList(value)) {
|
|
return value;
|
|
}
|
|
var iter = IndexedIterable(value);
|
|
var size = iter.size;
|
|
if (size === 0) {
|
|
return empty;
|
|
}
|
|
assertNotInfinite(size);
|
|
if (size > 0 && size < SIZE) {
|
|
return makeList(0, size, SHIFT, null, new VNode(iter.toArray()));
|
|
}
|
|
return empty.withMutations(function(list ) {
|
|
list.setSize(size);
|
|
iter.forEach(function(v, i) {return list.set(i, v)});
|
|
});
|
|
}
|
|
|
|
List.of = function(/*...values*/) {
|
|
return this(arguments);
|
|
};
|
|
|
|
List.prototype.toString = function() {
|
|
return this.__toString('List [', ']');
|
|
};
|
|
|
|
// @pragma Access
|
|
|
|
List.prototype.get = function(index, notSetValue) {
|
|
index = wrapIndex(this, index);
|
|
if (index < 0 || index >= this.size) {
|
|
return notSetValue;
|
|
}
|
|
index += this._origin;
|
|
var node = listNodeFor(this, index);
|
|
return node && node.array[index & MASK];
|
|
};
|
|
|
|
// @pragma Modification
|
|
|
|
List.prototype.set = function(index, value) {
|
|
return updateList(this, index, value);
|
|
};
|
|
|
|
List.prototype.remove = function(index) {
|
|
return !this.has(index) ? this :
|
|
index === 0 ? this.shift() :
|
|
index === this.size - 1 ? this.pop() :
|
|
this.splice(index, 1);
|
|
};
|
|
|
|
List.prototype.clear = function() {
|
|
if (this.size === 0) {
|
|
return this;
|
|
}
|
|
if (this.__ownerID) {
|
|
this.size = this._origin = this._capacity = 0;
|
|
this._level = SHIFT;
|
|
this._root = this._tail = null;
|
|
this.__hash = undefined;
|
|
this.__altered = true;
|
|
return this;
|
|
}
|
|
return emptyList();
|
|
};
|
|
|
|
List.prototype.push = function(/*...values*/) {
|
|
var values = arguments;
|
|
var oldSize = this.size;
|
|
return this.withMutations(function(list ) {
|
|
setListBounds(list, 0, oldSize + values.length);
|
|
for (var ii = 0; ii < values.length; ii++) {
|
|
list.set(oldSize + ii, values[ii]);
|
|
}
|
|
});
|
|
};
|
|
|
|
List.prototype.pop = function() {
|
|
return setListBounds(this, 0, -1);
|
|
};
|
|
|
|
List.prototype.unshift = function(/*...values*/) {
|
|
var values = arguments;
|
|
return this.withMutations(function(list ) {
|
|
setListBounds(list, -values.length);
|
|
for (var ii = 0; ii < values.length; ii++) {
|
|
list.set(ii, values[ii]);
|
|
}
|
|
});
|
|
};
|
|
|
|
List.prototype.shift = function() {
|
|
return setListBounds(this, 1);
|
|
};
|
|
|
|
// @pragma Composition
|
|
|
|
List.prototype.merge = function(/*...iters*/) {
|
|
return mergeIntoListWith(this, undefined, arguments);
|
|
};
|
|
|
|
List.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1);
|
|
return mergeIntoListWith(this, merger, iters);
|
|
};
|
|
|
|
List.prototype.mergeDeep = function(/*...iters*/) {
|
|
return mergeIntoListWith(this, deepMerger(undefined), arguments);
|
|
};
|
|
|
|
List.prototype.mergeDeepWith = function(merger) {var iters = SLICE$0.call(arguments, 1);
|
|
return mergeIntoListWith(this, deepMerger(merger), iters);
|
|
};
|
|
|
|
List.prototype.setSize = function(size) {
|
|
return setListBounds(this, 0, size);
|
|
};
|
|
|
|
// @pragma Iteration
|
|
|
|
List.prototype.slice = function(begin, end) {
|
|
var size = this.size;
|
|
if (wholeSlice(begin, end, size)) {
|
|
return this;
|
|
}
|
|
return setListBounds(
|
|
this,
|
|
resolveBegin(begin, size),
|
|
resolveEnd(end, size)
|
|
);
|
|
};
|
|
|
|
List.prototype.__iterator = function(type, reverse) {
|
|
var index = 0;
|
|
var values = iterateList(this, reverse);
|
|
return new src_Iterator__Iterator(function() {
|
|
var value = values();
|
|
return value === DONE ?
|
|
iteratorDone() :
|
|
iteratorValue(type, index++, value);
|
|
});
|
|
};
|
|
|
|
List.prototype.__iterate = function(fn, reverse) {
|
|
var index = 0;
|
|
var values = iterateList(this, reverse);
|
|
var value;
|
|
while ((value = values()) !== DONE) {
|
|
if (fn(value, index++, this) === false) {
|
|
break;
|
|
}
|
|
}
|
|
return index;
|
|
};
|
|
|
|
List.prototype.__ensureOwner = function(ownerID) {
|
|
if (ownerID === this.__ownerID) {
|
|
return this;
|
|
}
|
|
if (!ownerID) {
|
|
this.__ownerID = ownerID;
|
|
return this;
|
|
}
|
|
return makeList(this._origin, this._capacity, this._level, this._root, this._tail, ownerID, this.__hash);
|
|
};
|
|
|
|
|
|
function isList(maybeList) {
|
|
return !!(maybeList && maybeList[IS_LIST_SENTINEL]);
|
|
}
|
|
|
|
List.isList = isList;
|
|
|
|
var IS_LIST_SENTINEL = '@@__IMMUTABLE_LIST__@@';
|
|
|
|
var ListPrototype = List.prototype;
|
|
ListPrototype[IS_LIST_SENTINEL] = true;
|
|
ListPrototype[DELETE] = ListPrototype.remove;
|
|
ListPrototype.setIn = MapPrototype.setIn;
|
|
ListPrototype.deleteIn =
|
|
ListPrototype.removeIn = MapPrototype.removeIn;
|
|
ListPrototype.update = MapPrototype.update;
|
|
ListPrototype.updateIn = MapPrototype.updateIn;
|
|
ListPrototype.mergeIn = MapPrototype.mergeIn;
|
|
ListPrototype.mergeDeepIn = MapPrototype.mergeDeepIn;
|
|
ListPrototype.withMutations = MapPrototype.withMutations;
|
|
ListPrototype.asMutable = MapPrototype.asMutable;
|
|
ListPrototype.asImmutable = MapPrototype.asImmutable;
|
|
ListPrototype.wasAltered = MapPrototype.wasAltered;
|
|
|
|
|
|
|
|
function VNode(array, ownerID) {
|
|
this.array = array;
|
|
this.ownerID = ownerID;
|
|
}
|
|
|
|
// TODO: seems like these methods are very similar
|
|
|
|
VNode.prototype.removeBefore = function(ownerID, level, index) {
|
|
if (index === level ? 1 << level : 0 || this.array.length === 0) {
|
|
return this;
|
|
}
|
|
var originIndex = (index >>> level) & MASK;
|
|
if (originIndex >= this.array.length) {
|
|
return new VNode([], ownerID);
|
|
}
|
|
var removingFirst = originIndex === 0;
|
|
var newChild;
|
|
if (level > 0) {
|
|
var oldChild = this.array[originIndex];
|
|
newChild = oldChild && oldChild.removeBefore(ownerID, level - SHIFT, index);
|
|
if (newChild === oldChild && removingFirst) {
|
|
return this;
|
|
}
|
|
}
|
|
if (removingFirst && !newChild) {
|
|
return this;
|
|
}
|
|
var editable = editableVNode(this, ownerID);
|
|
if (!removingFirst) {
|
|
for (var ii = 0; ii < originIndex; ii++) {
|
|
editable.array[ii] = undefined;
|
|
}
|
|
}
|
|
if (newChild) {
|
|
editable.array[originIndex] = newChild;
|
|
}
|
|
return editable;
|
|
};
|
|
|
|
VNode.prototype.removeAfter = function(ownerID, level, index) {
|
|
if (index === level ? 1 << level : 0 || this.array.length === 0) {
|
|
return this;
|
|
}
|
|
var sizeIndex = ((index - 1) >>> level) & MASK;
|
|
if (sizeIndex >= this.array.length) {
|
|
return this;
|
|
}
|
|
var removingLast = sizeIndex === this.array.length - 1;
|
|
var newChild;
|
|
if (level > 0) {
|
|
var oldChild = this.array[sizeIndex];
|
|
newChild = oldChild && oldChild.removeAfter(ownerID, level - SHIFT, index);
|
|
if (newChild === oldChild && removingLast) {
|
|
return this;
|
|
}
|
|
}
|
|
if (removingLast && !newChild) {
|
|
return this;
|
|
}
|
|
var editable = editableVNode(this, ownerID);
|
|
if (!removingLast) {
|
|
editable.array.pop();
|
|
}
|
|
if (newChild) {
|
|
editable.array[sizeIndex] = newChild;
|
|
}
|
|
return editable;
|
|
};
|
|
|
|
|
|
|
|
var DONE = {};
|
|
|
|
function iterateList(list, reverse) {
|
|
var left = list._origin;
|
|
var right = list._capacity;
|
|
var tailPos = getTailOffset(right);
|
|
var tail = list._tail;
|
|
|
|
return iterateNodeOrLeaf(list._root, list._level, 0);
|
|
|
|
function iterateNodeOrLeaf(node, level, offset) {
|
|
return level === 0 ?
|
|
iterateLeaf(node, offset) :
|
|
iterateNode(node, level, offset);
|
|
}
|
|
|
|
function iterateLeaf(node, offset) {
|
|
var array = offset === tailPos ? tail && tail.array : node && node.array;
|
|
var from = offset > left ? 0 : left - offset;
|
|
var to = right - offset;
|
|
if (to > SIZE) {
|
|
to = SIZE;
|
|
}
|
|
return function() {
|
|
if (from === to) {
|
|
return DONE;
|
|
}
|
|
var idx = reverse ? --to : from++;
|
|
return array && array[idx];
|
|
};
|
|
}
|
|
|
|
function iterateNode(node, level, offset) {
|
|
var values;
|
|
var array = node && node.array;
|
|
var from = offset > left ? 0 : (left - offset) >> level;
|
|
var to = ((right - offset) >> level) + 1;
|
|
if (to > SIZE) {
|
|
to = SIZE;
|
|
}
|
|
return function() {
|
|
do {
|
|
if (values) {
|
|
var value = values();
|
|
if (value !== DONE) {
|
|
return value;
|
|
}
|
|
values = null;
|
|
}
|
|
if (from === to) {
|
|
return DONE;
|
|
}
|
|
var idx = reverse ? --to : from++;
|
|
values = iterateNodeOrLeaf(
|
|
array && array[idx], level - SHIFT, offset + (idx << level)
|
|
);
|
|
} while (true);
|
|
};
|
|
}
|
|
}
|
|
|
|
function makeList(origin, capacity, level, root, tail, ownerID, hash) {
|
|
var list = Object.create(ListPrototype);
|
|
list.size = capacity - origin;
|
|
list._origin = origin;
|
|
list._capacity = capacity;
|
|
list._level = level;
|
|
list._root = root;
|
|
list._tail = tail;
|
|
list.__ownerID = ownerID;
|
|
list.__hash = hash;
|
|
list.__altered = false;
|
|
return list;
|
|
}
|
|
|
|
var EMPTY_LIST;
|
|
function emptyList() {
|
|
return EMPTY_LIST || (EMPTY_LIST = makeList(0, 0, SHIFT));
|
|
}
|
|
|
|
function updateList(list, index, value) {
|
|
index = wrapIndex(list, index);
|
|
|
|
if (index >= list.size || index < 0) {
|
|
return list.withMutations(function(list ) {
|
|
index < 0 ?
|
|
setListBounds(list, index).set(0, value) :
|
|
setListBounds(list, 0, index + 1).set(index, value)
|
|
});
|
|
}
|
|
|
|
index += list._origin;
|
|
|
|
var newTail = list._tail;
|
|
var newRoot = list._root;
|
|
var didAlter = MakeRef(DID_ALTER);
|
|
if (index >= getTailOffset(list._capacity)) {
|
|
newTail = updateVNode(newTail, list.__ownerID, 0, index, value, didAlter);
|
|
} else {
|
|
newRoot = updateVNode(newRoot, list.__ownerID, list._level, index, value, didAlter);
|
|
}
|
|
|
|
if (!didAlter.value) {
|
|
return list;
|
|
}
|
|
|
|
if (list.__ownerID) {
|
|
list._root = newRoot;
|
|
list._tail = newTail;
|
|
list.__hash = undefined;
|
|
list.__altered = true;
|
|
return list;
|
|
}
|
|
return makeList(list._origin, list._capacity, list._level, newRoot, newTail);
|
|
}
|
|
|
|
function updateVNode(node, ownerID, level, index, value, didAlter) {
|
|
var idx = (index >>> level) & MASK;
|
|
var nodeHas = node && idx < node.array.length;
|
|
if (!nodeHas && value === undefined) {
|
|
return node;
|
|
}
|
|
|
|
var newNode;
|
|
|
|
if (level > 0) {
|
|
var lowerNode = node && node.array[idx];
|
|
var newLowerNode = updateVNode(lowerNode, ownerID, level - SHIFT, index, value, didAlter);
|
|
if (newLowerNode === lowerNode) {
|
|
return node;
|
|
}
|
|
newNode = editableVNode(node, ownerID);
|
|
newNode.array[idx] = newLowerNode;
|
|
return newNode;
|
|
}
|
|
|
|
if (nodeHas && node.array[idx] === value) {
|
|
return node;
|
|
}
|
|
|
|
SetRef(didAlter);
|
|
|
|
newNode = editableVNode(node, ownerID);
|
|
if (value === undefined && idx === newNode.array.length - 1) {
|
|
newNode.array.pop();
|
|
} else {
|
|
newNode.array[idx] = value;
|
|
}
|
|
return newNode;
|
|
}
|
|
|
|
function editableVNode(node, ownerID) {
|
|
if (ownerID && node && ownerID === node.ownerID) {
|
|
return node;
|
|
}
|
|
return new VNode(node ? node.array.slice() : [], ownerID);
|
|
}
|
|
|
|
function listNodeFor(list, rawIndex) {
|
|
if (rawIndex >= getTailOffset(list._capacity)) {
|
|
return list._tail;
|
|
}
|
|
if (rawIndex < 1 << (list._level + SHIFT)) {
|
|
var node = list._root;
|
|
var level = list._level;
|
|
while (node && level > 0) {
|
|
node = node.array[(rawIndex >>> level) & MASK];
|
|
level -= SHIFT;
|
|
}
|
|
return node;
|
|
}
|
|
}
|
|
|
|
function setListBounds(list, begin, end) {
|
|
var owner = list.__ownerID || new OwnerID();
|
|
var oldOrigin = list._origin;
|
|
var oldCapacity = list._capacity;
|
|
var newOrigin = oldOrigin + begin;
|
|
var newCapacity = end === undefined ? oldCapacity : end < 0 ? oldCapacity + end : oldOrigin + end;
|
|
if (newOrigin === oldOrigin && newCapacity === oldCapacity) {
|
|
return list;
|
|
}
|
|
|
|
// If it's going to end after it starts, it's empty.
|
|
if (newOrigin >= newCapacity) {
|
|
return list.clear();
|
|
}
|
|
|
|
var newLevel = list._level;
|
|
var newRoot = list._root;
|
|
|
|
// New origin might need creating a higher root.
|
|
var offsetShift = 0;
|
|
while (newOrigin + offsetShift < 0) {
|
|
newRoot = new VNode(newRoot && newRoot.array.length ? [undefined, newRoot] : [], owner);
|
|
newLevel += SHIFT;
|
|
offsetShift += 1 << newLevel;
|
|
}
|
|
if (offsetShift) {
|
|
newOrigin += offsetShift;
|
|
oldOrigin += offsetShift;
|
|
newCapacity += offsetShift;
|
|
oldCapacity += offsetShift;
|
|
}
|
|
|
|
var oldTailOffset = getTailOffset(oldCapacity);
|
|
var newTailOffset = getTailOffset(newCapacity);
|
|
|
|
// New size might need creating a higher root.
|
|
while (newTailOffset >= 1 << (newLevel + SHIFT)) {
|
|
newRoot = new VNode(newRoot && newRoot.array.length ? [newRoot] : [], owner);
|
|
newLevel += SHIFT;
|
|
}
|
|
|
|
// Locate or create the new tail.
|
|
var oldTail = list._tail;
|
|
var newTail = newTailOffset < oldTailOffset ?
|
|
listNodeFor(list, newCapacity - 1) :
|
|
newTailOffset > oldTailOffset ? new VNode([], owner) : oldTail;
|
|
|
|
// Merge Tail into tree.
|
|
if (oldTail && newTailOffset > oldTailOffset && newOrigin < oldCapacity && oldTail.array.length) {
|
|
newRoot = editableVNode(newRoot, owner);
|
|
var node = newRoot;
|
|
for (var level = newLevel; level > SHIFT; level -= SHIFT) {
|
|
var idx = (oldTailOffset >>> level) & MASK;
|
|
node = node.array[idx] = editableVNode(node.array[idx], owner);
|
|
}
|
|
node.array[(oldTailOffset >>> SHIFT) & MASK] = oldTail;
|
|
}
|
|
|
|
// If the size has been reduced, there's a chance the tail needs to be trimmed.
|
|
if (newCapacity < oldCapacity) {
|
|
newTail = newTail && newTail.removeAfter(owner, 0, newCapacity);
|
|
}
|
|
|
|
// If the new origin is within the tail, then we do not need a root.
|
|
if (newOrigin >= newTailOffset) {
|
|
newOrigin -= newTailOffset;
|
|
newCapacity -= newTailOffset;
|
|
newLevel = SHIFT;
|
|
newRoot = null;
|
|
newTail = newTail && newTail.removeBefore(owner, 0, newOrigin);
|
|
|
|
// Otherwise, if the root has been trimmed, garbage collect.
|
|
} else if (newOrigin > oldOrigin || newTailOffset < oldTailOffset) {
|
|
offsetShift = 0;
|
|
|
|
// Identify the new top root node of the subtree of the old root.
|
|
while (newRoot) {
|
|
var beginIndex = (newOrigin >>> newLevel) & MASK;
|
|
if (beginIndex !== (newTailOffset >>> newLevel) & MASK) {
|
|
break;
|
|
}
|
|
if (beginIndex) {
|
|
offsetShift += (1 << newLevel) * beginIndex;
|
|
}
|
|
newLevel -= SHIFT;
|
|
newRoot = newRoot.array[beginIndex];
|
|
}
|
|
|
|
// Trim the new sides of the new root.
|
|
if (newRoot && newOrigin > oldOrigin) {
|
|
newRoot = newRoot.removeBefore(owner, newLevel, newOrigin - offsetShift);
|
|
}
|
|
if (newRoot && newTailOffset < oldTailOffset) {
|
|
newRoot = newRoot.removeAfter(owner, newLevel, newTailOffset - offsetShift);
|
|
}
|
|
if (offsetShift) {
|
|
newOrigin -= offsetShift;
|
|
newCapacity -= offsetShift;
|
|
}
|
|
}
|
|
|
|
if (list.__ownerID) {
|
|
list.size = newCapacity - newOrigin;
|
|
list._origin = newOrigin;
|
|
list._capacity = newCapacity;
|
|
list._level = newLevel;
|
|
list._root = newRoot;
|
|
list._tail = newTail;
|
|
list.__hash = undefined;
|
|
list.__altered = true;
|
|
return list;
|
|
}
|
|
return makeList(newOrigin, newCapacity, newLevel, newRoot, newTail);
|
|
}
|
|
|
|
function mergeIntoListWith(list, merger, iterables) {
|
|
var iters = [];
|
|
var maxSize = 0;
|
|
for (var ii = 0; ii < iterables.length; ii++) {
|
|
var value = iterables[ii];
|
|
var iter = IndexedIterable(value);
|
|
if (iter.size > maxSize) {
|
|
maxSize = iter.size;
|
|
}
|
|
if (!isIterable(value)) {
|
|
iter = iter.map(function(v ) {return fromJS(v)});
|
|
}
|
|
iters.push(iter);
|
|
}
|
|
if (maxSize > list.size) {
|
|
list = list.setSize(maxSize);
|
|
}
|
|
return mergeIntoCollectionWith(list, merger, iters);
|
|
}
|
|
|
|
function getTailOffset(size) {
|
|
return size < SIZE ? 0 : (((size - 1) >>> SHIFT) << SHIFT);
|
|
}
|
|
|
|
createClass(OrderedMap, src_Map__Map);
|
|
|
|
// @pragma Construction
|
|
|
|
function OrderedMap(value) {
|
|
return value === null || value === undefined ? emptyOrderedMap() :
|
|
isOrderedMap(value) ? value :
|
|
emptyOrderedMap().withMutations(function(map ) {
|
|
var iter = KeyedIterable(value);
|
|
assertNotInfinite(iter.size);
|
|
iter.forEach(function(v, k) {return map.set(k, v)});
|
|
});
|
|
}
|
|
|
|
OrderedMap.of = function(/*...values*/) {
|
|
return this(arguments);
|
|
};
|
|
|
|
OrderedMap.prototype.toString = function() {
|
|
return this.__toString('OrderedMap {', '}');
|
|
};
|
|
|
|
// @pragma Access
|
|
|
|
OrderedMap.prototype.get = function(k, notSetValue) {
|
|
var index = this._map.get(k);
|
|
return index !== undefined ? this._list.get(index)[1] : notSetValue;
|
|
};
|
|
|
|
// @pragma Modification
|
|
|
|
OrderedMap.prototype.clear = function() {
|
|
if (this.size === 0) {
|
|
return this;
|
|
}
|
|
if (this.__ownerID) {
|
|
this.size = 0;
|
|
this._map.clear();
|
|
this._list.clear();
|
|
return this;
|
|
}
|
|
return emptyOrderedMap();
|
|
};
|
|
|
|
OrderedMap.prototype.set = function(k, v) {
|
|
return updateOrderedMap(this, k, v);
|
|
};
|
|
|
|
OrderedMap.prototype.remove = function(k) {
|
|
return updateOrderedMap(this, k, NOT_SET);
|
|
};
|
|
|
|
OrderedMap.prototype.wasAltered = function() {
|
|
return this._map.wasAltered() || this._list.wasAltered();
|
|
};
|
|
|
|
OrderedMap.prototype.__iterate = function(fn, reverse) {var this$0 = this;
|
|
return this._list.__iterate(
|
|
function(entry ) {return entry && fn(entry[1], entry[0], this$0)},
|
|
reverse
|
|
);
|
|
};
|
|
|
|
OrderedMap.prototype.__iterator = function(type, reverse) {
|
|
return this._list.fromEntrySeq().__iterator(type, reverse);
|
|
};
|
|
|
|
OrderedMap.prototype.__ensureOwner = function(ownerID) {
|
|
if (ownerID === this.__ownerID) {
|
|
return this;
|
|
}
|
|
var newMap = this._map.__ensureOwner(ownerID);
|
|
var newList = this._list.__ensureOwner(ownerID);
|
|
if (!ownerID) {
|
|
this.__ownerID = ownerID;
|
|
this._map = newMap;
|
|
this._list = newList;
|
|
return this;
|
|
}
|
|
return makeOrderedMap(newMap, newList, ownerID, this.__hash);
|
|
};
|
|
|
|
|
|
function isOrderedMap(maybeOrderedMap) {
|
|
return isMap(maybeOrderedMap) && isOrdered(maybeOrderedMap);
|
|
}
|
|
|
|
OrderedMap.isOrderedMap = isOrderedMap;
|
|
|
|
OrderedMap.prototype[IS_ORDERED_SENTINEL] = true;
|
|
OrderedMap.prototype[DELETE] = OrderedMap.prototype.remove;
|
|
|
|
|
|
|
|
function makeOrderedMap(map, list, ownerID, hash) {
|
|
var omap = Object.create(OrderedMap.prototype);
|
|
omap.size = map ? map.size : 0;
|
|
omap._map = map;
|
|
omap._list = list;
|
|
omap.__ownerID = ownerID;
|
|
omap.__hash = hash;
|
|
return omap;
|
|
}
|
|
|
|
var EMPTY_ORDERED_MAP;
|
|
function emptyOrderedMap() {
|
|
return EMPTY_ORDERED_MAP || (EMPTY_ORDERED_MAP = makeOrderedMap(emptyMap(), emptyList()));
|
|
}
|
|
|
|
function updateOrderedMap(omap, k, v) {
|
|
var map = omap._map;
|
|
var list = omap._list;
|
|
var i = map.get(k);
|
|
var has = i !== undefined;
|
|
var newMap;
|
|
var newList;
|
|
if (v === NOT_SET) { // removed
|
|
if (!has) {
|
|
return omap;
|
|
}
|
|
if (list.size >= SIZE && list.size >= map.size * 2) {
|
|
newList = list.filter(function(entry, idx) {return entry !== undefined && i !== idx});
|
|
newMap = newList.toKeyedSeq().map(function(entry ) {return entry[0]}).flip().toMap();
|
|
if (omap.__ownerID) {
|
|
newMap.__ownerID = newList.__ownerID = omap.__ownerID;
|
|
}
|
|
} else {
|
|
newMap = map.remove(k);
|
|
newList = i === list.size - 1 ? list.pop() : list.set(i, undefined);
|
|
}
|
|
} else {
|
|
if (has) {
|
|
if (v === list.get(i)[1]) {
|
|
return omap;
|
|
}
|
|
newMap = map;
|
|
newList = list.set(i, [k, v]);
|
|
} else {
|
|
newMap = map.set(k, list.size);
|
|
newList = list.set(list.size, [k, v]);
|
|
}
|
|
}
|
|
if (omap.__ownerID) {
|
|
omap.size = newMap.size;
|
|
omap._map = newMap;
|
|
omap._list = newList;
|
|
omap.__hash = undefined;
|
|
return omap;
|
|
}
|
|
return makeOrderedMap(newMap, newList);
|
|
}
|
|
|
|
createClass(Stack, IndexedCollection);
|
|
|
|
// @pragma Construction
|
|
|
|
function Stack(value) {
|
|
return value === null || value === undefined ? emptyStack() :
|
|
isStack(value) ? value :
|
|
emptyStack().unshiftAll(value);
|
|
}
|
|
|
|
Stack.of = function(/*...values*/) {
|
|
return this(arguments);
|
|
};
|
|
|
|
Stack.prototype.toString = function() {
|
|
return this.__toString('Stack [', ']');
|
|
};
|
|
|
|
// @pragma Access
|
|
|
|
Stack.prototype.get = function(index, notSetValue) {
|
|
var head = this._head;
|
|
index = wrapIndex(this, index);
|
|
while (head && index--) {
|
|
head = head.next;
|
|
}
|
|
return head ? head.value : notSetValue;
|
|
};
|
|
|
|
Stack.prototype.peek = function() {
|
|
return this._head && this._head.value;
|
|
};
|
|
|
|
// @pragma Modification
|
|
|
|
Stack.prototype.push = function(/*...values*/) {
|
|
if (arguments.length === 0) {
|
|
return this;
|
|
}
|
|
var newSize = this.size + arguments.length;
|
|
var head = this._head;
|
|
for (var ii = arguments.length - 1; ii >= 0; ii--) {
|
|
head = {
|
|
value: arguments[ii],
|
|
next: head
|
|
};
|
|
}
|
|
if (this.__ownerID) {
|
|
this.size = newSize;
|
|
this._head = head;
|
|
this.__hash = undefined;
|
|
this.__altered = true;
|
|
return this;
|
|
}
|
|
return makeStack(newSize, head);
|
|
};
|
|
|
|
Stack.prototype.pushAll = function(iter) {
|
|
iter = IndexedIterable(iter);
|
|
if (iter.size === 0) {
|
|
return this;
|
|
}
|
|
assertNotInfinite(iter.size);
|
|
var newSize = this.size;
|
|
var head = this._head;
|
|
iter.reverse().forEach(function(value ) {
|
|
newSize++;
|
|
head = {
|
|
value: value,
|
|
next: head
|
|
};
|
|
});
|
|
if (this.__ownerID) {
|
|
this.size = newSize;
|
|
this._head = head;
|
|
this.__hash = undefined;
|
|
this.__altered = true;
|
|
return this;
|
|
}
|
|
return makeStack(newSize, head);
|
|
};
|
|
|
|
Stack.prototype.pop = function() {
|
|
return this.slice(1);
|
|
};
|
|
|
|
Stack.prototype.unshift = function(/*...values*/) {
|
|
return this.push.apply(this, arguments);
|
|
};
|
|
|
|
Stack.prototype.unshiftAll = function(iter) {
|
|
return this.pushAll(iter);
|
|
};
|
|
|
|
Stack.prototype.shift = function() {
|
|
return this.pop.apply(this, arguments);
|
|
};
|
|
|
|
Stack.prototype.clear = function() {
|
|
if (this.size === 0) {
|
|
return this;
|
|
}
|
|
if (this.__ownerID) {
|
|
this.size = 0;
|
|
this._head = undefined;
|
|
this.__hash = undefined;
|
|
this.__altered = true;
|
|
return this;
|
|
}
|
|
return emptyStack();
|
|
};
|
|
|
|
Stack.prototype.slice = function(begin, end) {
|
|
if (wholeSlice(begin, end, this.size)) {
|
|
return this;
|
|
}
|
|
var resolvedBegin = resolveBegin(begin, this.size);
|
|
var resolvedEnd = resolveEnd(end, this.size);
|
|
if (resolvedEnd !== this.size) {
|
|
// super.slice(begin, end);
|
|
return IndexedCollection.prototype.slice.call(this, begin, end);
|
|
}
|
|
var newSize = this.size - resolvedBegin;
|
|
var head = this._head;
|
|
while (resolvedBegin--) {
|
|
head = head.next;
|
|
}
|
|
if (this.__ownerID) {
|
|
this.size = newSize;
|
|
this._head = head;
|
|
this.__hash = undefined;
|
|
this.__altered = true;
|
|
return this;
|
|
}
|
|
return makeStack(newSize, head);
|
|
};
|
|
|
|
// @pragma Mutability
|
|
|
|
Stack.prototype.__ensureOwner = function(ownerID) {
|
|
if (ownerID === this.__ownerID) {
|
|
return this;
|
|
}
|
|
if (!ownerID) {
|
|
this.__ownerID = ownerID;
|
|
this.__altered = false;
|
|
return this;
|
|
}
|
|
return makeStack(this.size, this._head, ownerID, this.__hash);
|
|
};
|
|
|
|
// @pragma Iteration
|
|
|
|
Stack.prototype.__iterate = function(fn, reverse) {
|
|
if (reverse) {
|
|
return this.reverse().__iterate(fn);
|
|
}
|
|
var iterations = 0;
|
|
var node = this._head;
|
|
while (node) {
|
|
if (fn(node.value, iterations++, this) === false) {
|
|
break;
|
|
}
|
|
node = node.next;
|
|
}
|
|
return iterations;
|
|
};
|
|
|
|
Stack.prototype.__iterator = function(type, reverse) {
|
|
if (reverse) {
|
|
return this.reverse().__iterator(type);
|
|
}
|
|
var iterations = 0;
|
|
var node = this._head;
|
|
return new src_Iterator__Iterator(function() {
|
|
if (node) {
|
|
var value = node.value;
|
|
node = node.next;
|
|
return iteratorValue(type, iterations++, value);
|
|
}
|
|
return iteratorDone();
|
|
});
|
|
};
|
|
|
|
|
|
function isStack(maybeStack) {
|
|
return !!(maybeStack && maybeStack[IS_STACK_SENTINEL]);
|
|
}
|
|
|
|
Stack.isStack = isStack;
|
|
|
|
var IS_STACK_SENTINEL = '@@__IMMUTABLE_STACK__@@';
|
|
|
|
var StackPrototype = Stack.prototype;
|
|
StackPrototype[IS_STACK_SENTINEL] = true;
|
|
StackPrototype.withMutations = MapPrototype.withMutations;
|
|
StackPrototype.asMutable = MapPrototype.asMutable;
|
|
StackPrototype.asImmutable = MapPrototype.asImmutable;
|
|
StackPrototype.wasAltered = MapPrototype.wasAltered;
|
|
|
|
|
|
function makeStack(size, head, ownerID, hash) {
|
|
var map = Object.create(StackPrototype);
|
|
map.size = size;
|
|
map._head = head;
|
|
map.__ownerID = ownerID;
|
|
map.__hash = hash;
|
|
map.__altered = false;
|
|
return map;
|
|
}
|
|
|
|
var EMPTY_STACK;
|
|
function emptyStack() {
|
|
return EMPTY_STACK || (EMPTY_STACK = makeStack(0));
|
|
}
|
|
|
|
createClass(src_Set__Set, SetCollection);
|
|
|
|
// @pragma Construction
|
|
|
|
function src_Set__Set(value) {
|
|
return value === null || value === undefined ? emptySet() :
|
|
isSet(value) ? value :
|
|
emptySet().withMutations(function(set ) {
|
|
var iter = SetIterable(value);
|
|
assertNotInfinite(iter.size);
|
|
iter.forEach(function(v ) {return set.add(v)});
|
|
});
|
|
}
|
|
|
|
src_Set__Set.of = function(/*...values*/) {
|
|
return this(arguments);
|
|
};
|
|
|
|
src_Set__Set.fromKeys = function(value) {
|
|
return this(KeyedIterable(value).keySeq());
|
|
};
|
|
|
|
src_Set__Set.prototype.toString = function() {
|
|
return this.__toString('Set {', '}');
|
|
};
|
|
|
|
// @pragma Access
|
|
|
|
src_Set__Set.prototype.has = function(value) {
|
|
return this._map.has(value);
|
|
};
|
|
|
|
// @pragma Modification
|
|
|
|
src_Set__Set.prototype.add = function(value) {
|
|
return updateSet(this, this._map.set(value, true));
|
|
};
|
|
|
|
src_Set__Set.prototype.remove = function(value) {
|
|
return updateSet(this, this._map.remove(value));
|
|
};
|
|
|
|
src_Set__Set.prototype.clear = function() {
|
|
return updateSet(this, this._map.clear());
|
|
};
|
|
|
|
// @pragma Composition
|
|
|
|
src_Set__Set.prototype.union = function() {var iters = SLICE$0.call(arguments, 0);
|
|
iters = iters.filter(function(x ) {return x.size !== 0});
|
|
if (iters.length === 0) {
|
|
return this;
|
|
}
|
|
if (this.size === 0 && !this.__ownerID && iters.length === 1) {
|
|
return this.constructor(iters[0]);
|
|
}
|
|
return this.withMutations(function(set ) {
|
|
for (var ii = 0; ii < iters.length; ii++) {
|
|
SetIterable(iters[ii]).forEach(function(value ) {return set.add(value)});
|
|
}
|
|
});
|
|
};
|
|
|
|
src_Set__Set.prototype.intersect = function() {var iters = SLICE$0.call(arguments, 0);
|
|
if (iters.length === 0) {
|
|
return this;
|
|
}
|
|
iters = iters.map(function(iter ) {return SetIterable(iter)});
|
|
var originalSet = this;
|
|
return this.withMutations(function(set ) {
|
|
originalSet.forEach(function(value ) {
|
|
if (!iters.every(function(iter ) {return iter.includes(value)})) {
|
|
set.remove(value);
|
|
}
|
|
});
|
|
});
|
|
};
|
|
|
|
src_Set__Set.prototype.subtract = function() {var iters = SLICE$0.call(arguments, 0);
|
|
if (iters.length === 0) {
|
|
return this;
|
|
}
|
|
iters = iters.map(function(iter ) {return SetIterable(iter)});
|
|
var originalSet = this;
|
|
return this.withMutations(function(set ) {
|
|
originalSet.forEach(function(value ) {
|
|
if (iters.some(function(iter ) {return iter.includes(value)})) {
|
|
set.remove(value);
|
|
}
|
|
});
|
|
});
|
|
};
|
|
|
|
src_Set__Set.prototype.merge = function() {
|
|
return this.union.apply(this, arguments);
|
|
};
|
|
|
|
src_Set__Set.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1);
|
|
return this.union.apply(this, iters);
|
|
};
|
|
|
|
src_Set__Set.prototype.sort = function(comparator) {
|
|
// Late binding
|
|
return OrderedSet(sortFactory(this, comparator));
|
|
};
|
|
|
|
src_Set__Set.prototype.sortBy = function(mapper, comparator) {
|
|
// Late binding
|
|
return OrderedSet(sortFactory(this, comparator, mapper));
|
|
};
|
|
|
|
src_Set__Set.prototype.wasAltered = function() {
|
|
return this._map.wasAltered();
|
|
};
|
|
|
|
src_Set__Set.prototype.__iterate = function(fn, reverse) {var this$0 = this;
|
|
return this._map.__iterate(function(_, k) {return fn(k, k, this$0)}, reverse);
|
|
};
|
|
|
|
src_Set__Set.prototype.__iterator = function(type, reverse) {
|
|
return this._map.map(function(_, k) {return k}).__iterator(type, reverse);
|
|
};
|
|
|
|
src_Set__Set.prototype.__ensureOwner = function(ownerID) {
|
|
if (ownerID === this.__ownerID) {
|
|
return this;
|
|
}
|
|
var newMap = this._map.__ensureOwner(ownerID);
|
|
if (!ownerID) {
|
|
this.__ownerID = ownerID;
|
|
this._map = newMap;
|
|
return this;
|
|
}
|
|
return this.__make(newMap, ownerID);
|
|
};
|
|
|
|
|
|
function isSet(maybeSet) {
|
|
return !!(maybeSet && maybeSet[IS_SET_SENTINEL]);
|
|
}
|
|
|
|
src_Set__Set.isSet = isSet;
|
|
|
|
var IS_SET_SENTINEL = '@@__IMMUTABLE_SET__@@';
|
|
|
|
var SetPrototype = src_Set__Set.prototype;
|
|
SetPrototype[IS_SET_SENTINEL] = true;
|
|
SetPrototype[DELETE] = SetPrototype.remove;
|
|
SetPrototype.mergeDeep = SetPrototype.merge;
|
|
SetPrototype.mergeDeepWith = SetPrototype.mergeWith;
|
|
SetPrototype.withMutations = MapPrototype.withMutations;
|
|
SetPrototype.asMutable = MapPrototype.asMutable;
|
|
SetPrototype.asImmutable = MapPrototype.asImmutable;
|
|
|
|
SetPrototype.__empty = emptySet;
|
|
SetPrototype.__make = makeSet;
|
|
|
|
function updateSet(set, newMap) {
|
|
if (set.__ownerID) {
|
|
set.size = newMap.size;
|
|
set._map = newMap;
|
|
return set;
|
|
}
|
|
return newMap === set._map ? set :
|
|
newMap.size === 0 ? set.__empty() :
|
|
set.__make(newMap);
|
|
}
|
|
|
|
function makeSet(map, ownerID) {
|
|
var set = Object.create(SetPrototype);
|
|
set.size = map ? map.size : 0;
|
|
set._map = map;
|
|
set.__ownerID = ownerID;
|
|
return set;
|
|
}
|
|
|
|
var EMPTY_SET;
|
|
function emptySet() {
|
|
return EMPTY_SET || (EMPTY_SET = makeSet(emptyMap()));
|
|
}
|
|
|
|
createClass(OrderedSet, src_Set__Set);
|
|
|
|
// @pragma Construction
|
|
|
|
function OrderedSet(value) {
|
|
return value === null || value === undefined ? emptyOrderedSet() :
|
|
isOrderedSet(value) ? value :
|
|
emptyOrderedSet().withMutations(function(set ) {
|
|
var iter = SetIterable(value);
|
|
assertNotInfinite(iter.size);
|
|
iter.forEach(function(v ) {return set.add(v)});
|
|
});
|
|
}
|
|
|
|
OrderedSet.of = function(/*...values*/) {
|
|
return this(arguments);
|
|
};
|
|
|
|
OrderedSet.fromKeys = function(value) {
|
|
return this(KeyedIterable(value).keySeq());
|
|
};
|
|
|
|
OrderedSet.prototype.toString = function() {
|
|
return this.__toString('OrderedSet {', '}');
|
|
};
|
|
|
|
|
|
function isOrderedSet(maybeOrderedSet) {
|
|
return isSet(maybeOrderedSet) && isOrdered(maybeOrderedSet);
|
|
}
|
|
|
|
OrderedSet.isOrderedSet = isOrderedSet;
|
|
|
|
var OrderedSetPrototype = OrderedSet.prototype;
|
|
OrderedSetPrototype[IS_ORDERED_SENTINEL] = true;
|
|
|
|
OrderedSetPrototype.__empty = emptyOrderedSet;
|
|
OrderedSetPrototype.__make = makeOrderedSet;
|
|
|
|
function makeOrderedSet(map, ownerID) {
|
|
var set = Object.create(OrderedSetPrototype);
|
|
set.size = map ? map.size : 0;
|
|
set._map = map;
|
|
set.__ownerID = ownerID;
|
|
return set;
|
|
}
|
|
|
|
var EMPTY_ORDERED_SET;
|
|
function emptyOrderedSet() {
|
|
return EMPTY_ORDERED_SET || (EMPTY_ORDERED_SET = makeOrderedSet(emptyOrderedMap()));
|
|
}
|
|
|
|
createClass(Record, KeyedCollection);
|
|
|
|
function Record(defaultValues, name) {
|
|
var hasInitialized;
|
|
|
|
var RecordType = function Record(values) {
|
|
if (values instanceof RecordType) {
|
|
return values;
|
|
}
|
|
if (!(this instanceof RecordType)) {
|
|
return new RecordType(values);
|
|
}
|
|
if (!hasInitialized) {
|
|
hasInitialized = true;
|
|
var keys = Object.keys(defaultValues);
|
|
setProps(RecordTypePrototype, keys);
|
|
RecordTypePrototype.size = keys.length;
|
|
RecordTypePrototype._name = name;
|
|
RecordTypePrototype._keys = keys;
|
|
RecordTypePrototype._defaultValues = defaultValues;
|
|
}
|
|
this._map = src_Map__Map(values);
|
|
};
|
|
|
|
var RecordTypePrototype = RecordType.prototype = Object.create(RecordPrototype);
|
|
RecordTypePrototype.constructor = RecordType;
|
|
|
|
return RecordType;
|
|
}
|
|
|
|
Record.prototype.toString = function() {
|
|
return this.__toString(recordName(this) + ' {', '}');
|
|
};
|
|
|
|
// @pragma Access
|
|
|
|
Record.prototype.has = function(k) {
|
|
return this._defaultValues.hasOwnProperty(k);
|
|
};
|
|
|
|
Record.prototype.get = function(k, notSetValue) {
|
|
if (!this.has(k)) {
|
|
return notSetValue;
|
|
}
|
|
var defaultVal = this._defaultValues[k];
|
|
return this._map ? this._map.get(k, defaultVal) : defaultVal;
|
|
};
|
|
|
|
// @pragma Modification
|
|
|
|
Record.prototype.clear = function() {
|
|
if (this.__ownerID) {
|
|
this._map && this._map.clear();
|
|
return this;
|
|
}
|
|
var RecordType = this.constructor;
|
|
return RecordType._empty || (RecordType._empty = makeRecord(this, emptyMap()));
|
|
};
|
|
|
|
Record.prototype.set = function(k, v) {
|
|
if (!this.has(k)) {
|
|
throw new Error('Cannot set unknown key "' + k + '" on ' + recordName(this));
|
|
}
|
|
var newMap = this._map && this._map.set(k, v);
|
|
if (this.__ownerID || newMap === this._map) {
|
|
return this;
|
|
}
|
|
return makeRecord(this, newMap);
|
|
};
|
|
|
|
Record.prototype.remove = function(k) {
|
|
if (!this.has(k)) {
|
|
return this;
|
|
}
|
|
var newMap = this._map && this._map.remove(k);
|
|
if (this.__ownerID || newMap === this._map) {
|
|
return this;
|
|
}
|
|
return makeRecord(this, newMap);
|
|
};
|
|
|
|
Record.prototype.wasAltered = function() {
|
|
return this._map.wasAltered();
|
|
};
|
|
|
|
Record.prototype.__iterator = function(type, reverse) {var this$0 = this;
|
|
return KeyedIterable(this._defaultValues).map(function(_, k) {return this$0.get(k)}).__iterator(type, reverse);
|
|
};
|
|
|
|
Record.prototype.__iterate = function(fn, reverse) {var this$0 = this;
|
|
return KeyedIterable(this._defaultValues).map(function(_, k) {return this$0.get(k)}).__iterate(fn, reverse);
|
|
};
|
|
|
|
Record.prototype.__ensureOwner = function(ownerID) {
|
|
if (ownerID === this.__ownerID) {
|
|
return this;
|
|
}
|
|
var newMap = this._map && this._map.__ensureOwner(ownerID);
|
|
if (!ownerID) {
|
|
this.__ownerID = ownerID;
|
|
this._map = newMap;
|
|
return this;
|
|
}
|
|
return makeRecord(this, newMap, ownerID);
|
|
};
|
|
|
|
|
|
var RecordPrototype = Record.prototype;
|
|
RecordPrototype[DELETE] = RecordPrototype.remove;
|
|
RecordPrototype.deleteIn =
|
|
RecordPrototype.removeIn = MapPrototype.removeIn;
|
|
RecordPrototype.merge = MapPrototype.merge;
|
|
RecordPrototype.mergeWith = MapPrototype.mergeWith;
|
|
RecordPrototype.mergeIn = MapPrototype.mergeIn;
|
|
RecordPrototype.mergeDeep = MapPrototype.mergeDeep;
|
|
RecordPrototype.mergeDeepWith = MapPrototype.mergeDeepWith;
|
|
RecordPrototype.mergeDeepIn = MapPrototype.mergeDeepIn;
|
|
RecordPrototype.setIn = MapPrototype.setIn;
|
|
RecordPrototype.update = MapPrototype.update;
|
|
RecordPrototype.updateIn = MapPrototype.updateIn;
|
|
RecordPrototype.withMutations = MapPrototype.withMutations;
|
|
RecordPrototype.asMutable = MapPrototype.asMutable;
|
|
RecordPrototype.asImmutable = MapPrototype.asImmutable;
|
|
|
|
|
|
function makeRecord(likeRecord, map, ownerID) {
|
|
var record = Object.create(Object.getPrototypeOf(likeRecord));
|
|
record._map = map;
|
|
record.__ownerID = ownerID;
|
|
return record;
|
|
}
|
|
|
|
function recordName(record) {
|
|
return record._name || record.constructor.name || 'Record';
|
|
}
|
|
|
|
function setProps(prototype, names) {
|
|
try {
|
|
names.forEach(setProp.bind(undefined, prototype));
|
|
} catch (error) {
|
|
// Object.defineProperty failed. Probably IE8.
|
|
}
|
|
}
|
|
|
|
function setProp(prototype, name) {
|
|
Object.defineProperty(prototype, name, {
|
|
get: function() {
|
|
return this.get(name);
|
|
},
|
|
set: function(value) {
|
|
invariant(this.__ownerID, 'Cannot set on an immutable record.');
|
|
this.set(name, value);
|
|
}
|
|
});
|
|
}
|
|
|
|
function deepEqual(a, b) {
|
|
if (a === b) {
|
|
return true;
|
|
}
|
|
|
|
if (
|
|
!isIterable(b) ||
|
|
a.size !== undefined && b.size !== undefined && a.size !== b.size ||
|
|
a.__hash !== undefined && b.__hash !== undefined && a.__hash !== b.__hash ||
|
|
isKeyed(a) !== isKeyed(b) ||
|
|
isIndexed(a) !== isIndexed(b) ||
|
|
isOrdered(a) !== isOrdered(b)
|
|
) {
|
|
return false;
|
|
}
|
|
|
|
if (a.size === 0 && b.size === 0) {
|
|
return true;
|
|
}
|
|
|
|
var notAssociative = !isAssociative(a);
|
|
|
|
if (isOrdered(a)) {
|
|
var entries = a.entries();
|
|
return b.every(function(v, k) {
|
|
var entry = entries.next().value;
|
|
return entry && is(entry[1], v) && (notAssociative || is(entry[0], k));
|
|
}) && entries.next().done;
|
|
}
|
|
|
|
var flipped = false;
|
|
|
|
if (a.size === undefined) {
|
|
if (b.size === undefined) {
|
|
if (typeof a.cacheResult === 'function') {
|
|
a.cacheResult();
|
|
}
|
|
} else {
|
|
flipped = true;
|
|
var _ = a;
|
|
a = b;
|
|
b = _;
|
|
}
|
|
}
|
|
|
|
var allEqual = true;
|
|
var bSize = b.__iterate(function(v, k) {
|
|
if (notAssociative ? !a.has(v) :
|
|
flipped ? !is(v, a.get(k, NOT_SET)) : !is(a.get(k, NOT_SET), v)) {
|
|
allEqual = false;
|
|
return false;
|
|
}
|
|
});
|
|
|
|
return allEqual && a.size === bSize;
|
|
}
|
|
|
|
createClass(Range, IndexedSeq);
|
|
|
|
function Range(start, end, step) {
|
|
if (!(this instanceof Range)) {
|
|
return new Range(start, end, step);
|
|
}
|
|
invariant(step !== 0, 'Cannot step a Range by 0');
|
|
start = start || 0;
|
|
if (end === undefined) {
|
|
end = Infinity;
|
|
}
|
|
step = step === undefined ? 1 : Math.abs(step);
|
|
if (end < start) {
|
|
step = -step;
|
|
}
|
|
this._start = start;
|
|
this._end = end;
|
|
this._step = step;
|
|
this.size = Math.max(0, Math.ceil((end - start) / step - 1) + 1);
|
|
if (this.size === 0) {
|
|
if (EMPTY_RANGE) {
|
|
return EMPTY_RANGE;
|
|
}
|
|
EMPTY_RANGE = this;
|
|
}
|
|
}
|
|
|
|
Range.prototype.toString = function() {
|
|
if (this.size === 0) {
|
|
return 'Range []';
|
|
}
|
|
return 'Range [ ' +
|
|
this._start + '...' + this._end +
|
|
(this._step > 1 ? ' by ' + this._step : '') +
|
|
' ]';
|
|
};
|
|
|
|
Range.prototype.get = function(index, notSetValue) {
|
|
return this.has(index) ?
|
|
this._start + wrapIndex(this, index) * this._step :
|
|
notSetValue;
|
|
};
|
|
|
|
Range.prototype.includes = function(searchValue) {
|
|
var possibleIndex = (searchValue - this._start) / this._step;
|
|
return possibleIndex >= 0 &&
|
|
possibleIndex < this.size &&
|
|
possibleIndex === Math.floor(possibleIndex);
|
|
};
|
|
|
|
Range.prototype.slice = function(begin, end) {
|
|
if (wholeSlice(begin, end, this.size)) {
|
|
return this;
|
|
}
|
|
begin = resolveBegin(begin, this.size);
|
|
end = resolveEnd(end, this.size);
|
|
if (end <= begin) {
|
|
return new Range(0, 0);
|
|
}
|
|
return new Range(this.get(begin, this._end), this.get(end, this._end), this._step);
|
|
};
|
|
|
|
Range.prototype.indexOf = function(searchValue) {
|
|
var offsetValue = searchValue - this._start;
|
|
if (offsetValue % this._step === 0) {
|
|
var index = offsetValue / this._step;
|
|
if (index >= 0 && index < this.size) {
|
|
return index
|
|
}
|
|
}
|
|
return -1;
|
|
};
|
|
|
|
Range.prototype.lastIndexOf = function(searchValue) {
|
|
return this.indexOf(searchValue);
|
|
};
|
|
|
|
Range.prototype.__iterate = function(fn, reverse) {
|
|
var maxIndex = this.size - 1;
|
|
var step = this._step;
|
|
var value = reverse ? this._start + maxIndex * step : this._start;
|
|
for (var ii = 0; ii <= maxIndex; ii++) {
|
|
if (fn(value, ii, this) === false) {
|
|
return ii + 1;
|
|
}
|
|
value += reverse ? -step : step;
|
|
}
|
|
return ii;
|
|
};
|
|
|
|
Range.prototype.__iterator = function(type, reverse) {
|
|
var maxIndex = this.size - 1;
|
|
var step = this._step;
|
|
var value = reverse ? this._start + maxIndex * step : this._start;
|
|
var ii = 0;
|
|
return new src_Iterator__Iterator(function() {
|
|
var v = value;
|
|
value += reverse ? -step : step;
|
|
return ii > maxIndex ? iteratorDone() : iteratorValue(type, ii++, v);
|
|
});
|
|
};
|
|
|
|
Range.prototype.equals = function(other) {
|
|
return other instanceof Range ?
|
|
this._start === other._start &&
|
|
this._end === other._end &&
|
|
this._step === other._step :
|
|
deepEqual(this, other);
|
|
};
|
|
|
|
|
|
var EMPTY_RANGE;
|
|
|
|
createClass(Repeat, IndexedSeq);
|
|
|
|
function Repeat(value, times) {
|
|
if (!(this instanceof Repeat)) {
|
|
return new Repeat(value, times);
|
|
}
|
|
this._value = value;
|
|
this.size = times === undefined ? Infinity : Math.max(0, times);
|
|
if (this.size === 0) {
|
|
if (EMPTY_REPEAT) {
|
|
return EMPTY_REPEAT;
|
|
}
|
|
EMPTY_REPEAT = this;
|
|
}
|
|
}
|
|
|
|
Repeat.prototype.toString = function() {
|
|
if (this.size === 0) {
|
|
return 'Repeat []';
|
|
}
|
|
return 'Repeat [ ' + this._value + ' ' + this.size + ' times ]';
|
|
};
|
|
|
|
Repeat.prototype.get = function(index, notSetValue) {
|
|
return this.has(index) ? this._value : notSetValue;
|
|
};
|
|
|
|
Repeat.prototype.includes = function(searchValue) {
|
|
return is(this._value, searchValue);
|
|
};
|
|
|
|
Repeat.prototype.slice = function(begin, end) {
|
|
var size = this.size;
|
|
return wholeSlice(begin, end, size) ? this :
|
|
new Repeat(this._value, resolveEnd(end, size) - resolveBegin(begin, size));
|
|
};
|
|
|
|
Repeat.prototype.reverse = function() {
|
|
return this;
|
|
};
|
|
|
|
Repeat.prototype.indexOf = function(searchValue) {
|
|
if (is(this._value, searchValue)) {
|
|
return 0;
|
|
}
|
|
return -1;
|
|
};
|
|
|
|
Repeat.prototype.lastIndexOf = function(searchValue) {
|
|
if (is(this._value, searchValue)) {
|
|
return this.size;
|
|
}
|
|
return -1;
|
|
};
|
|
|
|
Repeat.prototype.__iterate = function(fn, reverse) {
|
|
for (var ii = 0; ii < this.size; ii++) {
|
|
if (fn(this._value, ii, this) === false) {
|
|
return ii + 1;
|
|
}
|
|
}
|
|
return ii;
|
|
};
|
|
|
|
Repeat.prototype.__iterator = function(type, reverse) {var this$0 = this;
|
|
var ii = 0;
|
|
return new src_Iterator__Iterator(function()
|
|
{return ii < this$0.size ? iteratorValue(type, ii++, this$0._value) : iteratorDone()}
|
|
);
|
|
};
|
|
|
|
Repeat.prototype.equals = function(other) {
|
|
return other instanceof Repeat ?
|
|
is(this._value, other._value) :
|
|
deepEqual(other);
|
|
};
|
|
|
|
|
|
var EMPTY_REPEAT;
|
|
|
|
/**
|
|
* Contributes additional methods to a constructor
|
|
*/
|
|
function mixin(ctor, methods) {
|
|
var keyCopier = function(key ) { ctor.prototype[key] = methods[key]; };
|
|
Object.keys(methods).forEach(keyCopier);
|
|
Object.getOwnPropertySymbols &&
|
|
Object.getOwnPropertySymbols(methods).forEach(keyCopier);
|
|
return ctor;
|
|
}
|
|
|
|
Iterable.Iterator = src_Iterator__Iterator;
|
|
|
|
mixin(Iterable, {
|
|
|
|
// ### Conversion to other types
|
|
|
|
toArray: function() {
|
|
assertNotInfinite(this.size);
|
|
var array = new Array(this.size || 0);
|
|
this.valueSeq().__iterate(function(v, i) { array[i] = v; });
|
|
return array;
|
|
},
|
|
|
|
toIndexedSeq: function() {
|
|
return new ToIndexedSequence(this);
|
|
},
|
|
|
|
toJS: function() {
|
|
return this.toSeq().map(
|
|
function(value ) {return value && typeof value.toJS === 'function' ? value.toJS() : value}
|
|
).__toJS();
|
|
},
|
|
|
|
toJSON: function() {
|
|
return this.toSeq().map(
|
|
function(value ) {return value && typeof value.toJSON === 'function' ? value.toJSON() : value}
|
|
).__toJS();
|
|
},
|
|
|
|
toKeyedSeq: function() {
|
|
return new ToKeyedSequence(this, true);
|
|
},
|
|
|
|
toMap: function() {
|
|
// Use Late Binding here to solve the circular dependency.
|
|
return src_Map__Map(this.toKeyedSeq());
|
|
},
|
|
|
|
toObject: function() {
|
|
assertNotInfinite(this.size);
|
|
var object = {};
|
|
this.__iterate(function(v, k) { object[k] = v; });
|
|
return object;
|
|
},
|
|
|
|
toOrderedMap: function() {
|
|
// Use Late Binding here to solve the circular dependency.
|
|
return OrderedMap(this.toKeyedSeq());
|
|
},
|
|
|
|
toOrderedSet: function() {
|
|
// Use Late Binding here to solve the circular dependency.
|
|
return OrderedSet(isKeyed(this) ? this.valueSeq() : this);
|
|
},
|
|
|
|
toSet: function() {
|
|
// Use Late Binding here to solve the circular dependency.
|
|
return src_Set__Set(isKeyed(this) ? this.valueSeq() : this);
|
|
},
|
|
|
|
toSetSeq: function() {
|
|
return new ToSetSequence(this);
|
|
},
|
|
|
|
toSeq: function() {
|
|
return isIndexed(this) ? this.toIndexedSeq() :
|
|
isKeyed(this) ? this.toKeyedSeq() :
|
|
this.toSetSeq();
|
|
},
|
|
|
|
toStack: function() {
|
|
// Use Late Binding here to solve the circular dependency.
|
|
return Stack(isKeyed(this) ? this.valueSeq() : this);
|
|
},
|
|
|
|
toList: function() {
|
|
// Use Late Binding here to solve the circular dependency.
|
|
return List(isKeyed(this) ? this.valueSeq() : this);
|
|
},
|
|
|
|
|
|
// ### Common JavaScript methods and properties
|
|
|
|
toString: function() {
|
|
return '[Iterable]';
|
|
},
|
|
|
|
__toString: function(head, tail) {
|
|
if (this.size === 0) {
|
|
return head + tail;
|
|
}
|
|
return head + ' ' + this.toSeq().map(this.__toStringMapper).join(', ') + ' ' + tail;
|
|
},
|
|
|
|
|
|
// ### ES6 Collection methods (ES6 Array and Map)
|
|
|
|
concat: function() {var values = SLICE$0.call(arguments, 0);
|
|
return reify(this, concatFactory(this, values));
|
|
},
|
|
|
|
contains: function(searchValue) {
|
|
return this.includes(searchValue);
|
|
},
|
|
|
|
includes: function(searchValue) {
|
|
return this.some(function(value ) {return is(value, searchValue)});
|
|
},
|
|
|
|
entries: function() {
|
|
return this.__iterator(ITERATE_ENTRIES);
|
|
},
|
|
|
|
every: function(predicate, context) {
|
|
assertNotInfinite(this.size);
|
|
var returnValue = true;
|
|
this.__iterate(function(v, k, c) {
|
|
if (!predicate.call(context, v, k, c)) {
|
|
returnValue = false;
|
|
return false;
|
|
}
|
|
});
|
|
return returnValue;
|
|
},
|
|
|
|
filter: function(predicate, context) {
|
|
return reify(this, filterFactory(this, predicate, context, true));
|
|
},
|
|
|
|
find: function(predicate, context, notSetValue) {
|
|
var entry = this.findEntry(predicate, context);
|
|
return entry ? entry[1] : notSetValue;
|
|
},
|
|
|
|
findEntry: function(predicate, context) {
|
|
var found;
|
|
this.__iterate(function(v, k, c) {
|
|
if (predicate.call(context, v, k, c)) {
|
|
found = [k, v];
|
|
return false;
|
|
}
|
|
});
|
|
return found;
|
|
},
|
|
|
|
findLastEntry: function(predicate, context) {
|
|
return this.toSeq().reverse().findEntry(predicate, context);
|
|
},
|
|
|
|
forEach: function(sideEffect, context) {
|
|
assertNotInfinite(this.size);
|
|
return this.__iterate(context ? sideEffect.bind(context) : sideEffect);
|
|
},
|
|
|
|
join: function(separator) {
|
|
assertNotInfinite(this.size);
|
|
separator = separator !== undefined ? '' + separator : ',';
|
|
var joined = '';
|
|
var isFirst = true;
|
|
this.__iterate(function(v ) {
|
|
isFirst ? (isFirst = false) : (joined += separator);
|
|
joined += v !== null && v !== undefined ? v.toString() : '';
|
|
});
|
|
return joined;
|
|
},
|
|
|
|
keys: function() {
|
|
return this.__iterator(ITERATE_KEYS);
|
|
},
|
|
|
|
map: function(mapper, context) {
|
|
return reify(this, mapFactory(this, mapper, context));
|
|
},
|
|
|
|
reduce: function(reducer, initialReduction, context) {
|
|
assertNotInfinite(this.size);
|
|
var reduction;
|
|
var useFirst;
|
|
if (arguments.length < 2) {
|
|
useFirst = true;
|
|
} else {
|
|
reduction = initialReduction;
|
|
}
|
|
this.__iterate(function(v, k, c) {
|
|
if (useFirst) {
|
|
useFirst = false;
|
|
reduction = v;
|
|
} else {
|
|
reduction = reducer.call(context, reduction, v, k, c);
|
|
}
|
|
});
|
|
return reduction;
|
|
},
|
|
|
|
reduceRight: function(reducer, initialReduction, context) {
|
|
var reversed = this.toKeyedSeq().reverse();
|
|
return reversed.reduce.apply(reversed, arguments);
|
|
},
|
|
|
|
reverse: function() {
|
|
return reify(this, reverseFactory(this, true));
|
|
},
|
|
|
|
slice: function(begin, end) {
|
|
return reify(this, sliceFactory(this, begin, end, true));
|
|
},
|
|
|
|
some: function(predicate, context) {
|
|
return !this.every(not(predicate), context);
|
|
},
|
|
|
|
sort: function(comparator) {
|
|
return reify(this, sortFactory(this, comparator));
|
|
},
|
|
|
|
values: function() {
|
|
return this.__iterator(ITERATE_VALUES);
|
|
},
|
|
|
|
|
|
// ### More sequential methods
|
|
|
|
butLast: function() {
|
|
return this.slice(0, -1);
|
|
},
|
|
|
|
isEmpty: function() {
|
|
return this.size !== undefined ? this.size === 0 : !this.some(function() {return true});
|
|
},
|
|
|
|
count: function(predicate, context) {
|
|
return ensureSize(
|
|
predicate ? this.toSeq().filter(predicate, context) : this
|
|
);
|
|
},
|
|
|
|
countBy: function(grouper, context) {
|
|
return countByFactory(this, grouper, context);
|
|
},
|
|
|
|
equals: function(other) {
|
|
return deepEqual(this, other);
|
|
},
|
|
|
|
entrySeq: function() {
|
|
var iterable = this;
|
|
if (iterable._cache) {
|
|
// We cache as an entries array, so we can just return the cache!
|
|
return new ArraySeq(iterable._cache);
|
|
}
|
|
var entriesSequence = iterable.toSeq().map(entryMapper).toIndexedSeq();
|
|
entriesSequence.fromEntrySeq = function() {return iterable.toSeq()};
|
|
return entriesSequence;
|
|
},
|
|
|
|
filterNot: function(predicate, context) {
|
|
return this.filter(not(predicate), context);
|
|
},
|
|
|
|
findLast: function(predicate, context, notSetValue) {
|
|
return this.toKeyedSeq().reverse().find(predicate, context, notSetValue);
|
|
},
|
|
|
|
first: function() {
|
|
return this.find(returnTrue);
|
|
},
|
|
|
|
flatMap: function(mapper, context) {
|
|
return reify(this, flatMapFactory(this, mapper, context));
|
|
},
|
|
|
|
flatten: function(depth) {
|
|
return reify(this, flattenFactory(this, depth, true));
|
|
},
|
|
|
|
fromEntrySeq: function() {
|
|
return new FromEntriesSequence(this);
|
|
},
|
|
|
|
get: function(searchKey, notSetValue) {
|
|
return this.find(function(_, key) {return is(key, searchKey)}, undefined, notSetValue);
|
|
},
|
|
|
|
getIn: function(searchKeyPath, notSetValue) {
|
|
var nested = this;
|
|
// Note: in an ES6 environment, we would prefer:
|
|
// for (var key of searchKeyPath) {
|
|
var iter = forceIterator(searchKeyPath);
|
|
var step;
|
|
while (!(step = iter.next()).done) {
|
|
var key = step.value;
|
|
nested = nested && nested.get ? nested.get(key, NOT_SET) : NOT_SET;
|
|
if (nested === NOT_SET) {
|
|
return notSetValue;
|
|
}
|
|
}
|
|
return nested;
|
|
},
|
|
|
|
groupBy: function(grouper, context) {
|
|
return groupByFactory(this, grouper, context);
|
|
},
|
|
|
|
has: function(searchKey) {
|
|
return this.get(searchKey, NOT_SET) !== NOT_SET;
|
|
},
|
|
|
|
hasIn: function(searchKeyPath) {
|
|
return this.getIn(searchKeyPath, NOT_SET) !== NOT_SET;
|
|
},
|
|
|
|
isSubset: function(iter) {
|
|
iter = typeof iter.includes === 'function' ? iter : Iterable(iter);
|
|
return this.every(function(value ) {return iter.includes(value)});
|
|
},
|
|
|
|
isSuperset: function(iter) {
|
|
iter = typeof iter.isSubset === 'function' ? iter : Iterable(iter);
|
|
return iter.isSubset(this);
|
|
},
|
|
|
|
keySeq: function() {
|
|
return this.toSeq().map(keyMapper).toIndexedSeq();
|
|
},
|
|
|
|
last: function() {
|
|
return this.toSeq().reverse().first();
|
|
},
|
|
|
|
max: function(comparator) {
|
|
return maxFactory(this, comparator);
|
|
},
|
|
|
|
maxBy: function(mapper, comparator) {
|
|
return maxFactory(this, comparator, mapper);
|
|
},
|
|
|
|
min: function(comparator) {
|
|
return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator);
|
|
},
|
|
|
|
minBy: function(mapper, comparator) {
|
|
return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator, mapper);
|
|
},
|
|
|
|
rest: function() {
|
|
return this.slice(1);
|
|
},
|
|
|
|
skip: function(amount) {
|
|
return this.slice(Math.max(0, amount));
|
|
},
|
|
|
|
skipLast: function(amount) {
|
|
return reify(this, this.toSeq().reverse().skip(amount).reverse());
|
|
},
|
|
|
|
skipWhile: function(predicate, context) {
|
|
return reify(this, skipWhileFactory(this, predicate, context, true));
|
|
},
|
|
|
|
skipUntil: function(predicate, context) {
|
|
return this.skipWhile(not(predicate), context);
|
|
},
|
|
|
|
sortBy: function(mapper, comparator) {
|
|
return reify(this, sortFactory(this, comparator, mapper));
|
|
},
|
|
|
|
take: function(amount) {
|
|
return this.slice(0, Math.max(0, amount));
|
|
},
|
|
|
|
takeLast: function(amount) {
|
|
return reify(this, this.toSeq().reverse().take(amount).reverse());
|
|
},
|
|
|
|
takeWhile: function(predicate, context) {
|
|
return reify(this, takeWhileFactory(this, predicate, context));
|
|
},
|
|
|
|
takeUntil: function(predicate, context) {
|
|
return this.takeWhile(not(predicate), context);
|
|
},
|
|
|
|
valueSeq: function() {
|
|
return this.toIndexedSeq();
|
|
},
|
|
|
|
|
|
// ### Hashable Object
|
|
|
|
hashCode: function() {
|
|
return this.__hash || (this.__hash = hashIterable(this));
|
|
},
|
|
|
|
|
|
// ### Internal
|
|
|
|
// abstract __iterate(fn, reverse)
|
|
|
|
// abstract __iterator(type, reverse)
|
|
});
|
|
|
|
// var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@';
|
|
// var IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@';
|
|
// var IS_INDEXED_SENTINEL = '@@__IMMUTABLE_INDEXED__@@';
|
|
// var IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@';
|
|
|
|
var IterablePrototype = Iterable.prototype;
|
|
IterablePrototype[IS_ITERABLE_SENTINEL] = true;
|
|
IterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.values;
|
|
IterablePrototype.__toJS = IterablePrototype.toArray;
|
|
IterablePrototype.__toStringMapper = quoteString;
|
|
IterablePrototype.inspect =
|
|
IterablePrototype.toSource = function() { return this.toString(); };
|
|
IterablePrototype.chain = IterablePrototype.flatMap;
|
|
|
|
// Temporary warning about using length
|
|
(function () {
|
|
try {
|
|
Object.defineProperty(IterablePrototype, 'length', {
|
|
get: function () {
|
|
if (!Iterable.noLengthWarning) {
|
|
var stack;
|
|
try {
|
|
throw new Error();
|
|
} catch (error) {
|
|
stack = error.stack;
|
|
}
|
|
if (stack.indexOf('_wrapObject') === -1) {
|
|
console && console.warn && console.warn(
|
|
'iterable.length has been deprecated, '+
|
|
'use iterable.size or iterable.count(). '+
|
|
'This warning will become a silent error in a future version. ' +
|
|
stack
|
|
);
|
|
return this.size;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
} catch (e) {}
|
|
})();
|
|
|
|
|
|
|
|
mixin(KeyedIterable, {
|
|
|
|
// ### More sequential methods
|
|
|
|
flip: function() {
|
|
return reify(this, flipFactory(this));
|
|
},
|
|
|
|
findKey: function(predicate, context) {
|
|
var entry = this.findEntry(predicate, context);
|
|
return entry && entry[0];
|
|
},
|
|
|
|
findLastKey: function(predicate, context) {
|
|
return this.toSeq().reverse().findKey(predicate, context);
|
|
},
|
|
|
|
keyOf: function(searchValue) {
|
|
return this.findKey(function(value ) {return is(value, searchValue)});
|
|
},
|
|
|
|
lastKeyOf: function(searchValue) {
|
|
return this.findLastKey(function(value ) {return is(value, searchValue)});
|
|
},
|
|
|
|
mapEntries: function(mapper, context) {var this$0 = this;
|
|
var iterations = 0;
|
|
return reify(this,
|
|
this.toSeq().map(
|
|
function(v, k) {return mapper.call(context, [k, v], iterations++, this$0)}
|
|
).fromEntrySeq()
|
|
);
|
|
},
|
|
|
|
mapKeys: function(mapper, context) {var this$0 = this;
|
|
return reify(this,
|
|
this.toSeq().flip().map(
|
|
function(k, v) {return mapper.call(context, k, v, this$0)}
|
|
).flip()
|
|
);
|
|
},
|
|
|
|
});
|
|
|
|
var KeyedIterablePrototype = KeyedIterable.prototype;
|
|
KeyedIterablePrototype[IS_KEYED_SENTINEL] = true;
|
|
KeyedIterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.entries;
|
|
KeyedIterablePrototype.__toJS = IterablePrototype.toObject;
|
|
KeyedIterablePrototype.__toStringMapper = function(v, k) {return JSON.stringify(k) + ': ' + quoteString(v)};
|
|
|
|
|
|
|
|
mixin(IndexedIterable, {
|
|
|
|
// ### Conversion to other types
|
|
|
|
toKeyedSeq: function() {
|
|
return new ToKeyedSequence(this, false);
|
|
},
|
|
|
|
|
|
// ### ES6 Collection methods (ES6 Array and Map)
|
|
|
|
filter: function(predicate, context) {
|
|
return reify(this, filterFactory(this, predicate, context, false));
|
|
},
|
|
|
|
findIndex: function(predicate, context) {
|
|
var entry = this.findEntry(predicate, context);
|
|
return entry ? entry[0] : -1;
|
|
},
|
|
|
|
indexOf: function(searchValue) {
|
|
var key = this.toKeyedSeq().keyOf(searchValue);
|
|
return key === undefined ? -1 : key;
|
|
},
|
|
|
|
lastIndexOf: function(searchValue) {
|
|
return this.toSeq().reverse().indexOf(searchValue);
|
|
},
|
|
|
|
reverse: function() {
|
|
return reify(this, reverseFactory(this, false));
|
|
},
|
|
|
|
slice: function(begin, end) {
|
|
return reify(this, sliceFactory(this, begin, end, false));
|
|
},
|
|
|
|
splice: function(index, removeNum /*, ...values*/) {
|
|
var numArgs = arguments.length;
|
|
removeNum = Math.max(removeNum | 0, 0);
|
|
if (numArgs === 0 || (numArgs === 2 && !removeNum)) {
|
|
return this;
|
|
}
|
|
index = resolveBegin(index, this.size);
|
|
var spliced = this.slice(0, index);
|
|
return reify(
|
|
this,
|
|
numArgs === 1 ?
|
|
spliced :
|
|
spliced.concat(arrCopy(arguments, 2), this.slice(index + removeNum))
|
|
);
|
|
},
|
|
|
|
|
|
// ### More collection methods
|
|
|
|
findLastIndex: function(predicate, context) {
|
|
var key = this.toKeyedSeq().findLastKey(predicate, context);
|
|
return key === undefined ? -1 : key;
|
|
},
|
|
|
|
first: function() {
|
|
return this.get(0);
|
|
},
|
|
|
|
flatten: function(depth) {
|
|
return reify(this, flattenFactory(this, depth, false));
|
|
},
|
|
|
|
get: function(index, notSetValue) {
|
|
index = wrapIndex(this, index);
|
|
return (index < 0 || (this.size === Infinity ||
|
|
(this.size !== undefined && index > this.size))) ?
|
|
notSetValue :
|
|
this.find(function(_, key) {return key === index}, undefined, notSetValue);
|
|
},
|
|
|
|
has: function(index) {
|
|
index = wrapIndex(this, index);
|
|
return index >= 0 && (this.size !== undefined ?
|
|
this.size === Infinity || index < this.size :
|
|
this.indexOf(index) !== -1
|
|
);
|
|
},
|
|
|
|
interpose: function(separator) {
|
|
return reify(this, interposeFactory(this, separator));
|
|
},
|
|
|
|
interleave: function(/*...iterables*/) {
|
|
var iterables = [this].concat(arrCopy(arguments));
|
|
var zipped = zipWithFactory(this.toSeq(), IndexedSeq.of, iterables);
|
|
var interleaved = zipped.flatten(true);
|
|
if (zipped.size) {
|
|
interleaved.size = zipped.size * iterables.length;
|
|
}
|
|
return reify(this, interleaved);
|
|
},
|
|
|
|
last: function() {
|
|
return this.get(-1);
|
|
},
|
|
|
|
skipWhile: function(predicate, context) {
|
|
return reify(this, skipWhileFactory(this, predicate, context, false));
|
|
},
|
|
|
|
zip: function(/*, ...iterables */) {
|
|
var iterables = [this].concat(arrCopy(arguments));
|
|
return reify(this, zipWithFactory(this, defaultZipper, iterables));
|
|
},
|
|
|
|
zipWith: function(zipper/*, ...iterables */) {
|
|
var iterables = arrCopy(arguments);
|
|
iterables[0] = this;
|
|
return reify(this, zipWithFactory(this, zipper, iterables));
|
|
},
|
|
|
|
});
|
|
|
|
IndexedIterable.prototype[IS_INDEXED_SENTINEL] = true;
|
|
IndexedIterable.prototype[IS_ORDERED_SENTINEL] = true;
|
|
|
|
|
|
|
|
mixin(SetIterable, {
|
|
|
|
// ### ES6 Collection methods (ES6 Array and Map)
|
|
|
|
get: function(value, notSetValue) {
|
|
return this.has(value) ? value : notSetValue;
|
|
},
|
|
|
|
includes: function(value) {
|
|
return this.has(value);
|
|
},
|
|
|
|
|
|
// ### More sequential methods
|
|
|
|
keySeq: function() {
|
|
return this.valueSeq();
|
|
},
|
|
|
|
});
|
|
|
|
SetIterable.prototype.has = IterablePrototype.includes;
|
|
|
|
|
|
// Mixin subclasses
|
|
|
|
mixin(KeyedSeq, KeyedIterable.prototype);
|
|
mixin(IndexedSeq, IndexedIterable.prototype);
|
|
mixin(SetSeq, SetIterable.prototype);
|
|
|
|
mixin(KeyedCollection, KeyedIterable.prototype);
|
|
mixin(IndexedCollection, IndexedIterable.prototype);
|
|
mixin(SetCollection, SetIterable.prototype);
|
|
|
|
|
|
// #pragma Helper functions
|
|
|
|
function keyMapper(v, k) {
|
|
return k;
|
|
}
|
|
|
|
function entryMapper(v, k) {
|
|
return [k, v];
|
|
}
|
|
|
|
function not(predicate) {
|
|
return function() {
|
|
return !predicate.apply(this, arguments);
|
|
}
|
|
}
|
|
|
|
function neg(predicate) {
|
|
return function() {
|
|
return -predicate.apply(this, arguments);
|
|
}
|
|
}
|
|
|
|
function quoteString(value) {
|
|
return typeof value === 'string' ? JSON.stringify(value) : value;
|
|
}
|
|
|
|
function defaultZipper() {
|
|
return arrCopy(arguments);
|
|
}
|
|
|
|
function defaultNegComparator(a, b) {
|
|
return a < b ? 1 : a > b ? -1 : 0;
|
|
}
|
|
|
|
function hashIterable(iterable) {
|
|
if (iterable.size === Infinity) {
|
|
return 0;
|
|
}
|
|
var ordered = isOrdered(iterable);
|
|
var keyed = isKeyed(iterable);
|
|
var h = ordered ? 1 : 0;
|
|
var size = iterable.__iterate(
|
|
keyed ?
|
|
ordered ?
|
|
function(v, k) { h = 31 * h + hashMerge(hash(v), hash(k)) | 0; } :
|
|
function(v, k) { h = h + hashMerge(hash(v), hash(k)) | 0; } :
|
|
ordered ?
|
|
function(v ) { h = 31 * h + hash(v) | 0; } :
|
|
function(v ) { h = h + hash(v) | 0; }
|
|
);
|
|
return murmurHashOfSize(size, h);
|
|
}
|
|
|
|
function murmurHashOfSize(size, h) {
|
|
h = src_Math__imul(h, 0xCC9E2D51);
|
|
h = src_Math__imul(h << 15 | h >>> -15, 0x1B873593);
|
|
h = src_Math__imul(h << 13 | h >>> -13, 5);
|
|
h = (h + 0xE6546B64 | 0) ^ size;
|
|
h = src_Math__imul(h ^ h >>> 16, 0x85EBCA6B);
|
|
h = src_Math__imul(h ^ h >>> 13, 0xC2B2AE35);
|
|
h = smi(h ^ h >>> 16);
|
|
return h;
|
|
}
|
|
|
|
function hashMerge(a, b) {
|
|
return a ^ b + 0x9E3779B9 + (a << 6) + (a >> 2) | 0; // int
|
|
}
|
|
|
|
var Immutable = {
|
|
|
|
Iterable: Iterable,
|
|
|
|
Seq: Seq,
|
|
Collection: Collection,
|
|
Map: src_Map__Map,
|
|
OrderedMap: OrderedMap,
|
|
List: List,
|
|
Stack: Stack,
|
|
Set: src_Set__Set,
|
|
OrderedSet: OrderedSet,
|
|
|
|
Record: Record,
|
|
Range: Range,
|
|
Repeat: Repeat,
|
|
|
|
is: is,
|
|
fromJS: fromJS,
|
|
|
|
};
|
|
|
|
return Immutable;
|
|
|
|
}));
|
|
},{}],"store":[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
exports.bind = bind;
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _redux = require('redux');
|
|
|
|
var _reducersAll = require('reducers/all');
|
|
|
|
var _reducersAll2 = _interopRequireDefault(_reducersAll);
|
|
|
|
var _actionsChangedir = require('actions/changedir');
|
|
|
|
var _actionsChangedir2 = _interopRequireDefault(_actionsChangedir);
|
|
|
|
var _immutable = require('immutable');
|
|
|
|
var _immutable2 = _interopRequireDefault(_immutable);
|
|
|
|
var _menus = require('./menus');
|
|
|
|
var _menus2 = _interopRequireDefault(_menus);
|
|
|
|
var _dialogs = require('./dialogs');
|
|
|
|
var _dialogs2 = _interopRequireDefault(_dialogs);
|
|
|
|
var DEFAULT = new _immutable2['default'].Map(Object.assign({
|
|
dir: ''
|
|
}, _dialogs2['default'], _menus2['default']));
|
|
|
|
var store = (0, _redux.createStore)(_reducersAll2['default'], DEFAULT);
|
|
store.dispatch((0, _actionsChangedir2['default'])(DEFAULT.get('dir')));
|
|
|
|
function bind(action) {
|
|
return function () {
|
|
return store.dispatch(action);
|
|
};
|
|
}
|
|
|
|
exports['default'] = store;
|
|
|
|
},{"./dialogs":235,"./menus":237,"actions/changedir":215,"immutable":247,"reducers/all":239,"redux":207}],"utils":[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
exports.type = type;
|
|
exports.template = template;
|
|
exports.getKey = getKey;
|
|
exports.reportError = reportError;
|
|
exports.humanSize = humanSize;
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var _store = require('store');
|
|
|
|
var _store2 = _interopRequireDefault(_store);
|
|
|
|
var _actionsDialog = require('actions/dialog');
|
|
|
|
function type(obj) {
|
|
return Object.prototype.toString.call(obj).slice(8, -1);
|
|
}
|
|
|
|
function template(string, props) {
|
|
return string.replace(/@(\S+)/g, function (all, match) {
|
|
return getKey(props, match);
|
|
});
|
|
}
|
|
|
|
function getKey(object, key) {
|
|
if (object === undefined) object = _store2['default'].getState().toJS();
|
|
|
|
var parent = object;
|
|
|
|
do {
|
|
var dot = key.indexOf('.');
|
|
if (dot === -1) dot = key.length;
|
|
parent = parent[key.slice(0, dot)];
|
|
|
|
key = key.slice(dot + 1);
|
|
} while (key);
|
|
|
|
return parent;
|
|
}
|
|
|
|
function reportError(err) {
|
|
var action = (0, _actionsDialog.show)('errorDialog', { description: err.message });
|
|
_store2['default'].dispatch(action);
|
|
}
|
|
|
|
var sizes = {
|
|
'GB': Math.pow(2, 30),
|
|
'MB': Math.pow(2, 20),
|
|
'KB': Math.pow(2, 10),
|
|
'B': -1
|
|
};
|
|
|
|
function humanSize(size) {
|
|
console.log(size);
|
|
for (var key in sizes) {
|
|
var value = sizes[key];
|
|
|
|
console.log(value);
|
|
if (size > value) {
|
|
return Math.round(size / value) + key;
|
|
}
|
|
}
|
|
}
|
|
|
|
},{"actions/dialog":216,"store":"store"}]},{},[215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,"store","utils"]);
|