Skip to content

Instantly share code, notes, and snippets.

@brentvatne
Created May 14, 2015 02:52
Show Gist options
  • Save brentvatne/8b67dba34b05da9ac973 to your computer and use it in GitHub Desktop.
Save brentvatne/8b67dba34b05da9ac973 to your computer and use it in GitHub Desktop.
This file has been truncated, but you can view the full file.
/* eslint global-strict:0 */
__DEV__ = false;
/* eslint global-strict:0,eqeqeq:0,no-bitwise:0,no-undef:0 */
(function(global) {
// avoid redefining require()
if (global.require) {
return;
}
var __DEV__ = global.__DEV__;
var toString = Object.prototype.toString;
/**
* module index: {
* mod1: {
* exports: { ... },
* id: 'mod1',
* dependencies: ['mod1', 'mod2'],
* factory: function() { ... },
* waitingMap: { mod1: 1, mod3: 1, mod4: 1 },
* waiting: 2
* }
* }
*/
var modulesMap = {},
/**
* inverse index: {
* mod1: [modules, waiting for mod1],
* mod2: [modules, waiting for mod2]
* }
*/
dependencyMap = {},
/**
* modules whose reference counts are set out of order
*/
predefinedRefCounts = {},
_counter = 0,
REQUIRE_WHEN_READY = 1,
USED_AS_TRANSPORT = 2,
hop = Object.prototype.hasOwnProperty;
function _debugUnresolvedDependencies(names) {
var unresolved = Array.prototype.slice.call(names);
var visited = {};
var ii, name, module, dependency;
while (unresolved.length) {
name = unresolved.shift();
if (visited[name]) {
continue;
}
visited[name] = true;
module = modulesMap[name];
if (!module || !module.waiting) {
continue;
}
for (ii = 0; ii < module.dependencies.length; ii++) {
dependency = module.dependencies[ii];
if (!modulesMap[dependency] || modulesMap[dependency].waiting) {
unresolved.push(dependency);
}
}
}
for (name in visited) if (hop.call(visited, name)) {
unresolved.push(name);
}
var messages = [];
for (ii = 0; ii < unresolved.length; ii++) {
name = unresolved[ii];
var message = name;
module = modulesMap[name];
if (!module) {
message += ' is not defined';
} else if (!module.waiting) {
message += ' is ready';
} else {
var unresolvedDependencies = [];
for (var jj = 0; jj < module.dependencies.length; jj++) {
dependency = module.dependencies[jj];
if (!modulesMap[dependency] || modulesMap[dependency].waiting) {
unresolvedDependencies.push(dependency);
}
}
message += ' is waiting for ' + unresolvedDependencies.join(', ');
}
messages.push(message);
}
return messages.join('\n');
}
/**
* This is mainly for logging in ModuleErrorLogger.
*/
function ModuleError(msg) {
this.name = 'ModuleError';
this.message = msg;
this.stack = Error(msg).stack;
this.framesToPop = 2;
}
ModuleError.prototype = Object.create(Error.prototype);
ModuleError.prototype.constructor = ModuleError;
var _performance =
global.performance ||
global.msPerformance ||
global.webkitPerformance || {};
if (!_performance.now) {
_performance = global.Date;
}
var _now = _performance ?
_performance.now.bind(_performance) : function(){return 0;};
var _factoryStackCount = 0;
var _factoryTime = 0;
var _totalFactories = 0;
/**
* The require function conforming to CommonJS spec:
* http://wiki.commonjs.org/wiki/Modules/1.1.1
*
* To define a CommonJS-compliant module add the providesModule
* Haste header to your file instead of @provides. Your file is going
* to be executed in a separate context. Every variable/function you
* define will be local (private) to that module. To export local members
* use "exports" variable or return the exported value at the end of your
* file. Your code will have access to the "module" object.
* The "module" object will have an "id" property that is the id of your
* current module. "module" object will also have "exports" property that
* is the same as "exports" variable passed into your module context.
* You can require other modules using their ids.
*
* Haste will automatically pick dependencies from require() calls. So
* you don't have to manually specify @requires in your header.
*
* You cannot require() modules from non-CommonJS files. Write a legacy stub
* (@providesLegacy) and use @requires instead.
*
* @example
*
* / **
* * @providesModule math
* * /
* exports.add = function() {
* var sum = 0, i = 0, args = arguments, l = args.length;
* while (i < l) {
* sum += args[i++];
* }
* return sum;
* };
*
* / **
* * @providesModule increment
* * /
* var add = require('math').add;
* return function(val) {
* return add(val, 1);
* };
*
* / **
* * @providesModule program
* * /
* var inc = require('increment');
* var a = 1;
* inc(a); // 2
*
* module.id == "program";
*
*
* @param {String} id
* @throws when module is not loaded or not ready to be required
*/
function require(id) {
var module = modulesMap[id], dep, i, msg;
if (module && module.exports) {
// If ref count is 1, this was the last call, so undefine the module.
// The ref count can be null or undefined, but those are never === 1.
if (module.refcount-- === 1) {
delete modulesMap[id];
}
return module.exports;
}
if (global.ErrorUtils && !global.ErrorUtils.inGuard()) {
return ErrorUtils.applyWithGuard(require, this, arguments);
}
if (!module) {
msg = 'Requiring unknown module "' + id + '"';
if (__DEV__) {
msg += '. If you are sure the module is there, try restarting the packager.';
}
throw new ModuleError(msg);
}
if (module.hasError) {
throw new ModuleError(
'Requiring module "' + id + '" which threw an exception'
);
}
if (module.waiting) {
throw new ModuleError(
'Requiring module "' + id + '" with unresolved dependencies: ' +
_debugUnresolvedDependencies([id])
);
}
var exports = module.exports = {};
var factory = module.factory;
if (toString.call(factory) === '[object Function]') {
var args = [],
dependencies = module.dependencies,
length = dependencies.length,
ret;
if (module.special & USED_AS_TRANSPORT) {
length = Math.min(length, factory.length);
}
try {
for (i = 0; args.length < length; i++) {
dep = dependencies[i];
if (!module.inlineRequires[dep]) {
args.push(dep === 'module' ? module :
(dep === 'exports' ? exports :
require.call(null, dep)));
}
}
++_totalFactories;
if (_factoryStackCount++ === 0) {
_factoryTime -= _now();
}
try {
ret = factory.apply(module.context || global, args);
} catch (e) {
if (modulesMap.ex && modulesMap.erx) {
// when ErrorUtils is ready, ex and erx are ready. otherwise, we
// don't append module id to the error message but still throw it
var ex = require.call(null, 'ex');
var erx = require.call(null, 'erx');
var messageWithParams = erx(e.message);
if (messageWithParams[0].indexOf(' from module "%s"') < 0) {
messageWithParams[0] += ' from module "%s"';
messageWithParams[messageWithParams.length] = id;
}
e.message = ex.apply(null, messageWithParams);
}
throw e;
} finally {
if (--_factoryStackCount === 0) {
_factoryTime += _now();
}
}
} catch (e) {
module.hasError = true;
module.exports = null;
throw e;
}
if (ret) {
if (__DEV__) {
if (typeof ret != 'object' && typeof ret != 'function') {
throw new ModuleError(
'Factory for module "' + id + '" returned ' +
'an invalid value "' + ret + '". ' +
'Returned value should be either a function or an object.'
);
}
}
module.exports = ret;
}
} else {
module.exports = factory;
}
// If ref count is 1, this was the last call, so undefine the module.
// The ref count can be null or undefined, but those are never === 1.
if (module.refcount-- === 1) {
delete modulesMap[id];
}
return module.exports;
}
require.__getFactoryTime = function() {
return (_factoryStackCount ? _now() : 0) + _factoryTime;
};
require.__getTotalFactories = function() {
return _totalFactories;
};
/**
* The define function conforming to CommonJS proposal:
* http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition
*
* define() allows you to explicitly state dependencies of your module
* in javascript. It's most useful in non-CommonJS files.
*
* define() is used internally by haste as a transport for CommonJS
* modules. So there's no need to use define() if you use providesModule
*
* @example
* / **
* * @provides alpha
* * /
*
* // Sets up the module with ID of "alpha", that uses require,
* // exports and the module with ID of "beta":
* define("alpha", ["require", "exports", "beta"],
* function (require, exports, beta) {
* exports.verb = function() {
* return beta.verb();
* //Or:
* return require("beta").verb();
* }
* });
*
* / **
* * @provides alpha
* * /
* // An anonymous module could be defined (module id derived from filename)
* // that returns an object literal:
*
* define(["alpha"], function (alpha) {
* return {
* verb: function(){
* return alpha.verb() + 2;
* }
* };
* });
*
* / **
* * @provides alpha
* * /
* // A dependency-free module can define a direct object literal:
*
* define({
* add: function(x, y){
* return x + y;
* }
* });
*
* @param {String} id optional
* @param {Array} dependencies optional
* @param {Object|Function} factory
*/
function define(id, dependencies, factory,
_special, _context, _refCount, _inlineRequires) {
if (dependencies === undefined) {
dependencies = [];
factory = id;
id = _uid();
} else if (factory === undefined) {
factory = dependencies;
if (toString.call(id) === '[object Array]') {
dependencies = id;
id = _uid();
} else {
dependencies = [];
}
}
// Non-standard: we allow modules to be undefined. This is designed for
// temporary modules.
var canceler = { cancel: _undefine.bind(this, id) };
var record = modulesMap[id];
// Nonstandard hack: we call define with null deps and factory, but a
// non-null reference count (e.g. define('name', null, null, 0, null, 4))
// when this module is defined elsewhere and we just need to update the
// reference count. We use this hack to avoid having to expose another
// global function to increment ref counts.
if (record) {
if (_refCount) {
record.refcount += _refCount;
}
// Calling define() on a pre-existing module does not redefine it
return canceler;
} else if (!dependencies && !factory && _refCount) {
// If this module hasn't been defined yet, store the ref count. We'll use
// it when the module is defined later.
predefinedRefCounts[id] = (predefinedRefCounts[id] || 0) + _refCount;
return canceler;
} else {
// Defining a new module
record = { id: id };
record.refcount = (predefinedRefCounts[id] || 0) + (_refCount || 0);
delete predefinedRefCounts[id];
}
if (__DEV__) {
if (
!factory ||
(typeof factory != 'object' && typeof factory != 'function' &&
typeof factory != 'string')) {
throw new ModuleError(
'Invalid factory "' + factory + '" for module "' + id + '". ' +
'Factory should be either a function or an object.'
);
}
if (toString.call(dependencies) !== '[object Array]') {
throw new ModuleError(
'Invalid dependencies for module "' + id + '". ' +
'Dependencies must be passed as an array.'
);
}
}
record.factory = factory;
record.dependencies = dependencies;
record.context = _context;
record.special = _special;
record.inlineRequires = _inlineRequires || {};
record.waitingMap = {};
record.waiting = 0;
record.hasError = false;
modulesMap[id] = record;
_initDependencies(id);
return canceler;
}
function _undefine(id) {
if (!modulesMap[id]) {
return;
}
var module = modulesMap[id];
delete modulesMap[id];
for (var dep in module.waitingMap) {
if (module.waitingMap[dep]) {
delete dependencyMap[dep][id];
}
}
for (var ii = 0; ii < module.dependencies.length; ii++) {
dep = module.dependencies[ii];
if (modulesMap[dep]) {
if (modulesMap[dep].refcount-- === 1) {
_undefine(dep);
}
} else if (predefinedRefCounts[dep]) {
predefinedRefCounts[dep]--;
}
// Subtle: we won't account for this one fewer reference if we don't have
// the dependency's definition or reference count yet.
}
}
/**
* Special version of define that executes the factory as soon as all
* dependencies are met.
*
* define() does just that, defines a module. Module's factory will not be
* called until required by other module. This makes sense for most of our
* library modules: we do not want to execute the factory unless it's being
* used by someone.
*
* On the other hand there are modules, that you can call "entrance points".
* You want to run the "factory" method for them as soon as all dependencies
* are met.
*
* @example
*
* define('BaseClass', [], function() { return ... });
* // ^^ factory for BaseClass was just stored in modulesMap
*
* define('SubClass', ['BaseClass'], function() { ... });
* // SubClass module is marked as ready (waiting == 0), factory is just
* // stored
*
* define('OtherClass, ['BaseClass'], function() { ... });
* // OtherClass module is marked as ready (waiting == 0), factory is just
* // stored
*
* requireLazy(['SubClass', 'ChatConfig'],
* function() { ... });
* // ChatRunner is waiting for ChatConfig to come
*
* define('ChatConfig', [], { foo: 'bar' });
* // at this point ChatRunner is marked as ready, and its factory
* // executed + all dependent factories are executed too: BaseClass,
* // SubClass, ChatConfig notice that OtherClass's factory won't be
* // executed unless explicitly required by someone
*
* @param {Array} dependencies
* @param {Object|Function} factory
*/
function requireLazy(dependencies, factory, context) {
return define(
dependencies,
factory,
undefined,
REQUIRE_WHEN_READY,
context,
1
);
}
function _uid() {
return '__mod__' + _counter++;
}
function _addDependency(module, dep) {
// do not add duplicate dependencies and circ deps
if (!module.waitingMap[dep] && module.id !== dep) {
module.waiting++;
module.waitingMap[dep] = 1;
dependencyMap[dep] || (dependencyMap[dep] = {});
dependencyMap[dep][module.id] = 1;
}
}
function _initDependencies(id) {
var modulesToRequire = [];
var module = modulesMap[id];
var dep, i, subdep;
// initialize id's waitingMap
for (i = 0; i < module.dependencies.length; i++) {
dep = module.dependencies[i];
if (!modulesMap[dep]) {
_addDependency(module, dep);
} else if (modulesMap[dep].waiting) {
for (subdep in modulesMap[dep].waitingMap) {
if (modulesMap[dep].waitingMap[subdep]) {
_addDependency(module, subdep);
}
}
}
}
if (module.waiting === 0 && module.special & REQUIRE_WHEN_READY) {
modulesToRequire.push(id);
}
// update modules depending on id
if (dependencyMap[id]) {
var deps = dependencyMap[id];
var submodule;
dependencyMap[id] = undefined;
for (dep in deps) {
submodule = modulesMap[dep];
// add all deps of id
for (subdep in module.waitingMap) {
if (module.waitingMap[subdep]) {
_addDependency(submodule, subdep);
}
}
// remove id itself
if (submodule.waitingMap[id]) {
submodule.waitingMap[id] = undefined;
submodule.waiting--;
}
if (submodule.waiting === 0 &&
submodule.special & REQUIRE_WHEN_READY) {
modulesToRequire.push(dep);
}
}
}
// run everything that's ready
for (i = 0; i < modulesToRequire.length; i++) {
require.call(null, modulesToRequire[i]);
}
}
function _register(id, exports) {
var module = modulesMap[id] = { id: id };
module.exports = exports;
module.refcount = 0;
}
// pseudo name used in common-require
// see require() function for more info
_register('module', 0);
_register('exports', 0);
_register('global', global);
_register('require', require);
_register('requireDynamic', require);
_register('requireLazy', requireLazy);
global.require = require;
global.requireDynamic = require;
global.requireLazy = requireLazy;
require.__debug = {
modules: modulesMap,
deps: dependencyMap,
printDependencyInfo: function() {
if (!global.console) {
return;
}
var names = Object.keys(require.__debug.deps);
global.console.log(_debugUnresolvedDependencies(names));
}
};
/**
* All @providesModule files are wrapped by this function by makehaste. It
* is a convenience function around define() that prepends a bunch of required
* modules (global, require, module, etc) so that we don't have to spit that
* out for every module which would be a lot of extra bytes.
*/
global.__d = function(id, deps, factory, _special, _inlineRequires) {
var defaultDeps = ['global', 'require', 'requireDynamic', 'requireLazy',
'module', 'exports'];
define(id, defaultDeps.concat(deps), factory, _special || USED_AS_TRANSPORT,
null, null, _inlineRequires);
};
})(this);
/**
* Copyright (c) 2015-present, 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.
*
* This pipes all of our console logging functions to native logging so that
* JavaScript errors in required modules show up in Xcode via NSLog.
*
* @provides Object.es6
* @polyfill
*/
// WARNING: This is an optimized version that fails on hasOwnProperty checks
// and non objects. It's not spec-compliant. It's a perf optimization.
/* eslint global-strict:0 */
Object.assign = function(target, sources) {
if (__DEV__) {
if (target == null) {
throw new TypeError('Object.assign target cannot be null or undefined');
}
if (typeof target !== 'object' && typeof target !== 'function') {
throw new TypeError(
'In this environment the target of assign MUST be an object.' +
'This error is a performance optimization and not spec compliant.'
);
}
}
for (var nextIndex = 1; nextIndex < arguments.length; nextIndex++) {
var nextSource = arguments[nextIndex];
if (nextSource == null) {
continue;
}
if (__DEV__) {
if (typeof nextSource !== 'object' &&
typeof nextSource !== 'function') {
throw new TypeError(
'In this environment the target of assign MUST be an object.' +
'This error is a performance optimization and not spec compliant.'
);
}
}
// 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.
for (var key in nextSource) {
if (__DEV__) {
var hasOwnProperty = Object.prototype.hasOwnProperty;
if (!hasOwnProperty.call(nextSource, key)) {
throw new TypeError(
'One of the sources to assign has an enumerable key on the ' +
'prototype chain. This is an edge case that we do not support. ' +
'This error is a performance optimization and not spec compliant.'
);
}
}
target[key] = nextSource[key];
}
}
return target;
};
/**
* Copyright (c) 2015-present, 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.
*
* This pipes all of our console logging functions to native logging so that
* JavaScript errors in required modules show up in Xcode via NSLog.
*
* @provides console
* @polyfill
*/
/*eslint global-strict:0*/
(function(global) {
'use strict';
var OBJECT_COLUMN_NAME = '(index)';
var LOG_LEVELS = {
trace: 0,
log: 1,
info: 2,
warn: 3,
error: 4
};
function setupConsole(global) {
if (!global.nativeLoggingHook) {
return;
}
function getNativeLogFunction(level) {
return function() {
var str = Array.prototype.map.call(arguments, function(arg) {
var ret;
var type = typeof arg;
if (arg === null) {
ret = 'null';
} else if (arg === undefined) {
ret = 'undefined';
} else if (type === 'string') {
ret = '"' + arg + '"';
} else if (type === 'function') {
try {
ret = arg.toString();
} catch (e) {
ret = '[function unknown]';
}
} else {
// Perform a try catch, just in case the object has a circular
// reference or stringify throws for some other reason.
try {
ret = JSON.stringify(arg);
} catch (e) {
if (typeof arg.toString === 'function') {
try {
ret = arg.toString();
} catch (E) {}
}
}
}
return ret || '["' + type + '" failed to stringify]';
}).join(', ');
global.nativeLoggingHook(str, level);
};
}
var repeat = function(element, n) {
return Array.apply(null, Array(n)).map(function() { return element; });
};
function consoleTablePolyfill(rows) {
// convert object -> array
if (!Array.isArray(rows)) {
var data = rows;
rows = [];
for (var key in data) {
if (data.hasOwnProperty(key)) {
var row = data[key];
row[OBJECT_COLUMN_NAME] = key;
rows.push(row);
}
}
}
if (rows.length === 0) {
global.nativeLoggingHook('', LOG_LEVELS.log);
return;
}
var columns = Object.keys(rows[0]).sort();
var stringRows = [];
var columnWidths = [];
// Convert each cell to a string. Also
// figure out max cell width for each column
columns.forEach(function(k, i) {
columnWidths[i] = k.length;
for (var j = 0; j < rows.length; j++) {
var cellStr = rows[j][k].toString();
stringRows[j] = stringRows[j] || [];
stringRows[j][i] = cellStr;
columnWidths[i] = Math.max(columnWidths[i], cellStr.length);
}
});
// Join all elements in the row into a single string with | separators
// (appends extra spaces to each cell to make separators | alligned)
var joinRow = function(row, space) {
var cells = row.map(function(cell, i) {
var extraSpaces = repeat(' ', columnWidths[i] - cell.length).join('');
return cell + extraSpaces;
});
space = space || ' ';
return cells.join(space + '|' + space);
};
var separators = columnWidths.map(function(columnWidth) {
return repeat('-', columnWidth).join('');
});
var separatorRow = joinRow(separators, '-');
var header = joinRow(columns);
var table = [header, separatorRow];
for (var i = 0; i < rows.length; i++) {
table.push(joinRow(stringRows[i]));
}
// Notice extra empty line at the beginning.
// Native logging hook adds "RCTLog >" at the front of every
// logged string, which would shift the header and screw up
// the table
global.nativeLoggingHook('\n' + table.join('\n'), LOG_LEVELS.log);
}
global.console = {
error: getNativeLogFunction(LOG_LEVELS.error),
info: getNativeLogFunction(LOG_LEVELS.info),
log: getNativeLogFunction(LOG_LEVELS.log),
warn: getNativeLogFunction(LOG_LEVELS.warn),
trace: getNativeLogFunction(LOG_LEVELS.trace),
table: consoleTablePolyfill
};
}
if (typeof module !== 'undefined') {
module.exports = setupConsole;
} else {
setupConsole(global);
}
})(this);
/**
* Copyright (c) 2015-present, 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.
*
* The particular require runtime that we are using looks for a global
* `ErrorUtils` object and if it exists, then it requires modules with the
* error handler specified via ErrorUtils.setGlobalHandler by calling the
* require function with applyWithGuard. Since the require module is loaded
* before any of the modules, this ErrorUtils must be defined (and the handler
* set) globally before requiring anything.
*/
/* eslint global-strict:0 */
(function(global) {
var ErrorUtils = {
_inGuard: 0,
_globalHandler: null,
setGlobalHandler: function(fun) {
ErrorUtils._globalHandler = fun;
},
reportError: function(error) {
Error._globalHandler && ErrorUtils._globalHandler(error);
},
applyWithGuard: function(fun, context, args) {
try {
ErrorUtils._inGuard++;
return fun.apply(context, args);
} catch (e) {
ErrorUtils._globalHandler && ErrorUtils._globalHandler(e);
} finally {
ErrorUtils._inGuard--;
}
},
applyWithGuardIfNeeded: function(fun, context, args) {
if (ErrorUtils.inGuard()) {
return fun.apply(context, args);
} else {
ErrorUtils.applyWithGuard(fun, context, args);
}
},
inGuard: function() {
return ErrorUtils._inGuard;
},
guard: function(fun, name, context) {
if (typeof fun !== 'function') {
console.warn('A function must be passed to ErrorUtils.guard, got ', fun);
return null;
}
name = name || fun.name || '<generated guard>';
function guarded() {
return (
ErrorUtils.applyWithGuard(
fun,
context || this,
arguments,
null,
name
)
);
}
return guarded;
}
};
global.ErrorUtils = ErrorUtils;
/**
* This is the error handler that is called when we encounter an exception
* when loading a module.
*/
function setupErrorGuard() {
var onError = function(e) {
global.console.error(
'Error: ' +
'\n stack: ' + e.stack +
'\n line: ' + e.line +
'\n message: ' + e.message,
e
);
};
global.ErrorUtils.setGlobalHandler(onError);
}
setupErrorGuard();
})(this);
/**
* @provides String.prototype.es6
* @polyfill
*/
/*eslint global-strict:0, no-extend-native:0, no-bitwise:0 */
/*jshint bitwise:false*/
/*
* NOTE: We use (Number(x) || 0) to replace NaN values with zero.
*/
if (!String.prototype.startsWith) {
String.prototype.startsWith = function(search) {
'use strict';
if (this == null) {
throw TypeError();
}
var string = String(this);
var pos = arguments.length > 1 ?
(Number(arguments[1]) || 0) : 0;
var start = Math.min(Math.max(pos, 0), string.length);
return string.indexOf(String(search), pos) === start;
};
}
if (!String.prototype.endsWith) {
String.prototype.endsWith = function(search) {
'use strict';
if (this == null) {
throw TypeError();
}
var string = String(this);
var stringLength = string.length;
var searchString = String(search);
var pos = arguments.length > 1 ?
(Number(arguments[1]) || 0) : stringLength;
var end = Math.min(Math.max(pos, 0), stringLength);
var start = end - searchString.length;
if (start < 0) {
return false;
}
return string.lastIndexOf(searchString, start) === start;
};
}
if (!String.prototype.contains) {
String.prototype.contains = function(search) {
'use strict';
if (this == null) {
throw TypeError();
}
var string = String(this);
var pos = arguments.length > 1 ?
(Number(arguments[1]) || 0) : 0;
return string.indexOf(String(search), pos) !== -1;
};
}
if (!String.prototype.repeat) {
String.prototype.repeat = function(count) {
'use strict';
if (this == null) {
throw TypeError();
}
var string = String(this);
count = Number(count) || 0;
if (count < 0 || count === Infinity) {
throw RangeError();
}
if (count === 1) {
return string;
}
var result = '';
while (count) {
if (count & 1) {
result += string;
}
if ((count >>= 1)) {
string += string;
}
}
return result;
};
}
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @provides Array.prototype.es6
* @polyfill
*/
/*eslint-disable */
/*jslint bitwise: true */
(function(undefined) {
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex
function findIndex(predicate, context) {
if (this == null) {
throw new TypeError(
'Array.prototype.findIndex called on null or undefined'
);
}
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
var list = Object(this);
var length = list.length >>> 0;
for (var i = 0; i < length; i++) {
if (predicate.call(context, list[i], i, list)) {
return i;
}
}
return -1;
}
if (!Array.prototype.findIndex) {
Object.defineProperty(Array.prototype, 'findIndex', {
enumerable: false,
writable: true,
configurable: true,
value: findIndex
});
}
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
if (!Array.prototype.find) {
Object.defineProperty(Array.prototype, 'find', {
enumerable: false,
writable: true,
configurable: true,
value: function(predicate, context) {
if (this == null) {
throw new TypeError(
'Array.prototype.find called on null or undefined'
);
}
var index = findIndex.call(this, predicate, context);
return index === -1 ? undefined : this[index];
}
});
}
})();
__d('SimpleExample/index.ios',["react-native/Libraries/react-native/react-native"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Sample React Native App
* https://github.com/facebook/react-native
*/
'use strict';
var React = require('react-native/Libraries/react-native/react-native');
var $__0=
React,AppRegistry=$__0.AppRegistry,StyleSheet=$__0.StyleSheet,Text=$__0.Text,View=$__0.View;
var CounterApp = React.createClass({displayName: "CounterApp",
getInitialState:function() {
return {count: 0};
},
incrementCount:function() {
this.setState({count: this.state.count + 1});
},
render:function() {
return (
React.createElement(View, {style: styles.container},
React.createElement(Text, {style: styles.welcome},
"My first React Native app"
),
React.createElement(Text, {onPress: this.incrementCount, style: styles.counter},
this.state.count, " clicks"
)
)
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
welcome: {
fontSize: 26,
textAlign: 'center',
margin: 10,
},
counter: {
fontSize: 24,
}
});
AppRegistry.registerComponent('SimpleExample', function() {return CounterApp;});
});
__d('react-native/Libraries/react-native/react-native',["React","ActivityIndicatorIOS","DatePickerIOS","Image","ListView","MapView","NavigatorIOS","PickerIOS","Navigator","SegmentedControlIOS","ScrollView","SliderIOS","SwitchIOS","TabBarIOS","Text","TextInput","TouchableHighlight","TouchableOpacity","TouchableWithoutFeedback","View","WebView","AlertIOS","AppRegistry","AppStateIOS","AsyncStorage","CameraRoll","InteractionManager","LinkingIOS","LayoutAnimation","NetInfo","PixelRatio","PushNotificationIOS","PanResponder","StatusBarIOS","StyleSheet","VibrationIOS","RCTDeviceEventEmitter","NativeModules","requireNativeComponent","LinkedStateMixin","ReactComponentWithPureRenderMixin","NativeModules","ReactUpdates","cloneWithProps","ReactFragment","update","ReactDefaultPerf","ReactTestUtils"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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.
*
* @flow
*/
'use strict';
// Export React, plus some native additions.
//
// The use of Object.create/assign is to work around a Flow bug (#6560135).
// Once that is fixed, change this back to
//
// var ReactNative = {...require('React'), /* additions */}
//
var ReactNative = Object.assign(Object.create(require('React')), {
// Components
ActivityIndicatorIOS: require('ActivityIndicatorIOS'),
DatePickerIOS: require('DatePickerIOS'),
Image: require('Image'),
ListView: require('ListView'),
MapView: require('MapView'),
NavigatorIOS: require('NavigatorIOS'),
PickerIOS: require('PickerIOS'),
Navigator: require('Navigator'),
SegmentedControlIOS: require('SegmentedControlIOS'),
ScrollView: require('ScrollView'),
SliderIOS: require('SliderIOS'),
SwitchIOS: require('SwitchIOS'),
TabBarIOS: require('TabBarIOS'),
Text: require('Text'),
TextInput: require('TextInput'),
TouchableHighlight: require('TouchableHighlight'),
TouchableOpacity: require('TouchableOpacity'),
TouchableWithoutFeedback: require('TouchableWithoutFeedback'),
View: require('View'),
WebView: require('WebView'),
// APIs
AlertIOS: require('AlertIOS'),
AppRegistry: require('AppRegistry'),
AppStateIOS: require('AppStateIOS'),
AsyncStorage: require('AsyncStorage'),
CameraRoll: require('CameraRoll'),
InteractionManager: require('InteractionManager'),
LinkingIOS: require('LinkingIOS'),
LayoutAnimation: require('LayoutAnimation'),
NetInfo: require('NetInfo'),
PixelRatio: require('PixelRatio'),
PushNotificationIOS: require('PushNotificationIOS'),
PanResponder: require('PanResponder'),
StatusBarIOS: require('StatusBarIOS'),
StyleSheet: require('StyleSheet'),
VibrationIOS: require('VibrationIOS'),
// Plugins
DeviceEventEmitter: require('RCTDeviceEventEmitter'),
NativeModules: require('NativeModules'),
requireNativeComponent: require('requireNativeComponent'),
addons: {
LinkedStateMixin: require('LinkedStateMixin'),
Perf: undefined,
PureRenderMixin: require('ReactComponentWithPureRenderMixin'),
TestModule: require('NativeModules').TestModule,
TestUtils: undefined,
batchedUpdates: require('ReactUpdates').batchedUpdates,
cloneWithProps: require('cloneWithProps'),
createFragment: require('ReactFragment').create,
update: require('update'),
},
});
if (__DEV__) {
ReactNative.addons.Perf = require('ReactDefaultPerf');
ReactNative.addons.TestUtils = require('ReactTestUtils');
}
module.exports = ReactNative;
});
__d('React',["ReactIOS"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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
* @flow
*/
"use strict";
module.exports = require('ReactIOS');
});
__d('ReactIOS',["ReactChildren","ReactClass","ReactComponent","ReactContext","ReactCurrentOwner","ReactElement","ReactElementValidator","ReactInstanceHandles","ReactIOSDefaultInjection","ReactIOSMount","ReactPropTypes","deprecated","invariant","onlyChild","ReactReconciler","ReactIOSTextComponent"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 ReactIOS
* @flow
*/
"use strict";
var ReactChildren = require('ReactChildren');
var ReactClass = require('ReactClass');
var ReactComponent = require('ReactComponent');
var ReactContext = require('ReactContext');
var ReactCurrentOwner = require('ReactCurrentOwner');
var ReactElement = require('ReactElement');
var ReactElementValidator = require('ReactElementValidator');
var ReactInstanceHandles = require('ReactInstanceHandles');
var ReactIOSDefaultInjection = require('ReactIOSDefaultInjection');
var ReactIOSMount = require('ReactIOSMount');
var ReactPropTypes = require('ReactPropTypes');
var deprecated = require('deprecated');
var invariant = require('invariant');
var onlyChild = require('onlyChild');
ReactIOSDefaultInjection.inject();
var createElement = ReactElement.createElement;
var createFactory = ReactElement.createFactory;
var cloneElement = ReactElement.cloneElement;
if (__DEV__) {
createElement = ReactElementValidator.createElement;
createFactory = ReactElementValidator.createFactory;
cloneElement = ReactElementValidator.cloneElement;
}
var resolveDefaultProps = function(element) {
// Could be optimized, but not currently in heavy use.
var defaultProps = element.type.defaultProps;
var props = element.props;
for (var propName in defaultProps) {
if (props[propName] === undefined) {
props[propName] = defaultProps[propName];
}
}
};
// Experimental optimized element creation
var augmentElement = function(element ) {
if (__DEV__) {
invariant(
false,
'This optimized path should never be used in DEV mode because ' +
'it does not provide validation. Check your JSX transform.'
);
}
element._owner = ReactCurrentOwner.current;
element._context = ReactContext.current;
if (element.type.defaultProps) {
resolveDefaultProps(element);
}
return element;
};
var render = function(
element ,
mountInto ,
callback
) {
return ReactIOSMount.renderComponent(element, mountInto, callback);
};
var ReactIOS = {
hasReactIOSInitialized: false,
Children: {
map: ReactChildren.map,
forEach: ReactChildren.forEach,
count: ReactChildren.count,
only: onlyChild
},
Component: ReactComponent,
PropTypes: ReactPropTypes,
createClass: ReactClass.createClass,
createElement: createElement,
createFactory: createFactory,
cloneElement: cloneElement,
_augmentElement: augmentElement,
render: render,
unmountComponentAtNode: ReactIOSMount.unmountComponentAtNode,
// Hook for JSX spread, don't use this for anything else.
__spread: Object.assign,
unmountComponentAtNodeAndRemoveContainer: ReactIOSMount.unmountComponentAtNodeAndRemoveContainer,
isValidClass: ReactElement.isValidFactory,
isValidElement: ReactElement.isValidElement,
// Deprecations (remove for 0.13)
renderComponent: deprecated(
'React',
'renderComponent',
'render',
this,
render
),
isValidComponent: deprecated(
'React',
'isValidComponent',
'isValidElement',
this,
ReactElement.isValidElement
)
};
// Inject the runtime into a devtools global hook regardless of browser.
// Allows for debugging when the hook is injected on the page.
/* globals __REACT_DEVTOOLS_GLOBAL_HOOK__ */
if (
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') {
__REACT_DEVTOOLS_GLOBAL_HOOK__.inject({
CurrentOwner: ReactCurrentOwner,
InstanceHandles: ReactInstanceHandles,
Mount: ReactIOSMount,
Reconciler: require('ReactReconciler'),
TextComponent: require('ReactIOSTextComponent'),
});
}
module.exports = ReactIOS;
});
__d('ReactChildren',["PooledClass","ReactFragment","traverseAllChildren","warning"],function(global, require, requireDynamic, requireLazy, 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 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 (__DEV__) {
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
);
}
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;
});
__d('PooledClass',["invariant"],function(global, require, requireDynamic, requireLazy, 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 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;
invariant(
instance instanceof Klass,
'Trying to release an instance into a pool of a different type.'
);
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;
});
__d('invariant',[],function(global, require, requireDynamic, requireLazy, 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 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 (__DEV__) {
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;
});
__d('ReactFragment',["ReactElement","warning"],function(global, require, requireDynamic, requireLazy, 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 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 (__DEV__) {
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() {
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.'
);
this[didWarnKey] = true;
return this[fragmentKey][key];
},
set: function(value) {
warning(
this[didWarnKey],
'A ReactFragment is an immutable opaque type. Mutating its ' +
'properties is deprecated.'
);
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 (__DEV__) {
if (typeof object !== 'object' || !object || Array.isArray(object)) {
warning(
false,
'React.addons.createFragment only accepts a single object.',
object
);
return object;
}
if (ReactElement.isValidElement(object)) {
warning(
false,
'React.addons.createFragment does not accept a ReactElement ' +
'without a wrapper object.'
);
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 (__DEV__) {
if (canWarnForReactFragment) {
if (!fragment[fragmentKey]) {
warning(
didWarnForFragment(fragment),
'Any use of a keyed object should be wrapped in ' +
'React.addons.createFragment(object) before being passed as a ' +
'child.'
);
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 (__DEV__) {
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;
});
__d('ReactElement',["ReactContext","ReactCurrentOwner","Object.assign","warning"],function(global, require, requireDynamic, requireLazy, 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 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) {
warning(
false,
'Don\'t set the %s property of the React element. Instead, ' +
'specify the correct value when initially creating the element.',
key
);
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 (__DEV__) {
// 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 (__DEV__) {
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 (__DEV__) {
// 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;
});
__d('ReactContext',["Object.assign","emptyObject","warning"],function(global, require, requireDynamic, requireLazy, 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 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 (__DEV__) {
warning(
didWarn,
'withContext is deprecated and will be removed in a future version. ' +
'Use a wrapper component with getChildContext instead.'
);
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;
});
__d('Object.assign',[],function(global, require, requireDynamic, requireLazy, 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;
});
__d('emptyObject',[],function(global, require, requireDynamic, requireLazy, 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 emptyObject
*/
"use strict";
var emptyObject = {};
if (__DEV__) {
Object.freeze(emptyObject);
}
module.exports = emptyObject;
});
__d('warning',["emptyFunction"],function(global, require, requireDynamic, requireLazy, 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 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 (__DEV__) {
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;
});
__d('emptyFunction',[],function(global, require, requireDynamic, requireLazy, 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;
});
__d('ReactCurrentOwner',[],function(global, require, requireDynamic, requireLazy, 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;
});
__d('traverseAllChildren',["ReactElement","ReactFragment","ReactInstanceHandles","getIteratorFn","invariant","warning"],function(global, require, requireDynamic, requireLazy, 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 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 (__DEV__) {
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.'
);
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') {
invariant(
children.nodeType !== 1,
'traverseAllChildren(...): Encountered an invalid child; DOM ' +
'elements are not valid children of React components.'
);
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;
});
__d('ReactInstanceHandles',["ReactRootIndex","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright 2013-2014 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 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) {
invariant(
isValidID(ancestorID) && isValidID(destinationID),
'getNextDescendantID(%s, %s): Received an invalid React DOM ID.',
ancestorID,
destinationID
);
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
);
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;
for (var 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);
invariant(
isValidID(longestCommonID),
'getFirstCommonAncestorID(%s, %s): Expected a valid React DOM ID: %s',
oneID,
twoID,
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 || '';
invariant(
start !== stop,
'traverseParentPath(...): Cannot traverse from and to the same ID, `%s`.',
start
);
var traverseUp = isAncestorIDOf(stop, start);
invariant(
traverseUp || isAncestorIDOf(start, stop),
'traverseParentPath(%s, %s, ...): Cannot traverse from two IDs that do ' +
'not have a parent path.',
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;
}
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
);
}
}
/**
* 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);
}
},
/**
* Same as `traverseTwoPhase` but skips the `targetID`.
*/
traverseTwoPhaseSkipTarget: function(targetID, cb, arg) {
if (targetID) {
traverseParentPath('', targetID, cb, arg, true, true);
traverseParentPath(targetID, '', cb, arg, true, 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;
});
__d('ReactRootIndex',[],function(global, require, requireDynamic, requireLazy, 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;
});
__d('getIteratorFn',[],function(global, require, requireDynamic, requireLazy, 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;
});
__d('ReactClass',["ReactComponent","ReactCurrentOwner","ReactElement","ReactErrorUtils","ReactInstanceMap","ReactLifeCycle","ReactPropTypeLocations","ReactPropTypeLocationNames","ReactUpdateQueue","Object.assign","invariant","keyMirror","keyOf","warning"],function(global, require, requireDynamic, requireLazy, 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 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 (__DEV__) {
validateTypeDef(
Constructor,
childContextTypes,
ReactPropTypeLocations.childContext
);
}
Constructor.childContextTypes = assign(
{},
Constructor.childContextTypes,
childContextTypes
);
},
contextTypes: function(Constructor, contextTypes) {
if (__DEV__) {
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 (__DEV__) {
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__
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
);
}
}
}
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)) {
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
);
}
// Disallow defining methods more than once unless explicitly allowed.
if (proto.hasOwnProperty(name)) {
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
);
}
}
/**
* Mixin helper which handles policy validation and reserved
* specification keys when building React classses.
*/
function mixSpecIntoComponent(Constructor, spec) {
if (!spec) {
return;
}
invariant(
typeof spec !== 'function',
'ReactClass: You\'re attempting to ' +
'use a component class as a mixin. Instead, just use a regular object.'
);
invariant(
!ReactElement.isValidElement(spec),
'ReactClass: You\'re attempting to ' +
'use a component as a mixin. Instead, just use a regular object.'
);
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
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
);
// 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 (__DEV__) {
// 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;
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
);
var isInherited = name in Constructor;
invariant(
!isInherited,
'ReactClass: You are attempting to define ' +
'`%s` on your component more than once. This conflict may be ' +
'due to a mixin.',
name
);
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) {
invariant(
one && two && typeof one === 'object' && typeof two === 'object',
'mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects.'
);
for (var key in two) {
if (two.hasOwnProperty(key)) {
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
);
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 (__DEV__) {
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) {
warning(
false,
'bind(): React component methods may only be bound to the ' +
'component instance. See %s',
componentName
);
} else if (!args.length) {
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
);
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';
warning(
false,
'%s.type is deprecated. Use %s directly to access the class.',
displayName,
displayName
);
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 (__DEV__) {
var owner = ReactCurrentOwner.current;
if (owner !== null) {
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'
);
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 (__DEV__) {
warning(
this instanceof Constructor,
'Something is calling a React component directly. Use a factory or ' +
'JSX instead. See: http://fb.me/react-legacyfactory'
);
}
// 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 (__DEV__) {
// 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;
}
}
invariant(
typeof initialState === 'object' && !Array.isArray(initialState),
'%s.getInitialState(): must return an object or null',
Constructor.displayName || 'ReactCompositeComponent'
);
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 (__DEV__) {
// 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 = {};
}
}
invariant(
Constructor.prototype.render,
'createClass(...): Class specification must implement a `render` method.'
);
if (__DEV__) {
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'
);
}
// 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 (__DEV__) {
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;
});
__d('ReactComponent',["ReactUpdateQueue","invariant","warning"],function(global, require, requireDynamic, requireLazy, 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 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) {
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.'
);
if (__DEV__) {
warning(
partialState != null,
'setState(...): You passed an undefined or null state object; ' +
'instead, use forceUpdate().'
);
}
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 (__DEV__) {
var deprecatedAPIs = {
getDOMNode: 'getDOMNode',
isMounted: 'isMounted',
replaceProps: 'replaceProps',
replaceState: 'replaceState',
setProps: 'setProps'
};
var defineDeprecationWarning = function(methodName, displayName) {
try {
Object.defineProperty(ReactComponent.prototype, methodName, {
get: function() {
warning(
false,
'%s(...) is deprecated in plain JavaScript React classes.',
displayName
);
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;
});
__d('ReactUpdateQueue',["ReactLifeCycle","ReactCurrentOwner","ReactElement","ReactInstanceMap","ReactUpdates","Object.assign","invariant","warning"],function(global, require, requireDynamic, requireLazy, 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 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) {
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
);
var internalInstance = ReactInstanceMap.get(publicInstance);
if (!internalInstance) {
if (__DEV__) {
// 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.
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
);
}
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) {
invariant(
typeof callback === 'function',
'enqueueCallback(...): You called `setProps`, `replaceProps`, ' +
'`setState`, `replaceState`, or `forceUpdate` with a callback that ' +
'isn\'t callable.'
);
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) {
invariant(
typeof callback === 'function',
'enqueueCallback(...): You called `setProps`, `replaceProps`, ' +
'`setState`, `replaceState`, or `forceUpdate` with a callback that ' +
'isn\'t callable.'
);
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;
}
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.'
);
// 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;
}
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.'
);
// 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;
});
__d('ReactLifeCycle',[],function(global, require, requireDynamic, requireLazy, 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;
});
__d('ReactInstanceMap',[],function(global, require, requireDynamic, requireLazy, 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;
});
__d('ReactUpdates',["CallbackQueue","PooledClass","ReactCurrentOwner","ReactPerf","ReactReconciler","Transaction","Object.assign","invariant","warning"],function(global, require, requireDynamic, requireLazy, 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 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() {
invariant(
ReactUpdates.ReactReconcileTransaction && batchingStrategy,
'ReactUpdates: must inject a reconcile transaction class and batching ' +
'strategy'
);
}
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;
invariant(
len === dirtyComponents.length,
'Expected flush transaction\'s stored dirty-components length (%s) to ' +
'match dirty-components array length (%s).',
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.)
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.'
);
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) {
invariant(
batchingStrategy.isBatchingUpdates,
'ReactUpdates.asap: Can\'t enqueue an asap callback in a context where' +
'updates are not being batched.'
);
asapCallbackQueue.enqueue(callback, context);
asapEnqueued = true;
}
var ReactUpdatesInjection = {
injectReconcileTransaction: function(ReconcileTransaction) {
invariant(
ReconcileTransaction,
'ReactUpdates: must provide a reconcile transaction class'
);
ReactUpdates.ReactReconcileTransaction = ReconcileTransaction;
},
injectBatchingStrategy: function(_batchingStrategy) {
invariant(
_batchingStrategy,
'ReactUpdates: must provide a batching strategy'
);
invariant(
typeof _batchingStrategy.batchedUpdates === 'function',
'ReactUpdates: must provide a batchedUpdates() function'
);
invariant(
typeof _batchingStrategy.isBatchingUpdates === 'boolean',
'ReactUpdates: must provide an isBatchingUpdates boolean attribute'
);
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;
});
__d('CallbackQueue',["PooledClass","Object.assign","invariant"],function(global, require, requireDynamic, requireLazy, 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 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) {
invariant(
callbacks.length === contexts.length,
'Mismatched list of contexts in callback queue'
);
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;
});
__d('ReactPerf',[],function(global, require, requireDynamic, requireLazy, 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 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 (__DEV__) {
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 (__DEV__) {
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;
});
__d('ReactReconciler',["ReactRef","ReactElementValidator"],function(global, require, requireDynamic, requireLazy, 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 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 (__DEV__) {
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 (__DEV__) {
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;
});
__d('ReactRef',["ReactOwner"],function(global, require, requireDynamic, requireLazy, 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;
});
__d('ReactOwner',["invariant"],function(global, require, requireDynamic, requireLazy, 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 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) {
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.'
);
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) {
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.'
);
// 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;
});
__d('ReactElementValidator',["ReactElement","ReactFragment","ReactPropTypeLocations","ReactPropTypeLocationNames","ReactCurrentOwner","ReactNativeComponent","getIteratorFn","invariant","warning"],function(global, require, requireDynamic, requireLazy, 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 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 + ".");
}
warning(
false,
message + '%s%s See http://fb.me/react-warning-keys for more information.',
parentOrOwnerAddendum,
childOwnerAddendum
);
}
/**
* 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.
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
);
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);
warning(false, 'Failed propType: %s%s', error.message, addendum);
}
}
}
}
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 + '.';
}
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
);
}
// 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') {
warning(
componentClass.getDefaultProps.isReactClassApproved,
'getDefaultProps is only used on classic React.createClass ' +
'definitions. Use a static property named `defaultProps` instead.'
);
}
}
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.
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).'
);
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 (__DEV__) {
try {
Object.defineProperty(
validatedFactory,
'type',
{
enumerable: false,
get: function() {
warning(
false,
'Factory.type is deprecated. Access the class directly ' +
'before passing it to createFactory.'
);
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;
});
__d('ReactPropTypeLocations',["keyMirror"],function(global, require, requireDynamic, requireLazy, 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;
});
__d('keyMirror',["invariant"],function(global, require, requireDynamic, requireLazy, 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 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;
invariant(
obj instanceof Object && !Array.isArray(obj),
'keyMirror(...): Argument must be an object.'
);
for (key in obj) {
if (!obj.hasOwnProperty(key)) {
continue;
}
ret[key] = key;
}
return ret;
};
module.exports = keyMirror;
});
__d('ReactPropTypeLocationNames',[],function(global, require, requireDynamic, requireLazy, 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 ReactPropTypeLocationNames
*/
'use strict';
var ReactPropTypeLocationNames = {};
if (__DEV__) {
ReactPropTypeLocationNames = {
prop: 'prop',
context: 'context',
childContext: 'child context'
};
}
module.exports = ReactPropTypeLocationNames;
});
__d('ReactNativeComponent',["Object.assign","invariant"],function(global, require, requireDynamic, requireLazy, 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 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) {
invariant(
genericComponentClass,
'There is no registered component for the tag %s',
element.type
);
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;
});
__d('Transaction',["invariant"],function(global, require, requireDynamic, requireLazy, 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 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) {
invariant(
!this.isInTransaction(),
'Transaction.perform(...): Cannot initialize a transaction when there ' +
'is already an outstanding transaction.'
);
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) {
invariant(
this.isInTransaction(),
'Transaction.closeAll(): Cannot close transaction when none are open.'
);
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;
});
__d('ReactErrorUtils',[],function(global, require, requireDynamic, requireLazy, 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;
});
__d('keyOf',[],function(global, require, requireDynamic, requireLazy, 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;
});
__d('ReactIOSDefaultInjection',["InitializeJavaScriptAppEngine","EventPluginHub","EventPluginUtils","IOSDefaultEventPluginOrder","IOSNativeBridgeEventPlugin","NodeHandle","ReactClass","ReactComponentEnvironment","ReactDefaultBatchingStrategy","ReactEmptyComponent","ReactInstanceHandles","ReactIOSComponentEnvironment","ReactIOSComponentMixin","ReactIOSGlobalInteractionHandler","ReactIOSGlobalResponderHandler","ReactIOSMount","ReactIOSTextComponent","ReactNativeComponent","ReactUpdates","ResponderEventPlugin","UniversalWorkerNodeHandle","createReactIOSNativeComponentClass","invariant","RCTEventEmitter","RCTLog","RCTJSTimers"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 ReactIOSDefaultInjection
* @flow
*/
"use strict";
/**
* Make sure `setTimeout`/`setInterval` are patched correctly.
*/
require('InitializeJavaScriptAppEngine');
var EventPluginHub = require('EventPluginHub');
var EventPluginUtils = require('EventPluginUtils');
var IOSDefaultEventPluginOrder = require('IOSDefaultEventPluginOrder');
var IOSNativeBridgeEventPlugin = require('IOSNativeBridgeEventPlugin');
var NodeHandle = require('NodeHandle');
var ReactClass = require('ReactClass');
var ReactComponentEnvironment = require('ReactComponentEnvironment');
var ReactDefaultBatchingStrategy = require('ReactDefaultBatchingStrategy');
var ReactEmptyComponent = require('ReactEmptyComponent');
var ReactInstanceHandles = require('ReactInstanceHandles');
var ReactIOSComponentEnvironment = require('ReactIOSComponentEnvironment');
var ReactIOSComponentMixin = require('ReactIOSComponentMixin');
var ReactIOSGlobalInteractionHandler = require('ReactIOSGlobalInteractionHandler');
var ReactIOSGlobalResponderHandler = require('ReactIOSGlobalResponderHandler');
var ReactIOSMount = require('ReactIOSMount');
var ReactIOSTextComponent = require('ReactIOSTextComponent');
var ReactNativeComponent = require('ReactNativeComponent');
var ReactUpdates = require('ReactUpdates');
var ResponderEventPlugin = require('ResponderEventPlugin');
var UniversalWorkerNodeHandle = require('UniversalWorkerNodeHandle');
var createReactIOSNativeComponentClass = require('createReactIOSNativeComponentClass');
var invariant = require('invariant');
// Just to ensure this gets packaged, since its only caller is from Native.
require('RCTEventEmitter');
require('RCTLog');
require('RCTJSTimers');
function inject() {
/**
* Inject module for resolving DOM hierarchy and plugin ordering.
*/
EventPluginHub.injection.injectEventPluginOrder(IOSDefaultEventPluginOrder);
EventPluginHub.injection.injectInstanceHandle(ReactInstanceHandles);
ResponderEventPlugin.injection.injectGlobalResponderHandler(
ReactIOSGlobalResponderHandler
);
ResponderEventPlugin.injection.injectGlobalInteractionHandler(
ReactIOSGlobalInteractionHandler
);
/**
* Some important event plugins included by default (without having to require
* them).
*/
EventPluginHub.injection.injectEventPluginsByName({
'ResponderEventPlugin': ResponderEventPlugin,
'IOSNativeBridgeEventPlugin': IOSNativeBridgeEventPlugin
});
ReactUpdates.injection.injectReconcileTransaction(
ReactIOSComponentEnvironment.ReactReconcileTransaction
);
ReactUpdates.injection.injectBatchingStrategy(
ReactDefaultBatchingStrategy
);
ReactComponentEnvironment.injection.injectEnvironment(
ReactIOSComponentEnvironment
);
// Can't import View here because it depends on React to make its composite
var RCTView = createReactIOSNativeComponentClass({
validAttributes: {},
uiViewClassName: 'RCTView',
});
ReactEmptyComponent.injection.injectEmptyComponent(RCTView);
EventPluginUtils.injection.injectMount(ReactIOSMount);
ReactClass.injection.injectMixin(ReactIOSComponentMixin);
ReactNativeComponent.injection.injectTextComponentClass(
ReactIOSTextComponent
);
ReactNativeComponent.injection.injectAutoWrapper(function(tag) {
// Show a nicer error message for non-function tags
var info = '';
if (typeof tag === 'string' && /^[a-z]/.test(tag)) {
info += ' Each component name should start with an uppercase letter.';
}
invariant(false, 'Expected a component class, got %s.%s', tag, info);
});
NodeHandle.injection.injectImplementation(UniversalWorkerNodeHandle);
}
module.exports = {
inject: inject,
};
});
__d('InitializeJavaScriptAppEngine',["RCTDeviceEventEmitter","ExceptionsManager","ErrorUtils","ExceptionsManager","Platform","JSTimers","NativeModules","Promise","XMLHttpRequest","fetch","Geolocation"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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.
*
* Sets up global variables typical in most JavaScript environments.
*
* 1. Global timers (via `setTimeout` etc).
* 2. Global console object.
* 3. Hooks for printing stack traces with source maps.
*
* Leaves enough room in the environment for implementing your own:
* 1. Require system.
* 2. Bridged modules.
*
* @providesModule InitializeJavaScriptAppEngine
*/
/* eslint global-strict: 0 */
/* globals GLOBAL: true, window: true */
// Just to make sure the JS gets packaged up.
require('RCTDeviceEventEmitter');
if (typeof GLOBAL === 'undefined') {
GLOBAL = this;
}
if (typeof window === 'undefined') {
window = GLOBAL;
}
/**
* The document must be shimmed before anything else that might define the
* `ExecutionEnvironment` module (which checks for `document.createElement`).
*/
function setupDocumentShim() {
// The browser defines Text and Image globals by default. If you forget to
// require them, then the error message is very confusing.
function getInvalidGlobalUseError(name) {
return new Error(
'You are trying to render the global ' + name + ' variable as a ' +
'React element. You probably forgot to require ' + name + '.'
);
}
GLOBAL.Text = {
get defaultProps() {
throw getInvalidGlobalUseError('Text');
}
};
GLOBAL.Image = {
get defaultProps() {
throw getInvalidGlobalUseError('Image');
}
};
// Force `ExecutionEnvironment.canUseDOM` to be false.
if (GLOBAL.document) {
GLOBAL.document.createElement = null;
}
// There is no DOM so MutationObserver doesn't make sense. It is used
// as feature detection in Bluebird Promise implementation
GLOBAL.MutationObserver = undefined;
}
function handleErrorWithRedBox(e) {
try {
require('ExceptionsManager').handleException(e);
} catch(ee) {
console.log('Failed to print error: ', ee.message);
}
}
function setupRedBoxErrorHandler() {
var ErrorUtils = require('ErrorUtils');
ErrorUtils.setGlobalHandler(handleErrorWithRedBox);
}
function setupRedBoxConsoleErrorHandler() {
// ExceptionsManager transitively requires Promise so we install it after
var ExceptionsManager = require('ExceptionsManager');
var Platform = require('Platform');
// TODO (#6925182): Enable console.error redbox on Android
if (__DEV__ && Platform.OS === 'ios') {
ExceptionsManager.installConsoleErrorReporter();
}
}
/**
* Sets up a set of window environment wrappers that ensure that the
* BatchedBridge is flushed after each tick. In both the case of the
* `UIWebView` based `RCTJavaScriptCaller` and `RCTContextCaller`, we
* implement our own custom timing bridge that should be immune to
* unexplainably dropped timing signals.
*/
function setupTimers() {
var JSTimers = require('JSTimers');
GLOBAL.setTimeout = JSTimers.setTimeout;
GLOBAL.setInterval = JSTimers.setInterval;
GLOBAL.setImmediate = JSTimers.setImmediate;
GLOBAL.clearTimeout = JSTimers.clearTimeout;
GLOBAL.clearInterval = JSTimers.clearInterval;
GLOBAL.clearImmediate = JSTimers.clearImmediate;
GLOBAL.cancelAnimationFrame = JSTimers.clearInterval;
GLOBAL.requestAnimationFrame = function(cb) {
/*requestAnimationFrame() { [native code] };*/ // Trick scroller library
return JSTimers.requestAnimationFrame(cb); // into thinking it's native
};
}
function setupAlert() {
var RCTAlertManager = require('NativeModules').AlertManager;
if (!GLOBAL.alert) {
GLOBAL.alert = function(text) {
var alertOpts = {
title: 'Alert',
message: '' + text,
buttons: [{'cancel': 'Okay'}],
};
RCTAlertManager.alertWithArgs(alertOpts, null);
};
}
}
function setupPromise() {
// The native Promise implementation throws the following error:
// ERROR: Event loop not supported.
GLOBAL.Promise = require('Promise');
}
function setupXHR() {
// The native XMLHttpRequest in Chrome dev tools is CORS aware and won't
// let you fetch anything from the internet
GLOBAL.XMLHttpRequest = require('XMLHttpRequest');
var fetchPolyfill = require('fetch');
GLOBAL.fetch = fetchPolyfill.fetch;
GLOBAL.Headers = fetchPolyfill.Headers;
GLOBAL.Request = fetchPolyfill.Request;
GLOBAL.Response = fetchPolyfill.Response;
}
function setupGeolocation() {
GLOBAL.navigator = GLOBAL.navigator || {};
GLOBAL.navigator.geolocation = require('Geolocation');
}
setupDocumentShim();
setupRedBoxErrorHandler();
setupTimers();
setupAlert();
setupPromise();
setupXHR();
setupRedBoxConsoleErrorHandler();
setupGeolocation();
});
__d('RCTDeviceEventEmitter',["EventEmitter"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 RCTDeviceEventEmitter
* @flow
*/
'use strict';
var EventEmitter = require('EventEmitter');
var RCTDeviceEventEmitter = new EventEmitter();
module.exports = RCTDeviceEventEmitter;
});
__d('EventEmitter',["EmitterSubscription","ErrorUtils","EventSubscriptionVendor","emptyFunction","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* @generated SignedSource<<494e66dea72a3e90b763a5ec50b1e0ca>>
*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* !! This file is a check-in of a static_upstream project! !!
* !! !!
* !! You should not modify this file directly. Instead: !!
* !! 1) Use `fjs use-upstream` to temporarily replace this with !!
* !! the latest version from upstream. !!
* !! 2) Make your changes, test them, etc. !!
* !! 3) Use `fjs push-upstream` to copy your changes back to !!
* !! static_upstream. !!
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
* @providesModule EventEmitter
* @typechecks
*/
var EmitterSubscription = require('EmitterSubscription');
var ErrorUtils = require('ErrorUtils');
var EventSubscriptionVendor = require('EventSubscriptionVendor');
var emptyFunction = require('emptyFunction');
var invariant = require('invariant');
/**
* @class EventEmitter
* @description
* An EventEmitter is responsible for managing a set of listeners and publishing
* events to them when it is told that such events happened. In addition to the
* data for the given event it also sends a event control object which allows
* the listeners/handlers to prevent the default behavior of the given event.
*
* The emitter is designed to be generic enough to support all the different
* contexts in which one might want to emit events. It is a simple multicast
* mechanism on top of which extra functionality can be composed. For example, a
* more advanced emitter may use an EventHolder and EventFactory.
*/
/**
* @constructor
*/
function EventEmitter() {"use strict";
this.$EventEmitter_subscriber = new EventSubscriptionVendor();
}
/**
* Adds a listener to be invoked when events of the specified type are
* emitted. An optional calling context may be provided. The data arguments
* emitted will be passed to the listener function.
*
* TODO: Annotate the listener arg's type. This is tricky because listeners
* can be invoked with varargs.
*
* @param {string} eventType - Name of the event to listen to
* @param {function} listener - Function to invoke when the specified event is
* emitted
* @param {*} context - Optional context object to use when invoking the
* listener
*/
EventEmitter.prototype.addListener=function(
eventType , listener, context ) {"use strict";
return this.$EventEmitter_subscriber.addSubscription(
eventType,
new EmitterSubscription(this.$EventEmitter_subscriber, listener, context));
};
/**
* Similar to addListener, except that the listener is removed after it is
* invoked once.
*
* @param {string} eventType - Name of the event to listen to
* @param {function} listener - Function to invoke only once when the
* specified event is emitted
* @param {*} context - Optional context object to use when invoking the
* listener
*/
EventEmitter.prototype.once=function(eventType , listener, context ) {"use strict";
var emitter = this;
return this.addListener(eventType, function() {
emitter.removeCurrentListener();
listener.apply(context, arguments);
});
};
/**
* Removes all of the registered listeners, including those registered as
* listener maps.
*
* @param {?string} eventType - Optional name of the event whose registered
* listeners to remove
*/
EventEmitter.prototype.removeAllListeners=function(eventType ) {"use strict";
this.$EventEmitter_subscriber.removeAllSubscriptions(eventType);
};
/**
* Provides an API that can be called during an eventing cycle to remove the
* last listener that was invoked. This allows a developer to provide an event
* object that can remove the listener (or listener map) during the
* invocation.
*
* If it is called when not inside of an emitting cycle it will throw.
*
* @throws {Error} When called not during an eventing cycle
*
* @example
* var subscription = emitter.addListenerMap({
* someEvent: function(data, event) {
* console.log(data);
* emitter.removeCurrentListener();
* }
* });
*
* emitter.emit('someEvent', 'abc'); // logs 'abc'
* emitter.emit('someEvent', 'def'); // does not log anything
*/
EventEmitter.prototype.removeCurrentListener=function() {"use strict";
invariant(
!!this.$EventEmitter_currentSubscription,
'Not in an emitting cycle; there is no current subscription'
);
this.$EventEmitter_subscriber.removeSubscription(this.$EventEmitter_currentSubscription);
};
/**
* Returns an array of listeners that are currently registered for the given
* event.
*
* @param {string} eventType - Name of the event to query
* @returns {array}
*/
EventEmitter.prototype.listeners=function(eventType ) /* TODO: Array<EventSubscription> */ {"use strict";
var subscriptions = this.$EventEmitter_subscriber.getSubscriptionsForType(eventType);
return subscriptions
? subscriptions.filter(emptyFunction.thatReturnsTrue).map(
function(subscription) {
return subscription.listener;
})
: [];
};
/**
* Emits an event of the given type with the given data. All handlers of that
* particular type will be notified.
*
* @param {string} eventType - Name of the event to emit
* @param {...*} Arbitrary arguments to be passed to each registered listener
*
* @example
* emitter.addListener('someEvent', function(message) {
* console.log(message);
* });
*
* emitter.emit('someEvent', 'abc'); // logs 'abc'
*/
EventEmitter.prototype.emit=function(eventType ) {"use strict";
var subscriptions = this.$EventEmitter_subscriber.getSubscriptionsForType(eventType);
if (subscriptions) {
var keys = Object.keys(subscriptions);
for (var ii = 0; ii < keys.length; ii++) {
var key = keys[ii];
var subscription = subscriptions[key];
// The subscription may have been removed during this event loop.
if (subscription) {
this.$EventEmitter_currentSubscription = subscription;
ErrorUtils.applyWithGuard(
subscription.listener,
subscription.context,
Array.prototype.slice.call(arguments, 1),
null,
'EventEmitter:' + eventType
);
}
}
this.$EventEmitter_currentSubscription = null;
}
};
module.exports = EventEmitter;
});
__d('EmitterSubscription',["EventSubscription"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* @generated SignedSource<<d17b6e5d9b7118fb0ed9169f579e5b8a>>
*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* !! This file is a check-in of a static_upstream project! !!
* !! !!
* !! You should not modify this file directly. Instead: !!
* !! 1) Use `fjs use-upstream` to temporarily replace this with !!
* !! the latest version from upstream. !!
* !! 2) Make your changes, test them, etc. !!
* !! 3) Use `fjs push-upstream` to copy your changes back to !!
* !! static_upstream. !!
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
* @providesModule EmitterSubscription
* @typechecks
*/
'use strict';
var EventSubscription = require('EventSubscription');
/**
* EmitterSubscription represents a subscription with listener and context data.
*/
for(var EventSubscription____Key in EventSubscription){if(EventSubscription.hasOwnProperty(EventSubscription____Key)){EmitterSubscription[EventSubscription____Key]=EventSubscription[EventSubscription____Key];}}var ____SuperProtoOfEventSubscription=EventSubscription===null?null:EventSubscription.prototype;EmitterSubscription.prototype=Object.create(____SuperProtoOfEventSubscription);EmitterSubscription.prototype.constructor=EmitterSubscription;EmitterSubscription.__superConstructor__=EventSubscription;
/**
* @param {EventSubscriptionVendor} subscriber - The subscriber that controls
* this subscription
* @param {function} listener - Function to invoke when the specified event is
* emitted
* @param {*} context - Optional context object to use when invoking the
* listener
*/
function EmitterSubscription(subscriber , listener, context ) {
EventSubscription.call(this,subscriber);
this.listener = listener;
this.context = context;
}
module.exports = EmitterSubscription;
});
__d('EventSubscription',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* @generated SignedSource<<92108a17b1f3eee4b7e3dd7d484aa17a>>
*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* !! This file is a check-in of a static_upstream project! !!
* !! !!
* !! You should not modify this file directly. Instead: !!
* !! 1) Use `fjs use-upstream` to temporarily replace this with !!
* !! the latest version from upstream. !!
* !! 2) Make your changes, test them, etc. !!
* !! 3) Use `fjs push-upstream` to copy your changes back to !!
* !! static_upstream. !!
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
* @providesModule EventSubscription
* @typechecks
*/
'use strict';
/**
* EventSubscription represents a subscription to a particular event. It can
* remove its own subscription.
*/
/**
* @param {EventSubscriptionVendor} subscriber the subscriber that controls
* this subscription.
*/
function EventSubscription(subscriber ) {
this.subscriber = subscriber;
}
/**
* Removes this subscription from the subscriber that controls it.
*/
EventSubscription.prototype.remove=function() {
this.subscriber.removeSubscription(this);
};
module.exports = EventSubscription;
});
__d('ErrorUtils',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 ErrorUtils
*/
var GLOBAL = this;
/**
* The particular require runtime that we are using looks for a global
* `ErrorUtils` object and if it exists, then it requires modules with the
* error handler specified via ErrorUtils.setGlobalHandler by calling the
* require function with applyWithGuard. Since the require module is loaded
* before any of the modules, this ErrorUtils must be defined (and the handler
* set) globally before requiring anything.
*
* However, we still want to treat ErrorUtils as a module so that other modules
* that use it aren't just using a global variable, so simply export the global
* variable here. ErrorUtils is original defined in a file named error-guard.js.
*/
module.exports = GLOBAL.ErrorUtils;
});
__d('EventSubscriptionVendor',["invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* @generated SignedSource<<24d5cc1cdd24704296686faf89dd36cf>>
*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* !! This file is a check-in of a static_upstream project! !!
* !! !!
* !! You should not modify this file directly. Instead: !!
* !! 1) Use `fjs use-upstream` to temporarily replace this with !!
* !! the latest version from upstream. !!
* !! 2) Make your changes, test them, etc. !!
* !! 3) Use `fjs push-upstream` to copy your changes back to !!
* !! static_upstream. !!
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
* @providesModule EventSubscriptionVendor
* @typechecks
*/
'use strict';
var invariant = require('invariant');
/**
* EventSubscriptionVendor stores a set of EventSubscriptions that are
* subscribed to a particular event type.
*/
function EventSubscriptionVendor() {
this.$EventSubscriptionVendor_subscriptionsForType = {};
this.$EventSubscriptionVendor_currentSubscription = null;
}
/**
* Adds a subscription keyed by an event type.
*
* @param {string} eventType
* @param {EventSubscription} subscription
*/
EventSubscriptionVendor.prototype.addSubscription=function(
eventType , subscription ) {
invariant(
subscription.subscriber === this,
'The subscriber of the subscription is incorrectly set.');
if (!this.$EventSubscriptionVendor_subscriptionsForType[eventType]) {
this.$EventSubscriptionVendor_subscriptionsForType[eventType] = [];
}
var key = this.$EventSubscriptionVendor_subscriptionsForType[eventType].length;
this.$EventSubscriptionVendor_subscriptionsForType[eventType].push(subscription);
subscription.eventType = eventType;
subscription.key = key;
return subscription;
};
/**
* Removes a bulk set of the subscriptions.
*
* @param {?string} eventType - Optional name of the event type whose
* registered supscriptions to remove, if null remove all subscriptions.
*/
EventSubscriptionVendor.prototype.removeAllSubscriptions=function(eventType ) {
if (eventType === undefined) {
this.$EventSubscriptionVendor_subscriptionsForType = {};
} else {
delete this.$EventSubscriptionVendor_subscriptionsForType[eventType];
}
};
/**
* Removes a specific subscription. Instead of calling this function, call
* `subscription.remove()` directly.
*
* @param {object} subscription
*/
EventSubscriptionVendor.prototype.removeSubscription=function(subscription ) {
var eventType = subscription.eventType;
var key = subscription.key;
var subscriptionsForType = this.$EventSubscriptionVendor_subscriptionsForType[eventType];
if (subscriptionsForType) {
delete subscriptionsForType[key];
}
};
/**
* Returns the array of subscriptions that are currently registered for the
* given event type.
*
* Note: This array can be potentially sparse as subscriptions are deleted
* from it when they are removed.
*
* TODO: This returns a nullable array. wat?
*
* @param {string} eventType
* @returns {?array}
*/
EventSubscriptionVendor.prototype.getSubscriptionsForType=function(eventType ) {
return this.$EventSubscriptionVendor_subscriptionsForType[eventType];
};
module.exports = EventSubscriptionVendor;
});
__d('ExceptionsManager',["NativeModules","loadSourceMap","parseErrorStack","stringifySafe"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 ExceptionsManager
* @flow
*/
'use strict';
var RCTExceptionsManager = require('NativeModules').ExceptionsManager;
var loadSourceMap = require('loadSourceMap');
var parseErrorStack = require('parseErrorStack');
var stringifySafe = require('stringifySafe');
var sourceMapPromise;
function reportException(e , stack ) {
if (RCTExceptionsManager) {
if (!stack) {
stack = parseErrorStack(e);
}
RCTExceptionsManager.reportUnhandledException(e.message, stack);
if (__DEV__) {
(sourceMapPromise = sourceMapPromise || loadSourceMap())
.then(function(map) {
var prettyStack = parseErrorStack(e, map);
RCTExceptionsManager.updateExceptionMessage(e.message, prettyStack);
})
.then(null, function(error) {
console.error('#CLOWNTOWN (error while displaying error): ' + error.message);
});
}
}
}
function handleException(e ) {
var stack = parseErrorStack(e);
var msg =
'Error: ' + e.message +
'\n stack: \n' + stackToString(stack) +
'\n URL: ' + e.sourceURL +
'\n line: ' + e.line +
'\n message: ' + e.message;
if (console.errorOriginal) {
console.errorOriginal(msg);
} else {
console.error(msg);
}
reportException(e, stack);
}
/**
* Shows a redbox with stacktrace for all console.error messages. Disable by
* setting `console.reportErrorsAsExceptions = false;` in your app.
*/
function installConsoleErrorReporter() {
if (console.reportException) {
return; // already installed
}
console.reportException = reportException;
console.errorOriginal = console.error.bind(console);
console.error = function reactConsoleError() {
console.errorOriginal.apply(null, arguments);
if (!console.reportErrorsAsExceptions) {
return;
}
var str = Array.prototype.map.call(arguments, stringifySafe).join(', ');
var error = new Error('console.error: ' + str);
error.framesToPop = 1;
reportException(error);
};
if (console.reportErrorsAsExceptions === undefined) {
console.reportErrorsAsExceptions = true; // Individual apps can disable this
}
}
function stackToString(stack) {
var maxLength = Math.max.apply(null, stack.map(function(frame) {return frame.methodName.length;}));
return stack.map(function(frame) {return stackFrameToString(frame, maxLength);}).join('\n');
}
function stackFrameToString(stackFrame, maxLength) {
var fileNameParts = stackFrame.file.split('/');
var fileName = fileNameParts[fileNameParts.length - 1];
if (fileName.length > 18) {
fileName = fileName.substr(0, 17) + '\u2026' /* ... */;
}
var spaces = fillSpaces(maxLength - stackFrame.methodName.length);
return ' ' + stackFrame.methodName + spaces + ' ' + fileName + ':' + stackFrame.lineNumber;
}
function fillSpaces(n) {
return new Array(n + 1).join(' ');
}
module.exports = { handleException:handleException, installConsoleErrorReporter:installConsoleErrorReporter };
});
__d('NativeModules',["BatchedBridge","nativeModulePrefixNormalizer"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 NativeModules
* @flow
*/
'use strict';
var NativeModules = require('BatchedBridge').RemoteModules;
var nativeModulePrefixNormalizer = require('nativeModulePrefixNormalizer');
nativeModulePrefixNormalizer(NativeModules);
module.exports = NativeModules;
});
__d('BatchedBridge',["BatchedBridgeFactory","MessageQueue"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 BatchedBridge
*/
'use strict';
var BatchedBridgeFactory = require('BatchedBridgeFactory');
var MessageQueue = require('MessageQueue');
/**
* Signature that matches the native IOS modules/methods that are exposed. We
* indicate which ones accept a callback. The order of modules and methods
* within them implicitly define their numerical *ID* that will be used to
* describe method calls across the wire. This is so that memory is used
* efficiently and we do not need to copy strings in native land - or across any
* wire.
*/
var remoteModulesConfig = __fbBatchedBridgeConfig.remoteModuleConfig;
var localModulesConfig = __fbBatchedBridgeConfig.localModulesConfig;
var BatchedBridge = BatchedBridgeFactory.create(
MessageQueue,
remoteModulesConfig,
localModulesConfig
);
BatchedBridge._config = remoteModulesConfig;
module.exports = BatchedBridge;
});
__d('BatchedBridgeFactory',["invariant","keyMirror","mapObject","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 BatchedBridgeFactory
*/
'use strict';
var invariant = require('invariant');
var keyMirror = require('keyMirror');
var mapObject = require('mapObject');
var warning = require('warning');
var slice = Array.prototype.slice;
var MethodTypes = keyMirror({
remote: null,
local: null,
});
/**
* Creates remotely invokable modules.
*/
var BatchedBridgeFactory = {
MethodTypes: MethodTypes,
/**
* @param {MessageQueue} messageQueue Message queue that has been created with
* the `moduleConfig` (among others perhaps).
* @param {object} moduleConfig Configuration of module names/method
* names to callback types.
* @return {object} Remote representation of configured module.
*/
_createBridgedModule: function(messageQueue, moduleConfig, moduleName) {
var remoteModule = mapObject(moduleConfig.methods, function(methodConfig, memberName) {
return methodConfig.type === MethodTypes.local ? null : function() {
var lastArg = arguments.length > 0 ? arguments[arguments.length - 1] : null;
var secondLastArg = arguments.length > 1 ? arguments[arguments.length - 2] : null;
var hasSuccCB = typeof lastArg === 'function';
var hasErrorCB = typeof secondLastArg === 'function';
hasErrorCB && invariant(
hasSuccCB,
'Cannot have a non-function arg after a function arg.'
);
var numCBs = (hasSuccCB ? 1 : 0) + (hasErrorCB ? 1 : 0);
var args = slice.call(arguments, 0, arguments.length - numCBs);
var onSucc = hasSuccCB ? lastArg : null;
var onFail = hasErrorCB ? secondLastArg : null;
return messageQueue.call(moduleName, memberName, args, onFail, onSucc);
};
});
for (var constName in moduleConfig.constants) {
warning(!remoteModule[constName], 'saw constant and method named %s', constName);
remoteModule[constName] = moduleConfig.constants[constName];
}
return remoteModule;
},
create: function(MessageQueue, modulesConfig, localModulesConfig) {
var messageQueue = new MessageQueue(modulesConfig, localModulesConfig);
return {
callFunction: messageQueue.callFunction.bind(messageQueue),
callFunctionReturnFlushedQueue:
messageQueue.callFunctionReturnFlushedQueue.bind(messageQueue),
invokeCallback: messageQueue.invokeCallback.bind(messageQueue),
invokeCallbackAndReturnFlushedQueue:
messageQueue.invokeCallbackAndReturnFlushedQueue.bind(messageQueue),
flushedQueue: messageQueue.flushedQueue.bind(messageQueue),
RemoteModules: mapObject(modulesConfig, this._createBridgedModule.bind(this, messageQueue)),
setLoggingEnabled: messageQueue.setLoggingEnabled.bind(messageQueue),
getLoggedOutgoingItems: messageQueue.getLoggedOutgoingItems.bind(messageQueue),
getLoggedIncomingItems: messageQueue.getLoggedIncomingItems.bind(messageQueue),
replayPreviousLog: messageQueue.replayPreviousLog.bind(messageQueue),
processBatch: messageQueue.processBatch.bind(messageQueue),
};
}
};
module.exports = BatchedBridgeFactory;
});
__d('mapObject',[],function(global, require, requireDynamic, requireLazy, 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;
});
__d('MessageQueue',["ErrorUtils","ReactUpdates","invariant","warning","JSTimersExecution"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 MessageQueue
* @flow
*/
'use strict';
var ErrorUtils = require('ErrorUtils');
var ReactUpdates = require('ReactUpdates');
var invariant = require('invariant');
var warning = require('warning');
var JSTimersExecution = require('JSTimersExecution');
var INTERNAL_ERROR = 'Error in MessageQueue implementation';
// Prints all bridge traffic to console.log
var DEBUG_SPY_MODE = false;
/**
* So as not to confuse static build system.
*/
var requireFunc = require;
/**
* @param {Object!} module Module instance, must be loaded.
* @param {string} methodName Name of method in `module`.
* @param {array<*>} params Arguments to method.
* @returns {*} Return value of method invocation.
*/
var jsCall = function(module, methodName, params) {
return module[methodName].apply(module, params);
};
/**
* A utility for aggregating "work" to be done, and potentially transferring
* that work to another thread. Each instance of `MessageQueue` has the notion
* of a "target" thread - the thread that the work will be sent to.
*
* TODO: Long running callback results, and streaming callback results (ability
* for a callback to be invoked multiple times).
*
* @param {object} moduleNameToID Used to translate module/method names into
* efficient numeric IDs.
* @class MessageQueue
*/
var MessageQueue = function(
remoteModulesConfig ,
localModulesConfig ,
customRequire
) {
this._requireFunc = customRequire || requireFunc;
this._initBookeeping();
this._initNamingMap(remoteModulesConfig, localModulesConfig);
};
// REQUEST: Parallell arrays:
var REQUEST_MODULE_IDS = 0;
var REQUEST_METHOD_IDS = 1;
var REQUEST_PARAMSS = 2;
// RESPONSE: Parallell arrays:
var RESPONSE_CBIDS = 3;
var RESPONSE_RETURN_VALUES = 4;
/**
* Utility to catch errors and prevent having to bind, or execute a bound
* function, while catching errors in a process and returning a resulting
* return value. This ensures that even if a process fails, we can still return
* *some* values (from `_flushedQueueUnguarded` for example). Glorified
* try/catch/finally that invokes the global `onerror`.
*
* @param {function} operation Function to execute, likely populates the
* message buffer.
* @param {Array<*>} operationArguments Arguments passed to `operation`.
* @param {function} getReturnValue Returns a return value - will be invoked
* even if the `operation` fails half way through completing its task.
* @return {object} Return value returned from `getReturnValue`.
*/
var guardReturn = function(operation, operationArguments, getReturnValue, context) {
if (operation) {
ErrorUtils.applyWithGuard(operation, context, operationArguments);
}
if (getReturnValue) {
return ErrorUtils.applyWithGuard(getReturnValue, context, null);
}
return null;
};
/**
* Bookkeeping logic for callbackIDs. We ensure that success and error
* callbacks are numerically adjacent.
*
* We could have also stored the association between success cbID and errorCBID
* in a map without relying on this adjacency, but the bookkeeping here avoids
* an additional two maps to associate in each direction, and avoids growing
* dictionaries (new fields). Instead, we compute pairs of callback IDs, by
* populating the `res` argument to `allocateCallbackIDs` (in conjunction with
* pooling). Behind this bookeeping API, we ensure that error and success
* callback IDs are always adjacent so that when one is invoked, we always know
* how to free the memory of the other. By using this API, it is impossible to
* create malformed callbackIDs that are not adjacent.
*/
var createBookkeeping = function() {
return {
/**
* Incrementing callback ID. Must start at 1 - otherwise converted null
* values which become zero are not distinguishable from a GUID of zero.
*/
GUID: 1,
errorCallbackIDForSuccessCallbackID: function(successID) {
return successID + 1;
},
successCallbackIDForErrorCallbackID: function(errorID) {
return errorID - 1;
},
allocateCallbackIDs: function(res) {
res.successCallbackID = this.GUID++;
res.errorCallbackID = this.GUID++;
},
isSuccessCallback: function(id) {
return id % 2 === 1;
}
};
};
var MessageQueueMixin = {
/**
* Creates an efficient wire protocol for communicating across a bridge.
* Avoids allocating strings.
*
* @param {object} remoteModulesConfig Configuration of modules and their
* methods.
*/
_initNamingMap: function(
remoteModulesConfig ,
localModulesConfig
) {
this._remoteModuleNameToModuleID = {};
this._remoteModuleIDToModuleName = {}; // Reverse
this._remoteModuleNameToMethodNameToID = {};
this._remoteModuleNameToMethodIDToName = {}; // Reverse
this._localModuleNameToModuleID = {};
this._localModuleIDToModuleName = {}; // Reverse
this._localModuleNameToMethodNameToID = {};
this._localModuleNameToMethodIDToName = {}; // Reverse
function fillMappings(
modulesConfig ,
moduleNameToModuleID ,
moduleIDToModuleName ,
moduleNameToMethodNameToID ,
moduleNameToMethodIDToName
) {
for (var moduleName in modulesConfig) {
var moduleConfig = modulesConfig[moduleName];
var moduleID = moduleConfig.moduleID;
moduleNameToModuleID[moduleName] = moduleID;
moduleIDToModuleName[moduleID] = moduleName; // Reverse
moduleNameToMethodNameToID[moduleName] = {};
moduleNameToMethodIDToName[moduleName] = {}; // Reverse
var methods = moduleConfig.methods;
for (var methodName in methods) {
var methodID = methods[methodName].methodID;
moduleNameToMethodNameToID[moduleName][methodName] =
methodID;
moduleNameToMethodIDToName[moduleName][methodID] =
methodName; // Reverse
}
}
}
fillMappings(
remoteModulesConfig,
this._remoteModuleNameToModuleID,
this._remoteModuleIDToModuleName,
this._remoteModuleNameToMethodNameToID,
this._remoteModuleNameToMethodIDToName
);
fillMappings(
localModulesConfig,
this._localModuleNameToModuleID,
this._localModuleIDToModuleName,
this._localModuleNameToMethodNameToID,
this._localModuleNameToMethodIDToName
);
},
_initBookeeping: function() {
this._POOLED_CBIDS = {errorCallbackID: null, successCallbackID: null};
this._bookkeeping = createBookkeeping();
/**
* Stores callbacks so that we may simulate asynchronous return values from
* other threads. Remote invocations in other threads can pass return values
* back asynchronously to the requesting thread.
*/
this._threadLocalCallbacksByID = [];
this._threadLocalScopesByID = [];
/**
* Memory efficient parallel arrays. Each index cuts through the three
* arrays and forms a remote invocation of methodName(params) whos return
* value will be reported back to the other thread by way of the
* corresponding id in cbIDs. Each entry (A-D in the graphic below),
* represents a work item of the following form:
* - moduleID: ID of module to invoke method from.
* - methodID: ID of method in module to invoke.
* - params: List of params to pass to method.
* - cbID: ID to respond back to originating thread with.
*
* TODO: We can make this even more efficient (memory) by creating a single
* array, that is always pushed `n` elements as a time.
*/
this._outgoingItems = [
/*REQUEST_MODULE_IDS: */ [/* +-+ +-+ +-+ +-+ */],
/*REQUEST_METHOD_IDS: */ [/* |A| |B| |C| |D| */],
/*REQUEST_PARAMSS: */ [/* |-| |-| |-| |-| */],
/*RESPONSE_CBIDS: */ [/* +-+ +-+ +-+ +-+ */],
/* |E| |F| |G| |H| */
/*RESPONSE_RETURN_VALUES: */ [/* +-+ +-+ +-+ +-+ */]
];
/**
* Used to allow returning the buffer, while at the same time clearing it in
* a memory efficient manner.
*/
this._outgoingItemsSwap = [[], [], [], [], []];
},
invokeCallback: function(cbID, args) {
return guardReturn(this._invokeCallback, [cbID, args], null, this);
},
_invokeCallback: function(cbID, args) {
try {
var cb = this._threadLocalCallbacksByID[cbID];
var scope = this._threadLocalScopesByID[cbID];
warning(
cb,
'Cannot find callback with CBID %s. Native module may have invoked ' +
'both the success callback and the error callback.',
cbID
);
if (DEBUG_SPY_MODE) {
console.log('N->JS: Callback#' + cbID + '(' + JSON.stringify(args) + ')');
}
cb.apply(scope, args);
} catch(ie_requires_catch) {
throw ie_requires_catch;
} finally {
// Clear out the memory regardless of success or failure.
this._freeResourcesForCallbackID(cbID);
}
},
invokeCallbackAndReturnFlushedQueue: function(cbID, args) {
if (this._enableLogging) {
this._loggedIncomingItems.push([new Date().getTime(), cbID, args]);
}
return guardReturn(
this._invokeCallback,
[cbID, args],
this._flushedQueueUnguarded,
this
);
},
callFunction: function(moduleID, methodID, params) {
return guardReturn(this._callFunction, [moduleID, methodID, params], null, this);
},
_callFunction: function(moduleID, methodID, params) {
var moduleName = this._localModuleIDToModuleName[moduleID];
var methodName = this._localModuleNameToMethodIDToName[moduleName][methodID];
if (DEBUG_SPY_MODE) {
console.log(
'N->JS: ' + moduleName + '.' + methodName +
'(' + JSON.stringify(params) + ')');
}
var ret = jsCall(this._requireFunc(moduleName), methodName, params);
return ret;
},
callFunctionReturnFlushedQueue: function(moduleID, methodID, params) {
if (this._enableLogging) {
this._loggedIncomingItems.push([new Date().getTime(), moduleID, methodID, params]);
}
return guardReturn(
this._callFunction,
[moduleID, methodID, params],
this._flushedQueueUnguarded,
this
);
},
processBatch: function(batch) {
var self = this;
return guardReturn(function () {
ReactUpdates.batchedUpdates(function() {
batch.forEach(function(call) {
invariant(
call.module === 'BatchedBridge',
'All the calls should pass through the BatchedBridge module'
);
if (call.method === 'callFunctionReturnFlushedQueue') {
self._callFunction.apply(self, call.args);
} else if (call.method === 'invokeCallbackAndReturnFlushedQueue') {
self._invokeCallback.apply(self, call.args);
} else {
throw new Error(
'Unrecognized method called on BatchedBridge: ' + call.method);
}
});
});
}, null, this._flushedQueueUnguarded, this);
},
setLoggingEnabled: function(enabled) {
this._enableLogging = enabled;
this._loggedIncomingItems = [];
this._loggedOutgoingItems = [[], [], [], [], []];
},
getLoggedIncomingItems: function() {
return this._loggedIncomingItems;
},
getLoggedOutgoingItems: function() {
return this._loggedOutgoingItems;
},
replayPreviousLog: function(previousLog) {
this._outgoingItems = previousLog;
},
/**
* Simple helpers for clearing the queues. This doesn't handle the fact that
* memory in the current buffer is leaked until the next frame or update - but
* that will typically be on the order of < 500ms.
*/
_swapAndReinitializeBuffer: function() {
// Outgoing requests
var currentOutgoingItems = this._outgoingItems;
var nextOutgoingItems = this._outgoingItemsSwap;
nextOutgoingItems[REQUEST_MODULE_IDS].length = 0;
nextOutgoingItems[REQUEST_METHOD_IDS].length = 0;
nextOutgoingItems[REQUEST_PARAMSS].length = 0;
// Outgoing responses
nextOutgoingItems[RESPONSE_CBIDS].length = 0;
nextOutgoingItems[RESPONSE_RETURN_VALUES].length = 0;
this._outgoingItemsSwap = currentOutgoingItems;
this._outgoingItems = nextOutgoingItems;
},
/**
* @param {string} moduleID JS module name.
* @param {methodName} methodName Method in module to invoke.
* @param {array<*>?} params Array representing arguments to method.
* @param {string} cbID Unique ID to pass back in potential response.
*/
_pushRequestToOutgoingItems: function(moduleID, methodName, params) {
this._outgoingItems[REQUEST_MODULE_IDS].push(moduleID);
this._outgoingItems[REQUEST_METHOD_IDS].push(methodName);
this._outgoingItems[REQUEST_PARAMSS].push(params);
if (this._enableLogging) {
this._loggedOutgoingItems[REQUEST_MODULE_IDS].push(moduleID);
this._loggedOutgoingItems[REQUEST_METHOD_IDS].push(methodName);
this._loggedOutgoingItems[REQUEST_PARAMSS].push(params);
}
},
/**
* @param {string} cbID Unique ID that other side of bridge has remembered.
* @param {*} returnValue Return value to pass to callback on other side of
* bridge.
*/
_pushResponseToOutgoingItems: function(cbID, returnValue) {
this._outgoingItems[RESPONSE_CBIDS].push(cbID);
this._outgoingItems[RESPONSE_RETURN_VALUES].push(returnValue);
},
_freeResourcesForCallbackID: function(cbID) {
var correspondingCBID = this._bookkeeping.isSuccessCallback(cbID) ?
this._bookkeeping.errorCallbackIDForSuccessCallbackID(cbID) :
this._bookkeeping.successCallbackIDForErrorCallbackID(cbID);
this._threadLocalCallbacksByID[cbID] = null;
this._threadLocalScopesByID[cbID] = null;
if (this._threadLocalCallbacksByID[correspondingCBID]) {
this._threadLocalCallbacksByID[correspondingCBID] = null;
this._threadLocalScopesByID[correspondingCBID] = null;
}
},
/**
* @param {Function} onFail Function to store in current thread for later
* lookup, when request fails.
* @param {Function} onSucc Function to store in current thread for later
* lookup, when request succeeds.
* @param {Object?=} scope Scope to invoke `cb` with.
* @param {Object?=} res Resulting callback ids. Use `this._POOLED_CBIDS`.
*/
_storeCallbacksInCurrentThread: function(onFail, onSucc, scope) {
invariant(onFail || onSucc, INTERNAL_ERROR);
this._bookkeeping.allocateCallbackIDs(this._POOLED_CBIDS);
var succCBID = this._POOLED_CBIDS.successCallbackID;
var errorCBID = this._POOLED_CBIDS.errorCallbackID;
this._threadLocalCallbacksByID[errorCBID] = onFail;
this._threadLocalCallbacksByID[succCBID] = onSucc;
this._threadLocalScopesByID[errorCBID] = scope;
this._threadLocalScopesByID[succCBID] = scope;
},
/**
* IMPORTANT: There is possibly a timing issue with this form of flushing. We
* are currently not seeing any problems but the potential issue to look out
* for is:
* - While flushing this._outgoingItems contains the work for the other thread
* to perform.
* - To mitigate this, we never allow enqueueing messages if the queue is
* already reserved - as long as it is reserved, it could be in the midst of
* a flush.
*
* If this ever occurs we can easily eliminate the race condition. We can
* completely solve any ambiguity by sending messages such that we'll never
* try to reserve the queue when already reserved. Here's the pseudocode:
*
* var defensiveCopy = efficientDefensiveCopy(this._outgoingItems);
* this._swapAndReinitializeBuffer();
*/
flushedQueue: function() {
return guardReturn(null, null, this._flushedQueueUnguarded, this);
},
_flushedQueueUnguarded: function() {
// Call the functions registred via setImmediate
JSTimersExecution.callImmediates();
var currentOutgoingItems = this._outgoingItems;
this._swapAndReinitializeBuffer();
var ret = currentOutgoingItems[REQUEST_MODULE_IDS].length ||
currentOutgoingItems[RESPONSE_RETURN_VALUES].length ? currentOutgoingItems : null;
if (DEBUG_SPY_MODE && ret) {
for (var i = 0; i < currentOutgoingItems[0].length; i++) {
var moduleName = this._remoteModuleIDToModuleName[currentOutgoingItems[0][i]];
var methodName =
this._remoteModuleNameToMethodIDToName[moduleName][currentOutgoingItems[1][i]];
console.log(
'JS->N: ' + moduleName + '.' + methodName +
'(' + JSON.stringify(currentOutgoingItems[2][i]) + ')');
}
}
return ret;
},
call: function(moduleName, methodName, params, onFail, onSucc, scope) {
invariant(
(!onFail || typeof onFail === 'function') &&
(!onSucc || typeof onSucc === 'function'),
'Callbacks must be functions'
);
// Store callback _before_ sending the request, just in case the MailBox
// returns the response in a blocking manner.
if (onSucc) {
this._storeCallbacksInCurrentThread(onFail, onSucc, scope, this._POOLED_CBIDS);
onFail && params.push(this._POOLED_CBIDS.errorCallbackID);
params.push(this._POOLED_CBIDS.successCallbackID);
}
var moduleID = this._remoteModuleNameToModuleID[moduleName];
if (moduleID === undefined || moduleID === null) {
throw new Error('Unrecognized module name:' + moduleName);
}
var methodID = this._remoteModuleNameToMethodNameToID[moduleName][methodName];
if (methodID === undefined || moduleID === null) {
throw new Error('Unrecognized method name:' + methodName);
}
this._pushRequestToOutgoingItems(moduleID, methodID, params);
},
__numPendingCallbacksOnlyUseMeInTestCases: function() {
var callbacks = this._threadLocalCallbacksByID;
var total = 0;
for (var i = 0; i < callbacks.length; i++) {
if (callbacks[i]) {
total++;
}
}
return total;
}
};
Object.assign(MessageQueue.prototype, MessageQueueMixin);
module.exports = MessageQueue;
});
__d('JSTimersExecution',["invariant","keyMirror","performanceNow","warning","JSTimers","JSTimers"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 JSTimersExecution
*/
'use strict';
var invariant = require('invariant');
var keyMirror = require('keyMirror');
var performanceNow = require('performanceNow');
var warning = require('warning');
/**
* JS implementation of timer functions. Must be completely driven by an
* external clock signal, all that's stored here is timerID, timer type, and
* callback.
*/
var JSTimersExecution = {
GUID: 1,
Type: keyMirror({
setTimeout: null,
setInterval: null,
requestAnimationFrame: null,
setImmediate: null,
}),
// Parallel arrays:
callbacks: [],
types: [],
timerIDs: [],
immediates: [],
/**
* Calls the callback associated with the ID. Also unregister that callback
* if it was a one time timer (setTimeout), and not unregister it if it was
* recurring (setInterval).
*/
callTimer: function(timerID) {
warning(timerID <= JSTimersExecution.GUID, 'Tried to call timer with ID ' + timerID + ' but no such timer exists');
var timerIndex = JSTimersExecution.timerIDs.indexOf(timerID);
// timerIndex of -1 means that no timer with that ID exists. There are
// two situations when this happens, when a garbage timer ID was given
// and when a previously existing timer was deleted before this callback
// fired. In both cases we want to ignore the timer id, but in the former
// case we warn as well.
if (timerIndex === -1) {
return;
}
var type = JSTimersExecution.types[timerIndex];
var callback = JSTimersExecution.callbacks[timerIndex];
// Clear the metadata
if (type === JSTimersExecution.Type.setTimeout ||
type === JSTimersExecution.Type.setImmediate ||
type === JSTimersExecution.Type.requestAnimationFrame) {
JSTimersExecution._clearIndex(timerIndex);
}
try {
if (type === JSTimersExecution.Type.setTimeout ||
type === JSTimersExecution.Type.setInterval ||
type === JSTimersExecution.Type.setImmediate) {
callback();
} else if (type === JSTimersExecution.Type.requestAnimationFrame) {
var currentTime = performanceNow();
callback(currentTime);
} else {
console.error('Tried to call a callback with invalid type: ' + type);
return;
}
} catch (e) {
// Don't rethrow so that we can run every other timer.
JSTimersExecution.errors = JSTimersExecution.errors || [];
JSTimersExecution.errors.push(e);
}
},
/**
* This is called from the native side. We are passed an array of timerIDs,
* and
*/
callTimers: function(timerIDs) {
invariant(timerIDs.length !== 0, 'Probably shouldn\'t call "callTimers" with no timerIDs');
JSTimersExecution.errors = null;
timerIDs.forEach(JSTimersExecution.callTimer);
var errors = JSTimersExecution.errors;
if (errors) {
var errorCount = errors.length;
if (errorCount > 1) {
// Throw all the other errors in a setTimeout, which will throw each
// error one at a time
for (var ii = 1; ii < errorCount; ii++) {
require('JSTimers').setTimeout(
(function(error) { throw error; }).bind(null, errors[ii]),
0
);
}
}
throw errors[0];
}
},
/**
* This is called after we execute any command we receive from native but
* before we hand control back to native.
*/
callImmediates: function() {
JSTimersExecution.errors = null;
while (JSTimersExecution.immediates.length !== 0) {
JSTimersExecution.callTimer(JSTimersExecution.immediates.shift());
}
if (JSTimersExecution.errors) {
JSTimersExecution.errors.forEach(function(error)
{return require('JSTimers').setTimeout(function() { throw error; }, 0);}
);
}
},
_clearIndex: function(i) {
JSTimersExecution.timerIDs[i] = null;
JSTimersExecution.callbacks[i] = null;
JSTimersExecution.types[i] = null;
},
};
module.exports = JSTimersExecution;
});
__d('performanceNow',["performance"],function(global, require, requireDynamic, requireLazy, 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;
});
__d('performance',["ExecutionEnvironment"],function(global, require, requireDynamic, requireLazy, 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 || {};
});
__d('ExecutionEnvironment',[],function(global, require, requireDynamic, requireLazy, 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;
});
__d('JSTimers',["NativeModules","JSTimersExecution"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 JSTimers
*/
'use strict';
// Note that the module JSTimers is split into two in order to solve a cycle
// in dependencies. NativeModules > BatchedBridge > MessageQueue > JSTimersExecution
var RCTTiming = require('NativeModules').Timing;
var JSTimersExecution = require('JSTimersExecution');
/**
* JS implementation of timer functions. Must be completely driven by an
* external clock signal, all that's stored here is timerID, timer type, and
* callback.
*/
var JSTimers = {
Types: JSTimersExecution.Types,
/**
* Returns a free index if one is available, and the next consecutive index
* otherwise.
*/
_getFreeIndex: function() {
var freeIndex = JSTimersExecution.timerIDs.indexOf(null);
if (freeIndex === -1) {
freeIndex = JSTimersExecution.timerIDs.length;
}
return freeIndex;
},
/**
* @param {function} func Callback to be invoked after `duration` ms.
* @param {number} duration Number of milliseconds.
*/
setTimeout: function(func, duration ) {for (var args=[],$__0=2,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]);
var newID = JSTimersExecution.GUID++;
var freeIndex = JSTimers._getFreeIndex();
JSTimersExecution.timerIDs[freeIndex] = newID;
JSTimersExecution.callbacks[freeIndex] = func;
JSTimersExecution.callbacks[freeIndex] = function() {
return func.apply(undefined, args);
};
JSTimersExecution.types[freeIndex] = JSTimersExecution.Type.setTimeout;
RCTTiming.createTimer(newID, duration, Date.now(), /** recurring */ false);
return newID;
},
/**
* @param {function} func Callback to be invoked every `duration` ms.
* @param {number} duration Number of milliseconds.
*/
setInterval: function(func, duration ) {for (var args=[],$__0=2,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]);
var newID = JSTimersExecution.GUID++;
var freeIndex = JSTimers._getFreeIndex();
JSTimersExecution.timerIDs[freeIndex] = newID;
JSTimersExecution.callbacks[freeIndex] = func;
JSTimersExecution.callbacks[freeIndex] = function() {
return func.apply(undefined, args);
};
JSTimersExecution.types[freeIndex] = JSTimersExecution.Type.setInterval;
RCTTiming.createTimer(newID, duration, Date.now(), /** recurring */ true);
return newID;
},
/**
* @param {function} func Callback to be invoked before the end of the
* current JavaScript execution loop.
*/
setImmediate: function(func ) {for (var args=[],$__0=1,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]);
var newID = JSTimersExecution.GUID++;
var freeIndex = JSTimers._getFreeIndex();
JSTimersExecution.timerIDs[freeIndex] = newID;
JSTimersExecution.callbacks[freeIndex] = func;
JSTimersExecution.callbacks[freeIndex] = function() {
return func.apply(undefined, args);
};
JSTimersExecution.types[freeIndex] = JSTimersExecution.Type.setImmediate;
JSTimersExecution.immediates.push(newID);
return newID;
},
/**
* @param {function} func Callback to be invoked every frame.
*/
requestAnimationFrame: function(func) {
var newID = JSTimersExecution.GUID++;
var freeIndex = JSTimers._getFreeIndex();
JSTimersExecution.timerIDs[freeIndex] = newID;
JSTimersExecution.callbacks[freeIndex] = func;
JSTimersExecution.types[freeIndex] = JSTimersExecution.Type.requestAnimationFrame;
RCTTiming.createTimer(newID, 1, Date.now(), /** recurring */ false);
return newID;
},
clearTimeout: function(timerID) {
JSTimers._clearTimerID(timerID);
},
clearInterval: function(timerID) {
JSTimers._clearTimerID(timerID);
},
clearImmediate: function(timerID) {
JSTimers._clearTimerID(timerID);
JSTimersExecution.immediates.splice(
JSTimersExecution.immediates.indexOf(timerID),
1
);
},
cancelAnimationFrame: function(timerID) {
JSTimers._clearTimerID(timerID);
},
_clearTimerID: function(timerID) {
// JSTimersExecution.timerIDs contains nulls after timers have been removed;
// ignore nulls upfront so indexOf doesn't find them
if (timerID == null) {
return;
}
var index = JSTimersExecution.timerIDs.indexOf(timerID);
// See corresponding comment in `callTimers` for reasoning behind this
if (index !== -1) {
JSTimersExecution._clearIndex(index);
if (JSTimersExecution.types[index] !== JSTimersExecution.Type.setImmediate) {
RCTTiming.deleteTimer(timerID);
}
}
},
};
module.exports = JSTimers;
});
__d('nativeModulePrefixNormalizer',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 nativeModulePrefixNormalizer
* @flow
*/
'use strict';
// Dirty hack to support old (RK) and new (RCT) native module name conventions
function nativeModulePrefixNormalizer(
modules
) {
Object.keys(modules).forEach(function(moduleName) {
var strippedName = moduleName.replace(/^(RCT|RK)/, '');
if (modules['RCT' + strippedName] && modules['RK' + strippedName]) {
throw new Error(
'Module cannot be registered as both RCT and RK: ' + moduleName
);
}
if (strippedName !== moduleName) {
modules[strippedName] = modules[moduleName];
delete modules[moduleName];
}
});
}
module.exports = nativeModulePrefixNormalizer;
});
__d('loadSourceMap',["Promise","NativeModules","SourceMap","react-native/Libraries/JavaScriptAppEngine/Initialization/source-map-url"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 loadSourceMap
* @flow
*/
'use strict';
var Promise = require('Promise');
var RCTSourceCode = require('NativeModules').SourceCode;
var SourceMapConsumer = require('SourceMap').SourceMapConsumer;
var SourceMapURL = require('react-native/Libraries/JavaScriptAppEngine/Initialization/source-map-url');
function loadSourceMap() {
return fetchSourceMap()
.then(function(map) {return new SourceMapConsumer(map);});
}
function fetchSourceMap() {
if (global.RAW_SOURCE_MAP) {
return Promise.resolve(global.RAW_SOURCE_MAP);
}
if (!RCTSourceCode) {
return Promise.reject(new Error('RCTSourceCode module is not available'));
}
return new Promise(RCTSourceCode.getScriptText)
.then(extractSourceMapURL)
.then(fetch)
.then(function(response) {return response.text();})
}
function extractSourceMapURL($__0 ) {var url=$__0.url,text=$__0.text,fullSourceMappingURL=$__0.fullSourceMappingURL;
if (fullSourceMappingURL) {
return fullSourceMappingURL;
}
var mapURL = SourceMapURL.getFrom(text);
var baseURL = url.match(/(.+:\/\/.*?)\//)[1];
return baseURL + mapURL;
}
module.exports = loadSourceMap;
});
__d('Promise',["setImmediate","promise/setimmediate/es6-extensions","promise/setimmediate/done"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
*
* Copyright 2013-2014 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 Promise
*
* This module wraps and augments the minimally ES6-compliant Promise
* implementation provided by the promise npm package.
*/
'use strict';
global.setImmediate = require('setImmediate');
var Promise = require('promise/setimmediate/es6-extensions');
require('promise/setimmediate/done');
/**
* Handle either fulfillment or rejection with the same callback.
*/
Promise.prototype["finally"] = function(onSettled) {
return this.then(onSettled, onSettled);
};
module.exports = Promise;
});
__d('setImmediate',["ImmediateImplementation"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* @generated SignedSource<<9715e66cd259f4d1a1c3d39c97cd0b92>>
*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* !! This file is a check-in of a static_upstream project! !!
* !! !!
* !! You should not modify this file directly. Instead: !!
* !! 1) Use `fjs use-upstream` to temporarily replace this with !!
* !! the latest version from upstream. !!
* !! 2) Make your changes, test them, etc. !!
* !! 3) Use `fjs push-upstream` to copy your changes back to !!
* !! static_upstream. !!
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
* @providesModule setImmediate
*/
module.exports = global.setImmediate ||
require('ImmediateImplementation').setImmediate;
});
__d('ImmediateImplementation',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* @generated SignedSource<<57d0446bbd1186485d372efe6b323dca>>
*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* !! This file is a check-in of a static_upstream project! !!
* !! !!
* !! You should not modify this file directly. Instead: !!
* !! 1) Use `fjs use-upstream` to temporarily replace this with !!
* !! the latest version from upstream. !!
* !! 2) Make your changes, test them, etc. !!
* !! 3) Use `fjs push-upstream` to copy your changes back to !!
* !! static_upstream. !!
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
* Copyright (c) 2012 Barnesandnoble.com, llc, Donavon West, and Domenic
* Denicola
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* @preserve-header
* @providesModule ImmediateImplementation
*/
(function(global, undefined) {
"use strict";
var nextHandle = 1; // Spec says greater than zero
var tasksByHandle = {};
var queueHead = {};
var queueTail = queueHead;
var currentlyRunningATask = false;
var doc = global.document;
var setImmediate;
function addFromSetImmediateArguments(args) {
var handler = args[0];
args = Array.prototype.slice.call(args, 1);
tasksByHandle[nextHandle] = function() {
handler.apply(undefined, args);
};
queueTail = (queueTail.next = { handle: nextHandle++ });
return queueTail.handle;
}
function flushQueue() {
var next, task;
while (!currentlyRunningATask && (next = queueHead.next)) {
queueHead = next; // If this task fails, don't retry it.
if ((task = tasksByHandle[next.handle])) {
currentlyRunningATask = true;
try {
task();
currentlyRunningATask = false;
} finally {
clearImmediate(next.handle);
if (currentlyRunningATask) {
currentlyRunningATask = false;
// The call to task() must have thrown an
// exception if we reach this point, so, just in
// case there are tasks remaining to be executed,
// we schedule another flushQueue in a later tick
// of the event loop, and let the exception
// propagate uncaught.
if (queueHead.next) {
setImmediate(flushQueue);
}
}
}
}
}
}
function clearImmediate(handle) {
delete tasksByHandle[handle];
}
function canUsePostMessage() {
// The test against `importScripts` prevents this implementation from being installed inside a web worker,
// where `global.postMessage` means something completely different and can't be used for this purpose.
if (global.postMessage && !global.importScripts) {
var postMessageIsAsynchronous = true;
var onMessage = function() {
postMessageIsAsynchronous = false;
if (global.removeEventListener) {
global.removeEventListener("message", onMessage, false);
} else {
global.detachEvent("onmessage", onMessage);
}
};
if (global.addEventListener) {
global.addEventListener("message", onMessage, false);
} else if (global.attachEvent) {
global.attachEvent("onmessage", onMessage);
} else {
return false;
}
global.postMessage("", "*");
return postMessageIsAsynchronous;
}
}
function installPostMessageImplementation() {
// Installs an event handler on `global` for the `message` event: see
// * https://developer.mozilla.org/en/DOM/window.postMessage
var messagePrefix = "setImmediate$" + Math.random() + "$";
var onGlobalMessage = function(event) {
if (event.source === global &&
typeof event.data === "string" &&
event.data.indexOf(messagePrefix) === 0) {
flushQueue();
}
};
if (global.addEventListener) {
global.addEventListener("message", onGlobalMessage, false);
} else {
global.attachEvent("onmessage", onGlobalMessage);
}
setImmediate = function() {
var handle = addFromSetImmediateArguments(arguments);
global.postMessage(messagePrefix + handle, "*");
return handle;
};
}
function installMessageChannelImplementation() {
var channel = new MessageChannel();
channel.port1.onmessage = flushQueue;
setImmediate = function() {
var handle = addFromSetImmediateArguments(arguments);
channel.port2.postMessage(handle);
return handle;
};
}
function installReadyStateChangeImplementation() {
var html = doc.documentElement;
setImmediate = function() {
var handle = addFromSetImmediateArguments(arguments);
// Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
// into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
var script = doc.createElement("script");
script.onreadystatechange = function () {
script.onreadystatechange = null;
html.removeChild(script);
script = null;
flushQueue();
};
html.appendChild(script);
return handle;
};
}
function installSetTimeoutImplementation() {
setImmediate = function() {
setTimeout(flushQueue, 0);
return addFromSetImmediateArguments(arguments);
};
}
if (canUsePostMessage()) {
// For non-IE10 modern browsers
installPostMessageImplementation();
} else if (global.MessageChannel) {
// For web workers, where supported
installMessageChannelImplementation();
} else if (doc && "onreadystatechange" in doc.createElement("script")) {
// For IE 6-8
installReadyStateChangeImplementation();
} else {
// For older browsers
installSetTimeoutImplementation();
}
exports.setImmediate = setImmediate;
exports.clearImmediate = clearImmediate;
}(/* jslint evil: true */ Function("return this")()));
});
__d('promise/setimmediate/es6-extensions',["promise/setimmediate/core"],function(global, require, requireDynamic, requireLazy, module, exports) { 'use strict';
//This file contains the ES6 extensions to the core Promises/A+ API
var Promise = require('promise/setimmediate/core');
module.exports = Promise;
/* Static Functions */
var TRUE = valuePromise(true);
var FALSE = valuePromise(false);
var NULL = valuePromise(null);
var UNDEFINED = valuePromise(undefined);
var ZERO = valuePromise(0);
var EMPTYSTRING = valuePromise('');
function valuePromise(value) {
var p = new Promise(Promise._83);
p._32 = 1;
p._8 = value;
return p;
}
Promise.resolve = function (value) {
if (value instanceof Promise) return value;
if (value === null) return NULL;
if (value === undefined) return UNDEFINED;
if (value === true) return TRUE;
if (value === false) return FALSE;
if (value === 0) return ZERO;
if (value === '') return EMPTYSTRING;
if (typeof value === 'object' || typeof value === 'function') {
try {
var then = value.then;
if (typeof then === 'function') {
return new Promise(then.bind(value));
}
} catch (ex) {
return new Promise(function (resolve, reject) {
reject(ex);
});
}
}
return valuePromise(value);
};
Promise.all = function (arr) {
var args = Array.prototype.slice.call(arr);
return new Promise(function (resolve, reject) {
if (args.length === 0) return resolve([]);
var remaining = args.length;
function res(i, val) {
if (val && (typeof val === 'object' || typeof val === 'function')) {
if (val instanceof Promise && val.then === Promise.prototype.then) {
while (val._32 === 3) {
val = val._8;
}
if (val._32 === 1) return res(i, val._8);
if (val._32 === 2) reject(val._8);
val.then(function (val) {
res(i, val);
}, reject);
return;
} else {
var then = val.then;
if (typeof then === 'function') {
var p = new Promise(then.bind(val));
p.then(function (val) {
res(i, val);
}, reject);
return;
}
}
}
args[i] = val;
if (--remaining === 0) {
resolve(args);
}
}
for (var i = 0; i < args.length; i++) {
res(i, args[i]);
}
});
};
Promise.reject = function (value) {
return new Promise(function (resolve, reject) {
reject(value);
});
};
Promise.race = function (values) {
return new Promise(function (resolve, reject) {
values.forEach(function(value){
Promise.resolve(value).then(resolve, reject);
});
});
};
/* Prototype Methods */
Promise.prototype['catch'] = function (onRejected) {
return this.then(null, onRejected);
};
});
__d('promise/setimmediate/core',[],function(global, require, requireDynamic, requireLazy, module, exports) { 'use strict';
function noop() {}
// States:
//
// 0 - pending
// 1 - fulfilled with _value
// 2 - rejected with _value
// 3 - adopted the state of another promise, _value
//
// once the state is no longer pending (0) it is immutable
// All `_` prefixed properties will be reduced to `_{random number}`
// at build time to obfuscate them and discourage their use.
// We don't use symbols or Object.defineProperty to fully hide them
// because the performance isn't good enough.
// to avoid using try/catch inside critical functions, we
// extract them to here.
var LAST_ERROR = null;
var IS_ERROR = {};
function getThen(obj) {
try {
return obj.then;
} catch (ex) {
LAST_ERROR = ex;
return IS_ERROR;
}
}
function tryCallOne(fn, a) {
try {
return fn(a);
} catch (ex) {
LAST_ERROR = ex;
return IS_ERROR;
}
}
function tryCallTwo(fn, a, b) {
try {
fn(a, b);
} catch (ex) {
LAST_ERROR = ex;
return IS_ERROR;
}
}
module.exports = Promise;
function Promise(fn) {
if (typeof this !== 'object') {
throw new TypeError('Promises must be constructed via new');
}
if (typeof fn !== 'function') {
throw new TypeError('not a function');
}
this._32 = 0;
this._8 = null;
this._89 = [];
if (fn === noop) return;
doResolve(fn, this);
}
Promise._83 = noop;
Promise.prototype.then = function(onFulfilled, onRejected) {
if (this.constructor !== Promise) {
return safeThen(this, onFulfilled, onRejected);
}
var res = new Promise(noop);
handle(this, new Handler(onFulfilled, onRejected, res));
return res;
};
function safeThen(self, onFulfilled, onRejected) {
return new self.constructor(function (resolve, reject) {
var res = new Promise(noop);
res.then(resolve, reject);
handle(self, new Handler(onFulfilled, onRejected, res));
});
};
function handle(self, deferred) {
while (self._32 === 3) {
self = self._8;
}
if (self._32 === 0) {
self._89.push(deferred);
return;
}
setImmediate(function() {
var cb = self._32 === 1 ? deferred.onFulfilled : deferred.onRejected;
if (cb === null) {
if (self._32 === 1) {
resolve(deferred.promise, self._8);
} else {
reject(deferred.promise, self._8);
}
return;
}
var ret = tryCallOne(cb, self._8);
if (ret === IS_ERROR) {
reject(deferred.promise, LAST_ERROR);
} else {
resolve(deferred.promise, ret);
}
});
}
function resolve(self, newValue) {
// Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
if (newValue === self) {
return reject(
self,
new TypeError('A promise cannot be resolved with itself.')
);
}
if (
newValue &&
(typeof newValue === 'object' || typeof newValue === 'function')
) {
var then = getThen(newValue);
if (then === IS_ERROR) {
return reject(self, LAST_ERROR);
}
if (
then === self.then &&
newValue instanceof Promise
) {
self._32 = 3;
self._8 = newValue;
finale(self);
return;
} else if (typeof then === 'function') {
doResolve(then.bind(newValue), self);
return;
}
}
self._32 = 1;
self._8 = newValue;
finale(self);
}
function reject(self, newValue) {
self._32 = 2;
self._8 = newValue;
finale(self);
}
function finale(self) {
for (var i = 0; i < self._89.length; i++) {
handle(self, self._89[i]);
}
self._89 = null;
}
function Handler(onFulfilled, onRejected, promise){
this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
this.onRejected = typeof onRejected === 'function' ? onRejected : null;
this.promise = promise;
}
/**
* Take a potentially misbehaving resolver function and make sure
* onFulfilled and onRejected are only called once.
*
* Makes no guarantees about asynchrony.
*/
function doResolve(fn, promise) {
var done = false;
var res = tryCallTwo(fn, function (value) {
if (done) return;
done = true;
resolve(promise, value);
}, function (reason) {
if (done) return;
done = true;
reject(promise, reason);
})
if (!done && res === IS_ERROR) {
done = true;
reject(promise, LAST_ERROR);
}
}
});
__d('promise/setimmediate/done',["promise/setimmediate/core"],function(global, require, requireDynamic, requireLazy, module, exports) { 'use strict';
var Promise = require('promise/setimmediate/core');
module.exports = Promise;
Promise.prototype.done = function (onFulfilled, onRejected) {
var self = arguments.length ? this.then.apply(this, arguments) : this;
self.then(null, function (err) {
setTimeout(function () {
throw err;
}, 0);
});
};
});
__d('SourceMap',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 SourceMap
* @generated
*
* This module was generated from `node_modules/source-map` by running
*
* $ npm install dryice
* $ node Makefile.dryice.js
* $ cat dist/source-map.js
*
* and wrapping resulting file into `wrapper` function.
*
*/
var scope = {};
wrapper.call(scope);
module.exports = scope.sourceMap;
function wrapper() {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
/**
* Define a module along with a payload.
* @param {string} moduleName Name for the payload
* @param {ignored} deps Ignored. For compatibility with CommonJS AMD Spec
* @param {function} payload Function with (require, exports, module) params
*/
function define(moduleName, deps, payload) {
if (typeof moduleName != "string") {
throw new TypeError('Expected string, got: ' + moduleName);
}
if (arguments.length == 2) {
payload = deps;
}
if (moduleName in define.modules) {
throw new Error("Module already defined: " + moduleName);
}
define.modules[moduleName] = payload;
};
/**
* The global store of un-instantiated modules
*/
define.modules = {};
/**
* We invoke require() in the context of a Domain so we can have multiple
* sets of modules running separate from each other.
* This contrasts with JSMs which are singletons, Domains allows us to
* optionally load a CommonJS module twice with separate data each time.
* Perhaps you want 2 command lines with a different set of commands in each,
* for example.
*/
function Domain() {
this.modules = {};
this._currentModule = null;
}
(function () {
/**
* Lookup module names and resolve them by calling the definition function if
* needed.
* There are 2 ways to call this, either with an array of dependencies and a
* callback to call when the dependencies are found (which can happen
* asynchronously in an in-page context) or with a single string an no callback
* where the dependency is resolved synchronously and returned.
* The API is designed to be compatible with the CommonJS AMD spec and
* RequireJS.
* @param {string[]|string} deps A name, or names for the payload
* @param {function|undefined} callback Function to call when the dependencies
* are resolved
* @return {undefined|object} The module required or undefined for
* array/callback method
*/
Domain.prototype.require = function(deps, callback) {
if (Array.isArray(deps)) {
var params = deps.map(function(dep) {
return this.lookup(dep);
}, this);
if (callback) {
callback.apply(null, params);
}
return undefined;
}
else {
return this.lookup(deps);
}
};
function normalize(path) {
var bits = path.split('/');
var i = 1;
while (i < bits.length) {
if (bits[i] === '..') {
bits.splice(i-1, 1);
} else if (bits[i] === '.') {
bits.splice(i, 1);
} else {
i++;
}
}
return bits.join('/');
}
function join(a, b) {
a = a.trim();
b = b.trim();
if (/^\//.test(b)) {
return b;
} else {
return a.replace(/\/*$/, '/') + b;
}
}
function dirname(path) {
var bits = path.split('/');
bits.pop();
return bits.join('/');
}
/**
* Lookup module names and resolve them by calling the definition function if
* needed.
* @param {string} moduleName A name for the payload to lookup
* @return {object} The module specified by aModuleName or null if not found.
*/
Domain.prototype.lookup = function(moduleName) {
if (/^\./.test(moduleName)) {
moduleName = normalize(join(dirname(this._currentModule), moduleName));
}
if (moduleName in this.modules) {
var module = this.modules[moduleName];
return module;
}
if (!(moduleName in define.modules)) {
throw new Error("Module not defined: " + moduleName);
}
var module = define.modules[moduleName];
if (typeof module == "function") {
var exports = {};
var previousModule = this._currentModule;
this._currentModule = moduleName;
module(this.require.bind(this), exports, { id: moduleName, uri: "" });
this._currentModule = previousModule;
module = exports;
}
// cache the resulting module object for next time
this.modules[moduleName] = module;
return module;
};
}());
define.Domain = Domain;
define.globalDomain = new Domain();
var require = define.globalDomain.require.bind(define.globalDomain);
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('source-map/source-map-generator', ['require', 'exports', 'module' , 'source-map/base64-vlq', 'source-map/util', 'source-map/array-set'], function(require, exports, module) {
var base64VLQ = require('./base64-vlq');
var util = require('./util');
var ArraySet = require('./array-set').ArraySet;
/**
* An instance of the SourceMapGenerator represents a source map which is
* being built incrementally. To create a new one, you must pass an object
* with the following properties:
*
* - file: The filename of the generated source.
* - sourceRoot: An optional root for all URLs in this source map.
*/
function SourceMapGenerator(aArgs) {
this._file = util.getArg(aArgs, 'file');
this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
this._sources = new ArraySet();
this._names = new ArraySet();
this._mappings = [];
this._sourcesContents = null;
}
SourceMapGenerator.prototype._version = 3;
/**
* Creates a new SourceMapGenerator based on a SourceMapConsumer
*
* @param aSourceMapConsumer The SourceMap.
*/
SourceMapGenerator.fromSourceMap =
function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
var sourceRoot = aSourceMapConsumer.sourceRoot;
var generator = new SourceMapGenerator({
file: aSourceMapConsumer.file,
sourceRoot: sourceRoot
});
aSourceMapConsumer.eachMapping(function (mapping) {
var newMapping = {
generated: {
line: mapping.generatedLine,
column: mapping.generatedColumn
}
};
if (mapping.source) {
newMapping.source = mapping.source;
if (sourceRoot) {
newMapping.source = util.relative(sourceRoot, newMapping.source);
}
newMapping.original = {
line: mapping.originalLine,
column: mapping.originalColumn
};
if (mapping.name) {
newMapping.name = mapping.name;
}
}
generator.addMapping(newMapping);
});
aSourceMapConsumer.sources.forEach(function (sourceFile) {
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
if (content) {
generator.setSourceContent(sourceFile, content);
}
});
return generator;
};
/**
* Add a single mapping from original source line and column to the generated
* source's line and column for this source map being created. The mapping
* object should have the following properties:
*
* - generated: An object with the generated line and column positions.
* - original: An object with the original line and column positions.
* - source: The original source file (relative to the sourceRoot).
* - name: An optional original token name for this mapping.
*/
SourceMapGenerator.prototype.addMapping =
function SourceMapGenerator_addMapping(aArgs) {
var generated = util.getArg(aArgs, 'generated');
var original = util.getArg(aArgs, 'original', null);
var source = util.getArg(aArgs, 'source', null);
var name = util.getArg(aArgs, 'name', null);
this._validateMapping(generated, original, source, name);
if (source && !this._sources.has(source)) {
this._sources.add(source);
}
if (name && !this._names.has(name)) {
this._names.add(name);
}
this._mappings.push({
generatedLine: generated.line,
generatedColumn: generated.column,
originalLine: original != null && original.line,
originalColumn: original != null && original.column,
source: source,
name: name
});
};
/**
* Set the source content for a source file.
*/
SourceMapGenerator.prototype.setSourceContent =
function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
var source = aSourceFile;
if (this._sourceRoot) {
source = util.relative(this._sourceRoot, source);
}
if (aSourceContent !== null) {
// Add the source content to the _sourcesContents map.
// Create a new _sourcesContents map if the property is null.
if (!this._sourcesContents) {
this._sourcesContents = {};
}
this._sourcesContents[util.toSetString(source)] = aSourceContent;
} else {
// Remove the source file from the _sourcesContents map.
// If the _sourcesContents map is empty, set the property to null.
delete this._sourcesContents[util.toSetString(source)];
if (Object.keys(this._sourcesContents).length === 0) {
this._sourcesContents = null;
}
}
};
/**
* Applies the mappings of a sub-source-map for a specific source file to the
* source map being generated. Each mapping to the supplied source file is
* rewritten using the supplied source map. Note: The resolution for the
* resulting mappings is the minimium of this map and the supplied map.
*
* @param aSourceMapConsumer The source map to be applied.
* @param aSourceFile Optional. The filename of the source file.
* If omitted, SourceMapConsumer's file property will be used.
*/
SourceMapGenerator.prototype.applySourceMap =
function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile) {
// If aSourceFile is omitted, we will use the file property of the SourceMap
if (!aSourceFile) {
aSourceFile = aSourceMapConsumer.file;
}
var sourceRoot = this._sourceRoot;
// Make "aSourceFile" relative if an absolute Url is passed.
if (sourceRoot) {
aSourceFile = util.relative(sourceRoot, aSourceFile);
}
// Applying the SourceMap can add and remove items from the sources and
// the names array.
var newSources = new ArraySet();
var newNames = new ArraySet();
// Find mappings for the "aSourceFile"
this._mappings.forEach(function (mapping) {
if (mapping.source === aSourceFile && mapping.originalLine) {
// Check if it can be mapped by the source map, then update the mapping.
var original = aSourceMapConsumer.originalPositionFor({
line: mapping.originalLine,
column: mapping.originalColumn
});
if (original.source !== null) {
// Copy mapping
if (sourceRoot) {
mapping.source = util.relative(sourceRoot, original.source);
} else {
mapping.source = original.source;
}
mapping.originalLine = original.line;
mapping.originalColumn = original.column;
if (original.name !== null && mapping.name !== null) {
// Only use the identifier name if it's an identifier
// in both SourceMaps
mapping.name = original.name;
}
}
}
var source = mapping.source;
if (source && !newSources.has(source)) {
newSources.add(source);
}
var name = mapping.name;
if (name && !newNames.has(name)) {
newNames.add(name);
}
}, this);
this._sources = newSources;
this._names = newNames;
// Copy sourcesContents of applied map.
aSourceMapConsumer.sources.forEach(function (sourceFile) {
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
if (content) {
if (sourceRoot) {
sourceFile = util.relative(sourceRoot, sourceFile);
}
this.setSourceContent(sourceFile, content);
}
}, this);
};
/**
* A mapping can have one of the three levels of data:
*
* 1. Just the generated position.
* 2. The Generated position, original position, and original source.
* 3. Generated and original position, original source, as well as a name
* token.
*
* To maintain consistency, we validate that any new mapping being added falls
* in to one of these categories.
*/
SourceMapGenerator.prototype._validateMapping =
function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
aName) {
if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
&& aGenerated.line > 0 && aGenerated.column >= 0
&& !aOriginal && !aSource && !aName) {
// Case 1.
return;
}
else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
&& aOriginal && 'line' in aOriginal && 'column' in aOriginal
&& aGenerated.line > 0 && aGenerated.column >= 0
&& aOriginal.line > 0 && aOriginal.column >= 0
&& aSource) {
// Cases 2 and 3.
return;
}
else {
throw new Error('Invalid mapping: ' + JSON.stringify({
generated: aGenerated,
source: aSource,
orginal: aOriginal,
name: aName
}));
}
};
/**
* Serialize the accumulated mappings in to the stream of base 64 VLQs
* specified by the source map format.
*/
SourceMapGenerator.prototype._serializeMappings =
function SourceMapGenerator_serializeMappings() {
var previousGeneratedColumn = 0;
var previousGeneratedLine = 1;
var previousOriginalColumn = 0;
var previousOriginalLine = 0;
var previousName = 0;
var previousSource = 0;
var result = '';
var mapping;
// The mappings must be guaranteed to be in sorted order before we start
// serializing them or else the generated line numbers (which are defined
// via the ';' separators) will be all messed up. Note: it might be more
// performant to maintain the sorting as we insert them, rather than as we
// serialize them, but the big O is the same either way.
this._mappings.sort(util.compareByGeneratedPositions);
for (var i = 0, len = this._mappings.length; i < len; i++) {
mapping = this._mappings[i];
if (mapping.generatedLine !== previousGeneratedLine) {
previousGeneratedColumn = 0;
while (mapping.generatedLine !== previousGeneratedLine) {
result += ';';
previousGeneratedLine++;
}
}
else {
if (i > 0) {
if (!util.compareByGeneratedPositions(mapping, this._mappings[i - 1])) {
continue;
}
result += ',';
}
}
result += base64VLQ.encode(mapping.generatedColumn
- previousGeneratedColumn);
previousGeneratedColumn = mapping.generatedColumn;
if (mapping.source) {
result += base64VLQ.encode(this._sources.indexOf(mapping.source)
- previousSource);
previousSource = this._sources.indexOf(mapping.source);
// lines are stored 0-based in SourceMap spec version 3
result += base64VLQ.encode(mapping.originalLine - 1
- previousOriginalLine);
previousOriginalLine = mapping.originalLine - 1;
result += base64VLQ.encode(mapping.originalColumn
- previousOriginalColumn);
previousOriginalColumn = mapping.originalColumn;
if (mapping.name) {
result += base64VLQ.encode(this._names.indexOf(mapping.name)
- previousName);
previousName = this._names.indexOf(mapping.name);
}
}
}
return result;
};
SourceMapGenerator.prototype._generateSourcesContent =
function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
return aSources.map(function (source) {
if (!this._sourcesContents) {
return null;
}
if (aSourceRoot) {
source = util.relative(aSourceRoot, source);
}
var key = util.toSetString(source);
return Object.prototype.hasOwnProperty.call(this._sourcesContents,
key)
? this._sourcesContents[key]
: null;
}, this);
};
/**
* Externalize the source map.
*/
SourceMapGenerator.prototype.toJSON =
function SourceMapGenerator_toJSON() {
var map = {
version: this._version,
file: this._file,
sources: this._sources.toArray(),
names: this._names.toArray(),
mappings: this._serializeMappings()
};
if (this._sourceRoot) {
map.sourceRoot = this._sourceRoot;
}
if (this._sourcesContents) {
map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
}
return map;
};
/**
* Render the source map being generated to a string.
*/
SourceMapGenerator.prototype.toString =
function SourceMapGenerator_toString() {
return JSON.stringify(this);
};
exports.SourceMapGenerator = SourceMapGenerator;
});
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*
* Based on the Base 64 VLQ implementation in Closure Compiler:
* https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
*
* Copyright 2011 The Closure Compiler Authors. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
define('source-map/base64-vlq', ['require', 'exports', 'module' , 'source-map/base64'], function(require, exports, module) {
var base64 = require('./base64');
// A single base 64 digit can contain 6 bits of data. For the base 64 variable
// length quantities we use in the source map spec, the first bit is the sign,
// the next four bits are the actual value, and the 6th bit is the
// continuation bit. The continuation bit tells us whether there are more
// digits in this value following this digit.
//
// Continuation
// | Sign
// | |
// V V
// 101011
var VLQ_BASE_SHIFT = 5;
// binary: 100000
var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
// binary: 011111
var VLQ_BASE_MASK = VLQ_BASE - 1;
// binary: 100000
var VLQ_CONTINUATION_BIT = VLQ_BASE;
/**
* Converts from a two-complement value to a value where the sign bit is
* is placed in the least significant bit. For example, as decimals:
* 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
* 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
*/
function toVLQSigned(aValue) {
return aValue < 0
? ((-aValue) << 1) + 1
: (aValue << 1) + 0;
}
/**
* Converts to a two-complement value from a value where the sign bit is
* is placed in the least significant bit. For example, as decimals:
* 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
* 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
*/
function fromVLQSigned(aValue) {
var isNegative = (aValue & 1) === 1;
var shifted = aValue >> 1;
return isNegative
? -shifted
: shifted;
}
/**
* Returns the base 64 VLQ encoded value.
*/
exports.encode = function base64VLQ_encode(aValue) {
var encoded = "";
var digit;
var vlq = toVLQSigned(aValue);
do {
digit = vlq & VLQ_BASE_MASK;
vlq >>>= VLQ_BASE_SHIFT;
if (vlq > 0) {
// There are still more digits in this value, so we must make sure the
// continuation bit is marked.
digit |= VLQ_CONTINUATION_BIT;
}
encoded += base64.encode(digit);
} while (vlq > 0);
return encoded;
};
/**
* Decodes the next base 64 VLQ value from the given string and returns the
* value and the rest of the string.
*/
exports.decode = function base64VLQ_decode(aStr) {
var i = 0;
var strLen = aStr.length;
var result = 0;
var shift = 0;
var continuation, digit;
do {
if (i >= strLen) {
throw new Error("Expected more digits in base 64 VLQ value.");
}
digit = base64.decode(aStr.charAt(i++));
continuation = !!(digit & VLQ_CONTINUATION_BIT);
digit &= VLQ_BASE_MASK;
result = result + (digit << shift);
shift += VLQ_BASE_SHIFT;
} while (continuation);
return {
value: fromVLQSigned(result),
rest: aStr.slice(i)
};
};
});
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('source-map/base64', ['require', 'exports', 'module' , ], function(require, exports, module) {
var charToIntMap = {};
var intToCharMap = {};
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
.split('')
.forEach(function (ch, index) {
charToIntMap[ch] = index;
intToCharMap[index] = ch;
});
/**
* Encode an integer in the range of 0 to 63 to a single base 64 digit.
*/
exports.encode = function base64_encode(aNumber) {
if (aNumber in intToCharMap) {
return intToCharMap[aNumber];
}
throw new TypeError("Must be between 0 and 63: " + aNumber);
};
/**
* Decode a single base 64 digit to an integer.
*/
exports.decode = function base64_decode(aChar) {
if (aChar in charToIntMap) {
return charToIntMap[aChar];
}
throw new TypeError("Not a valid base 64 digit: " + aChar);
};
});
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('source-map/util', ['require', 'exports', 'module' , ], function(require, exports, module) {
/**
* This is a helper function for getting values from parameter/options
* objects.
*
* @param args The object we are extracting values from
* @param name The name of the property we are getting.
* @param defaultValue An optional value to return if the property is missing
* from the object. If this is not specified and the property is missing, an
* error will be thrown.
*/
function getArg(aArgs, aName, aDefaultValue) {
if (aName in aArgs) {
return aArgs[aName];
} else if (arguments.length === 3) {
return aDefaultValue;
} else {
throw new Error('"' + aName + '" is a required argument.');
}
}
exports.getArg = getArg;
var urlRegexp = /([\w+\-.]+):\/\/((\w+:\w+)@)?([\w.]+)?(:(\d+))?(\S+)?/;
var dataUrlRegexp = /^data:.+\,.+/;
function urlParse(aUrl) {
var match = aUrl.match(urlRegexp);
if (!match) {
return null;
}
return {
scheme: match[1],
auth: match[3],
host: match[4],
port: match[6],
path: match[7]
};
}
exports.urlParse = urlParse;
function urlGenerate(aParsedUrl) {
var url = aParsedUrl.scheme + "://";
if (aParsedUrl.auth) {
url += aParsedUrl.auth + "@"
}
if (aParsedUrl.host) {
url += aParsedUrl.host;
}
if (aParsedUrl.port) {
url += ":" + aParsedUrl.port
}
if (aParsedUrl.path) {
url += aParsedUrl.path;
}
return url;
}
exports.urlGenerate = urlGenerate;
function join(aRoot, aPath) {
var url;
if (aPath.match(urlRegexp) || aPath.match(dataUrlRegexp)) {
return aPath;
}
if (aPath.charAt(0) === '/' && (url = urlParse(aRoot))) {
url.path = aPath;
return urlGenerate(url);
}
return aRoot.replace(/\/$/, '') + '/' + aPath;
}
exports.join = join;
/**
* Because behavior goes wacky when you set `__proto__` on objects, we
* have to prefix all the strings in our set with an arbitrary character.
*
* See https://github.com/mozilla/source-map/pull/31 and
* https://github.com/mozilla/source-map/issues/30
*
* @param String aStr
*/
function toSetString(aStr) {
return '$' + aStr;
}
exports.toSetString = toSetString;
function fromSetString(aStr) {
return aStr.substr(1);
}
exports.fromSetString = fromSetString;
function relative(aRoot, aPath) {
aRoot = aRoot.replace(/\/$/, '');
var url = urlParse(aRoot);
if (aPath.charAt(0) == "/" && url && url.path == "/") {
return aPath.slice(1);
}
return aPath.indexOf(aRoot + '/') === 0
? aPath.substr(aRoot.length + 1)
: aPath;
}
exports.relative = relative;
function strcmp(aStr1, aStr2) {
var s1 = aStr1 || "";
var s2 = aStr2 || "";
return (s1 > s2) - (s1 < s2);
}
/**
* Comparator between two mappings where the original positions are compared.
*
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
* mappings with the same original source/line/column, but different generated
* line and column the same. Useful when searching for a mapping with a
* stubbed out mapping.
*/
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
var cmp;
cmp = strcmp(mappingA.source, mappingB.source);
if (cmp) {
return cmp;
}
cmp = mappingA.originalLine - mappingB.originalLine;
if (cmp) {
return cmp;
}
cmp = mappingA.originalColumn - mappingB.originalColumn;
if (cmp || onlyCompareOriginal) {
return cmp;
}
cmp = strcmp(mappingA.name, mappingB.name);
if (cmp) {
return cmp;
}
cmp = mappingA.generatedLine - mappingB.generatedLine;
if (cmp) {
return cmp;
}
return mappingA.generatedColumn - mappingB.generatedColumn;
};
exports.compareByOriginalPositions = compareByOriginalPositions;
/**
* Comparator between two mappings where the generated positions are
* compared.
*
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
* mappings with the same generated line and column, but different
* source/name/original line and column the same. Useful when searching for a
* mapping with a stubbed out mapping.
*/
function compareByGeneratedPositions(mappingA, mappingB, onlyCompareGenerated) {
var cmp;
cmp = mappingA.generatedLine - mappingB.generatedLine;
if (cmp) {
return cmp;
}
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
if (cmp || onlyCompareGenerated) {
return cmp;
}
cmp = strcmp(mappingA.source, mappingB.source);
if (cmp) {
return cmp;
}
cmp = mappingA.originalLine - mappingB.originalLine;
if (cmp) {
return cmp;
}
cmp = mappingA.originalColumn - mappingB.originalColumn;
if (cmp) {
return cmp;
}
return strcmp(mappingA.name, mappingB.name);
};
exports.compareByGeneratedPositions = compareByGeneratedPositions;
});
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('source-map/array-set', ['require', 'exports', 'module' , 'source-map/util'], function(require, exports, module) {
var util = require('./util');
/**
* A data structure which is a combination of an array and a set. Adding a new
* member is O(1), testing for membership is O(1), and finding the index of an
* element is O(1). Removing elements from the set is not supported. Only
* strings are supported for membership.
*/
function ArraySet() {
this._array = [];
this._set = {};
}
/**
* Static method for creating ArraySet instances from an existing array.
*/
ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
var set = new ArraySet();
for (var i = 0, len = aArray.length; i < len; i++) {
set.add(aArray[i], aAllowDuplicates);
}
return set;
};
/**
* Add the given string to this set.
*
* @param String aStr
*/
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
var isDuplicate = this.has(aStr);
var idx = this._array.length;
if (!isDuplicate || aAllowDuplicates) {
this._array.push(aStr);
}
if (!isDuplicate) {
this._set[util.toSetString(aStr)] = idx;
}
};
/**
* Is the given string a member of this set?
*
* @param String aStr
*/
ArraySet.prototype.has = function ArraySet_has(aStr) {
return Object.prototype.hasOwnProperty.call(this._set,
util.toSetString(aStr));
};
/**
* What is the index of the given string in the array?
*
* @param String aStr
*/
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
if (this.has(aStr)) {
return this._set[util.toSetString(aStr)];
}
throw new Error('"' + aStr + '" is not in the set.');
};
/**
* What is the element at the given index?
*
* @param Number aIdx
*/
ArraySet.prototype.at = function ArraySet_at(aIdx) {
if (aIdx >= 0 && aIdx < this._array.length) {
return this._array[aIdx];
}
throw new Error('No element indexed by ' + aIdx);
};
/**
* Returns the array representation of this set (which has the proper indices
* indicated by indexOf). Note that this is a copy of the internal array used
* for storing the members so that no one can mess with internal state.
*/
ArraySet.prototype.toArray = function ArraySet_toArray() {
return this._array.slice();
};
exports.ArraySet = ArraySet;
});
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('source-map/source-map-consumer', ['require', 'exports', 'module' , 'source-map/util', 'source-map/binary-search', 'source-map/array-set', 'source-map/base64-vlq'], function(require, exports, module) {
var util = require('./util');
var binarySearch = require('./binary-search');
var ArraySet = require('./array-set').ArraySet;
var base64VLQ = require('./base64-vlq');
/**
* A SourceMapConsumer instance represents a parsed source map which we can
* query for information about the original file positions by giving it a file
* position in the generated source.
*
* The only parameter is the raw source map (either as a JSON string, or
* already parsed to an object). According to the spec, source maps have the
* following attributes:
*
* - version: Which version of the source map spec this map is following.
* - sources: An array of URLs to the original source files.
* - names: An array of identifiers which can be referrenced by individual mappings.
* - sourceRoot: Optional. The URL root from which all sources are relative.
* - sourcesContent: Optional. An array of contents of the original source files.
* - mappings: A string of base64 VLQs which contain the actual mappings.
* - file: The generated file this source map is associated with.
*
* Here is an example source map, taken from the source map spec[0]:
*
* {
* version : 3,
* file: "out.js",
* sourceRoot : "",
* sources: ["foo.js", "bar.js"],
* names: ["src", "maps", "are", "fun"],
* mappings: "AA,AB;;ABCDE;"
* }
*
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
*/
function SourceMapConsumer(aSourceMap) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
}
var version = util.getArg(sourceMap, 'version');
var sources = util.getArg(sourceMap, 'sources');
// Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which
// requires the array) to play nice here.
var names = util.getArg(sourceMap, 'names', []);
var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null);
var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null);
var mappings = util.getArg(sourceMap, 'mappings');
var file = util.getArg(sourceMap, 'file', null);
// Once again, Sass deviates from the spec and supplies the version as a
// string rather than a number, so we use loose equality checking here.
if (version != this._version) {
throw new Error('Unsupported version: ' + version);
}
// Pass `true` below to allow duplicate names and sources. While source maps
// are intended to be compressed and deduplicated, the TypeScript compiler
// sometimes generates source maps with duplicates in them. See Github issue
// #72 and bugzil.la/889492.
this._names = ArraySet.fromArray(names, true);
this._sources = ArraySet.fromArray(sources, true);
this.sourceRoot = sourceRoot;
this.sourcesContent = sourcesContent;
this._mappings = mappings;
this.file = file;
}
/**
* Create a SourceMapConsumer from a SourceMapGenerator.
*
* @param SourceMapGenerator aSourceMap
* The source map that will be consumed.
* @returns SourceMapConsumer
*/
SourceMapConsumer.fromSourceMap =
function SourceMapConsumer_fromSourceMap(aSourceMap) {
var smc = Object.create(SourceMapConsumer.prototype);
smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);
smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true);
smc.sourceRoot = aSourceMap._sourceRoot;
smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),
smc.sourceRoot);
smc.file = aSourceMap._file;
smc.__generatedMappings = aSourceMap._mappings.slice()
.sort(util.compareByGeneratedPositions);
smc.__originalMappings = aSourceMap._mappings.slice()
.sort(util.compareByOriginalPositions);
return smc;
};
/**
* The version of the source mapping spec that we are consuming.
*/
SourceMapConsumer.prototype._version = 3;
/**
* The list of original sources.
*/
Object.defineProperty(SourceMapConsumer.prototype, 'sources', {
get: function () {
return this._sources.toArray().map(function (s) {
return this.sourceRoot ? util.join(this.sourceRoot, s) : s;
}, this);
}
});
// `__generatedMappings` and `__originalMappings` are arrays that hold the
// parsed mapping coordinates from the source map's "mappings" attribute. They
// are lazily instantiated, accessed via the `_generatedMappings` and
// `_originalMappings` getters respectively, and we only parse the mappings
// and create these arrays once queried for a source location. We jump through
// these hoops because there can be many thousands of mappings, and parsing
// them is expensive, so we only want to do it if we must.
//
// Each object in the arrays is of the form:
//
// {
// generatedLine: The line number in the generated code,
// generatedColumn: The column number in the generated code,
// source: The path to the original source file that generated this
// chunk of code,
// originalLine: The line number in the original source that
// corresponds to this chunk of generated code,
// originalColumn: The column number in the original source that
// corresponds to this chunk of generated code,
// name: The name of the original symbol which generated this chunk of
// code.
// }
//
// All properties except for `generatedLine` and `generatedColumn` can be
// `null`.
//
// `_generatedMappings` is ordered by the generated positions.
//
// `_originalMappings` is ordered by the original positions.
SourceMapConsumer.prototype.__generatedMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {
get: function () {
if (!this.__generatedMappings) {
this.__generatedMappings = [];
this.__originalMappings = [];
this._parseMappings(this._mappings, this.sourceRoot);
}
return this.__generatedMappings;
}
});
SourceMapConsumer.prototype.__originalMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {
get: function () {
if (!this.__originalMappings) {
this.__generatedMappings = [];
this.__originalMappings = [];
this._parseMappings(this._mappings, this.sourceRoot);
}
return this.__originalMappings;
}
});
/**
* Parse the mappings in a string in to a data structure which we can easily
* query (the ordered arrays in the `this.__generatedMappings` and
* `this.__originalMappings` properties).
*/
SourceMapConsumer.prototype._parseMappings =
function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
var generatedLine = 1;
var previousGeneratedColumn = 0;
var previousOriginalLine = 0;
var previousOriginalColumn = 0;
var previousSource = 0;
var previousName = 0;
var mappingSeparator = /^[,;]/;
var str = aStr;
var mapping;
var temp;
while (str.length > 0) {
if (str.charAt(0) === ';') {
generatedLine++;
str = str.slice(1);
previousGeneratedColumn = 0;
}
else if (str.charAt(0) === ',') {
str = str.slice(1);
}
else {
mapping = {};
mapping.generatedLine = generatedLine;
// Generated column.
temp = base64VLQ.decode(str);
mapping.generatedColumn = previousGeneratedColumn + temp.value;
previousGeneratedColumn = mapping.generatedColumn;
str = temp.rest;
if (str.length > 0 && !mappingSeparator.test(str.charAt(0))) {
// Original source.
temp = base64VLQ.decode(str);
mapping.source = this._sources.at(previousSource + temp.value);
previousSource += temp.value;
str = temp.rest;
if (str.length === 0 || mappingSeparator.test(str.charAt(0))) {
throw new Error('Found a source, but no line and column');
}
// Original line.
temp = base64VLQ.decode(str);
mapping.originalLine = previousOriginalLine + temp.value;
previousOriginalLine = mapping.originalLine;
// Lines are stored 0-based
mapping.originalLine += 1;
str = temp.rest;
if (str.length === 0 || mappingSeparator.test(str.charAt(0))) {
throw new Error('Found a source and line, but no column');
}
// Original column.
temp = base64VLQ.decode(str);
mapping.originalColumn = previousOriginalColumn + temp.value;
previousOriginalColumn = mapping.originalColumn;
str = temp.rest;
if (str.length > 0 && !mappingSeparator.test(str.charAt(0))) {
// Original name.
temp = base64VLQ.decode(str);
mapping.name = this._names.at(previousName + temp.value);
previousName += temp.value;
str = temp.rest;
}
}
this.__generatedMappings.push(mapping);
if (typeof mapping.originalLine === 'number') {
this.__originalMappings.push(mapping);
}
}
}
this.__originalMappings.sort(util.compareByOriginalPositions);
};
/**
* Find the mapping that best matches the hypothetical "needle" mapping that
* we are searching for in the given "haystack" of mappings.
*/
SourceMapConsumer.prototype._findMapping =
function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName,
aColumnName, aComparator) {
// To return the position we are searching for, we must first find the
// mapping for the given position and then return the opposite position it
// points to. Because the mappings are sorted, we can use binary search to
// find the best mapping.
if (aNeedle[aLineName] <= 0) {
throw new TypeError('Line must be greater than or equal to 1, got '
+ aNeedle[aLineName]);
}
if (aNeedle[aColumnName] < 0) {
throw new TypeError('Column must be greater than or equal to 0, got '
+ aNeedle[aColumnName]);
}
return binarySearch.search(aNeedle, aMappings, aComparator);
};
/**
* Returns the original source, line, and column information for the generated
* source's line and column positions provided. The only argument is an object
* with the following properties:
*
* - line: The line number in the generated source.
* - column: The column number in the generated source.
*
* and an object is returned with the following properties:
*
* - source: The original source file, or null.
* - line: The line number in the original source, or null.
* - column: The column number in the original source, or null.
* - name: The original identifier, or null.
*/
SourceMapConsumer.prototype.originalPositionFor =
function SourceMapConsumer_originalPositionFor(aArgs) {
var needle = {
generatedLine: util.getArg(aArgs, 'line'),
generatedColumn: util.getArg(aArgs, 'column')
};
var mapping = this._findMapping(needle,
this._generatedMappings,
"generatedLine",
"generatedColumn",
util.compareByGeneratedPositions);
if (mapping) {
var source = util.getArg(mapping, 'source', null);
if (source && this.sourceRoot) {
source = util.join(this.sourceRoot, source);
}
return {
source: source,
line: util.getArg(mapping, 'originalLine', null),
column: util.getArg(mapping, 'originalColumn', null),
name: util.getArg(mapping, 'name', null)
};
}
return {
source: null,
line: null,
column: null,
name: null
};
};
/**
* Returns the original source content. The only argument is the url of the
* original source file. Returns null if no original source content is
* availible.
*/
SourceMapConsumer.prototype.sourceContentFor =
function SourceMapConsumer_sourceContentFor(aSource) {
if (!this.sourcesContent) {
return null;
}
if (this.sourceRoot) {
aSource = util.relative(this.sourceRoot, aSource);
}
if (this._sources.has(aSource)) {
return this.sourcesContent[this._sources.indexOf(aSource)];
}
var url;
if (this.sourceRoot
&& (url = util.urlParse(this.sourceRoot))) {
// XXX: file:// URIs and absolute paths lead to unexpected behavior for
// many users. We can help them out when they expect file:// URIs to
// behave like it would if they were running a local HTTP server. See
// https://bugzilla.mozilla.org/show_bug.cgi?id=885597.
var fileUriAbsPath = aSource.replace(/^file:\/\//, "");
if (url.scheme == "file"
&& this._sources.has(fileUriAbsPath)) {
return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]
}
if ((!url.path || url.path == "/")
&& this._sources.has("/" + aSource)) {
return this.sourcesContent[this._sources.indexOf("/" + aSource)];
}
}
throw new Error('"' + aSource + '" is not in the SourceMap.');
};
/**
* Returns the generated line and column information for the original source,
* line, and column positions provided. The only argument is an object with
* the following properties:
*
* - source: The filename of the original source.
* - line: The line number in the original source.
* - column: The column number in the original source.
*
* and an object is returned with the following properties:
*
* - line: The line number in the generated source, or null.
* - column: The column number in the generated source, or null.
*/
SourceMapConsumer.prototype.generatedPositionFor =
function SourceMapConsumer_generatedPositionFor(aArgs) {
var needle = {
source: util.getArg(aArgs, 'source'),
originalLine: util.getArg(aArgs, 'line'),
originalColumn: util.getArg(aArgs, 'column')
};
if (this.sourceRoot) {
needle.source = util.relative(this.sourceRoot, needle.source);
}
var mapping = this._findMapping(needle,
this._originalMappings,
"originalLine",
"originalColumn",
util.compareByOriginalPositions);
if (mapping) {
return {
line: util.getArg(mapping, 'generatedLine', null),
column: util.getArg(mapping, 'generatedColumn', null)
};
}
return {
line: null,
column: null
};
};
SourceMapConsumer.GENERATED_ORDER = 1;
SourceMapConsumer.ORIGINAL_ORDER = 2;
/**
* Iterate over each mapping between an original source/line/column and a
* generated line/column in this source map.
*
* @param Function aCallback
* The function that is called with each mapping.
* @param Object aContext
* Optional. If specified, this object will be the value of `this` every
* time that `aCallback` is called.
* @param aOrder
* Either `SourceMapConsumer.GENERATED_ORDER` or
* `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to
* iterate over the mappings sorted by the generated file's line/column
* order or the original's source/line/column order, respectively. Defaults to
* `SourceMapConsumer.GENERATED_ORDER`.
*/
SourceMapConsumer.prototype.eachMapping =
function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) {
var context = aContext || null;
var order = aOrder || SourceMapConsumer.GENERATED_ORDER;
var mappings;
switch (order) {
case SourceMapConsumer.GENERATED_ORDER:
mappings = this._generatedMappings;
break;
case SourceMapConsumer.ORIGINAL_ORDER:
mappings = this._originalMappings;
break;
default:
throw new Error("Unknown order of iteration.");
}
var sourceRoot = this.sourceRoot;
mappings.map(function (mapping) {
var source = mapping.source;
if (source && sourceRoot) {
source = util.join(sourceRoot, source);
}
return {
source: source,
generatedLine: mapping.generatedLine,
generatedColumn: mapping.generatedColumn,
originalLine: mapping.originalLine,
originalColumn: mapping.originalColumn,
name: mapping.name
};
}).forEach(aCallback, context);
};
exports.SourceMapConsumer = SourceMapConsumer;
});
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('source-map/binary-search', ['require', 'exports', 'module' , ], function(require, exports, module) {
/**
* Recursive implementation of binary search.
*
* @param aLow Indices here and lower do not contain the needle.
* @param aHigh Indices here and higher do not contain the needle.
* @param aNeedle The element being searched for.
* @param aHaystack The non-empty array being searched.
* @param aCompare Function which takes two elements and returns -1, 0, or 1.
*/
function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare) {
// This function terminates when one of the following is true:
//
// 1. We find the exact element we are looking for.
//
// 2. We did not find the exact element, but we can return the next
// closest element that is less than that element.
//
// 3. We did not find the exact element, and there is no next-closest
// element which is less than the one we are searching for, so we
// return null.
var mid = Math.floor((aHigh - aLow) / 2) + aLow;
var cmp = aCompare(aNeedle, aHaystack[mid], true);
if (cmp === 0) {
// Found the element we are looking for.
return aHaystack[mid];
}
else if (cmp > 0) {
// aHaystack[mid] is greater than our needle.
if (aHigh - mid > 1) {
// The element is in the upper half.
return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare);
}
// We did not find an exact match, return the next closest one
// (termination case 2).
return aHaystack[mid];
}
else {
// aHaystack[mid] is less than our needle.
if (mid - aLow > 1) {
// The element is in the lower half.
return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare);
}
// The exact needle element was not found in this haystack. Determine if
// we are in termination case (2) or (3) and return the appropriate thing.
return aLow < 0
? null
: aHaystack[aLow];
}
}
/**
* This is an implementation of binary search which will always try and return
* the next lowest value checked if there is no exact hit. This is because
* mappings between original and generated line/col pairs are single points,
* and there is an implicit region between each of them, so a miss just means
* that you aren't on the very start of a region.
*
* @param aNeedle The element you are looking for.
* @param aHaystack The array that is being searched.
* @param aCompare A function which takes the needle and an element in the
* array and returns -1, 0, or 1 depending on whether the needle is less
* than, equal to, or greater than the element, respectively.
*/
exports.search = function search(aNeedle, aHaystack, aCompare) {
return aHaystack.length > 0
? recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, aCompare)
: null;
};
});
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('source-map/source-node', ['require', 'exports', 'module' , 'source-map/source-map-generator', 'source-map/util'], function(require, exports, module) {
var SourceMapGenerator = require('./source-map-generator').SourceMapGenerator;
var util = require('./util');
/**
* SourceNodes provide a way to abstract over interpolating/concatenating
* snippets of generated JavaScript source code while maintaining the line and
* column information associated with the original source code.
*
* @param aLine The original line number.
* @param aColumn The original column number.
* @param aSource The original source's filename.
* @param aChunks Optional. An array of strings which are snippets of
* generated JS, or other SourceNodes.
* @param aName The original identifier.
*/
function SourceNode(aLine, aColumn, aSource, aChunks, aName) {
this.children = [];
this.sourceContents = {};
this.line = aLine === undefined ? null : aLine;
this.column = aColumn === undefined ? null : aColumn;
this.source = aSource === undefined ? null : aSource;
this.name = aName === undefined ? null : aName;
if (aChunks != null) this.add(aChunks);
}
/**
* Creates a SourceNode from generated code and a SourceMapConsumer.
*
* @param aGeneratedCode The generated code
* @param aSourceMapConsumer The SourceMap for the generated code
*/
SourceNode.fromStringWithSourceMap =
function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer) {
// The SourceNode we want to fill with the generated code
// and the SourceMap
var node = new SourceNode();
// The generated code
// Processed fragments are removed from this array.
var remainingLines = aGeneratedCode.split('\n');
// We need to remember the position of "remainingLines"
var lastGeneratedLine = 1, lastGeneratedColumn = 0;
// The generate SourceNodes we need a code range.
// To extract it current and last mapping is used.
// Here we store the last mapping.
var lastMapping = null;
aSourceMapConsumer.eachMapping(function (mapping) {
if (lastMapping === null) {
// We add the generated code until the first mapping
// to the SourceNode without any mapping.
// Each line is added as separate string.
while (lastGeneratedLine < mapping.generatedLine) {
node.add(remainingLines.shift() + "\n");
lastGeneratedLine++;
}
if (lastGeneratedColumn < mapping.generatedColumn) {
var nextLine = remainingLines[0];
node.add(nextLine.substr(0, mapping.generatedColumn));
remainingLines[0] = nextLine.substr(mapping.generatedColumn);
lastGeneratedColumn = mapping.generatedColumn;
}
} else {
// We add the code from "lastMapping" to "mapping":
// First check if there is a new line in between.
if (lastGeneratedLine < mapping.generatedLine) {
var code = "";
// Associate full lines with "lastMapping"
do {
code += remainingLines.shift() + "\n";
lastGeneratedLine++;
lastGeneratedColumn = 0;
} while (lastGeneratedLine < mapping.generatedLine);
// When we reached the correct line, we add code until we
// reach the correct column too.
if (lastGeneratedColumn < mapping.generatedColumn) {
var nextLine = remainingLines[0];
code += nextLine.substr(0, mapping.generatedColumn);
remainingLines[0] = nextLine.substr(mapping.generatedColumn);
lastGeneratedColumn = mapping.generatedColumn;
}
// Create the SourceNode.
addMappingWithCode(lastMapping, code);
} else {
// There is no new line in between.
// Associate the code between "lastGeneratedColumn" and
// "mapping.generatedColumn" with "lastMapping"
var nextLine = remainingLines[0];
var code = nextLine.substr(0, mapping.generatedColumn -
lastGeneratedColumn);
remainingLines[0] = nextLine.substr(mapping.generatedColumn -
lastGeneratedColumn);
lastGeneratedColumn = mapping.generatedColumn;
addMappingWithCode(lastMapping, code);
}
}
lastMapping = mapping;
}, this);
// We have processed all mappings.
// Associate the remaining code in the current line with "lastMapping"
// and add the remaining lines without any mapping
addMappingWithCode(lastMapping, remainingLines.join("\n"));
// Copy sourcesContent into SourceNode
aSourceMapConsumer.sources.forEach(function (sourceFile) {
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
if (content) {
node.setSourceContent(sourceFile, content);
}
});
return node;
function addMappingWithCode(mapping, code) {
if (mapping === null || mapping.source === undefined) {
node.add(code);
} else {
node.add(new SourceNode(mapping.originalLine,
mapping.originalColumn,
mapping.source,
code,
mapping.name));
}
}
};
/**
* Add a chunk of generated JS to this source node.
*
* @param aChunk A string snippet of generated JS code, another instance of
* SourceNode, or an array where each member is one of those things.
*/
SourceNode.prototype.add = function SourceNode_add(aChunk) {
if (Array.isArray(aChunk)) {
aChunk.forEach(function (chunk) {
this.add(chunk);
}, this);
}
else if (aChunk instanceof SourceNode || typeof aChunk === "string") {
if (aChunk) {
this.children.push(aChunk);
}
}
else {
throw new TypeError(
"Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
);
}
return this;
};
/**
* Add a chunk of generated JS to the beginning of this source node.
*
* @param aChunk A string snippet of generated JS code, another instance of
* SourceNode, or an array where each member is one of those things.
*/
SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) {
if (Array.isArray(aChunk)) {
for (var i = aChunk.length-1; i >= 0; i--) {
this.prepend(aChunk[i]);
}
}
else if (aChunk instanceof SourceNode || typeof aChunk === "string") {
this.children.unshift(aChunk);
}
else {
throw new TypeError(
"Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
);
}
return this;
};
/**
* Walk over the tree of JS snippets in this node and its children. The
* walking function is called once for each snippet of JS and is passed that
* snippet and the its original associated source's line/column location.
*
* @param aFn The traversal function.
*/
SourceNode.prototype.walk = function SourceNode_walk(aFn) {
var chunk;
for (var i = 0, len = this.children.length; i < len; i++) {
chunk = this.children[i];
if (chunk instanceof SourceNode) {
chunk.walk(aFn);
}
else {
if (chunk !== '') {
aFn(chunk, { source: this.source,
line: this.line,
column: this.column,
name: this.name });
}
}
}
};
/**
* Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between
* each of `this.children`.
*
* @param aSep The separator.
*/
SourceNode.prototype.join = function SourceNode_join(aSep) {
var newChildren;
var i;
var len = this.children.length;
if (len > 0) {
newChildren = [];
for (i = 0; i < len-1; i++) {
newChildren.push(this.children[i]);
newChildren.push(aSep);
}
newChildren.push(this.children[i]);
this.children = newChildren;
}
return this;
};
/**
* Call String.prototype.replace on the very right-most source snippet. Useful
* for trimming whitespace from the end of a source node, etc.
*
* @param aPattern The pattern to replace.
* @param aReplacement The thing to replace the pattern with.
*/
SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) {
var lastChild = this.children[this.children.length - 1];
if (lastChild instanceof SourceNode) {
lastChild.replaceRight(aPattern, aReplacement);
}
else if (typeof lastChild === 'string') {
this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement);
}
else {
this.children.push(''.replace(aPattern, aReplacement));
}
return this;
};
/**
* Set the source content for a source file. This will be added to the SourceMapGenerator
* in the sourcesContent field.
*
* @param aSourceFile The filename of the source file
* @param aSourceContent The content of the source file
*/
SourceNode.prototype.setSourceContent =
function SourceNode_setSourceContent(aSourceFile, aSourceContent) {
this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent;
};
/**
* Walk over the tree of SourceNodes. The walking function is called for each
* source file content and is passed the filename and source content.
*
* @param aFn The traversal function.
*/
SourceNode.prototype.walkSourceContents =
function SourceNode_walkSourceContents(aFn) {
for (var i = 0, len = this.children.length; i < len; i++) {
if (this.children[i] instanceof SourceNode) {
this.children[i].walkSourceContents(aFn);
}
}
var sources = Object.keys(this.sourceContents);
for (var i = 0, len = sources.length; i < len; i++) {
aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]);
}
};
/**
* Return the string representation of this source node. Walks over the tree
* and concatenates all the various snippets together to one string.
*/
SourceNode.prototype.toString = function SourceNode_toString() {
var str = "";
this.walk(function (chunk) {
str += chunk;
});
return str;
};
/**
* Returns the string representation of this source node along with a source
* map.
*/
SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) {
var generated = {
code: "",
line: 1,
column: 0
};
var map = new SourceMapGenerator(aArgs);
var sourceMappingActive = false;
var lastOriginalSource = null;
var lastOriginalLine = null;
var lastOriginalColumn = null;
var lastOriginalName = null;
this.walk(function (chunk, original) {
generated.code += chunk;
if (original.source !== null
&& original.line !== null
&& original.column !== null) {
if(lastOriginalSource !== original.source
|| lastOriginalLine !== original.line
|| lastOriginalColumn !== original.column
|| lastOriginalName !== original.name) {
map.addMapping({
source: original.source,
original: {
line: original.line,
column: original.column
},
generated: {
line: generated.line,
column: generated.column
},
name: original.name
});
}
lastOriginalSource = original.source;
lastOriginalLine = original.line;
lastOriginalColumn = original.column;
lastOriginalName = original.name;
sourceMappingActive = true;
} else if (sourceMappingActive) {
map.addMapping({
generated: {
line: generated.line,
column: generated.column
}
});
lastOriginalSource = null;
sourceMappingActive = false;
}
chunk.split('').forEach(function (ch) {
if (ch === '\n') {
generated.line++;
generated.column = 0;
} else {
generated.column++;
}
});
});
this.walkSourceContents(function (sourceFile, sourceContent) {
map.setSourceContent(sourceFile, sourceContent);
});
return { code: generated.code, map: map };
};
exports.SourceNode = SourceNode;
});
/* -*- Mode: js; js-indent-level: 2; -*- */
///////////////////////////////////////////////////////////////////////////////
this.sourceMap = {
SourceMapConsumer: require('source-map/source-map-consumer').SourceMapConsumer,
SourceMapGenerator: require('source-map/source-map-generator').SourceMapGenerator,
SourceNode: require('source-map/source-node').SourceNode
};
}
});
__d('react-native/Libraries/JavaScriptAppEngine/Initialization/source-map-url',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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.
*
* This is a third-party micro-library grabbed from:
* https://github.com/lydell/source-map-url
*
* @nolint
*/
(function() {
var define = null; // Hack to make it work with our packager
// Copyright 2014 Simon Lydell
// X11 (“MIT”) Licensed. (See LICENSE.)
void (function(root, factory) {
if (typeof define === "function" && define.amd) {
define(factory)
} else if (typeof exports === "object") {
module.exports = factory()
} else {
root.sourceMappingURL = factory()
}
}(this, function() {
var innerRegex = /[#@] sourceMappingURL=([^\s'"]*)/
var regex = RegExp(
"(?:" +
"/\\*" +
"(?:\\s*\r?\n(?://)?)?" +
"(?:" + innerRegex.source + ")" +
"\\s*" +
"\\*/" +
"|" +
"//(?:" + innerRegex.source + ")" +
")" +
"\\s*$"
)
return {
regex: regex,
_innerRegex: innerRegex,
getFrom: function(code) {
var match = code.match(regex)
return (match ? match[1] || match[2] || "" : null)
},
existsIn: function(code) {
return regex.test(code)
},
removeFrom: function(code) {
return code.replace(regex, "")
},
insertBefore: function(code, string) {
var match = code.match(regex)
if (match) {
return code.slice(0, match.index) + string + code.slice(match.index)
} else {
return code + string
}
}
}
}));
/** End of the third-party code */
})();
});
__d('parseErrorStack',["stacktrace-parser/index"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 parseErrorStack
*/
'use strict';
var stacktraceParser = require('stacktrace-parser/index');
function resolveSourceMaps(sourceMapInstance, stackFrame) {
try {
var orig = sourceMapInstance.originalPositionFor({
line: stackFrame.lineNumber,
column: stackFrame.column,
});
if (orig) {
stackFrame.file = orig.source;
stackFrame.lineNumber = orig.line;
stackFrame.column = orig.column;
}
} catch (innerEx) {
}
}
function parseErrorStack(e, sourceMapInstance) {
var stack = stacktraceParser.parse(e.stack);
var framesToPop = e.framesToPop || 0;
while (framesToPop--) {
stack.shift();
}
if (sourceMapInstance) {
stack.forEach(resolveSourceMaps.bind(null, sourceMapInstance));
}
return stack;
}
module.exports = parseErrorStack;
});
__d('stacktrace-parser/index',["stacktrace-parser/lib/stacktrace-parser"],function(global, require, requireDynamic, requireLazy, module, exports) { module.exports = require('stacktrace-parser/lib/stacktrace-parser');
});
__d('stacktrace-parser/lib/stacktrace-parser',[],function(global, require, requireDynamic, requireLazy, module, exports) {
var UNKNOWN_FUNCTION = '<unknown>';
var StackTraceParser = {
/**
* This parses the different stack traces and puts them into one format
* This borrows heavily from TraceKit (https://github.com/occ/TraceKit)
*/
parse: function(stackString) {
var chrome = /^\s*at (?:(?:(?:Anonymous function)?|((?:\[object object\])?\S+(?: \[as \S+\])?)) )?\(?((?:file|http|https):.*?):(\d+)(?::(\d+))?\)?\s*$/i,
gecko = /^(?:\s*(\S*)(?:\((.*?)\))?@)?((?:\w).*?):(\d+)(?::(\d+))?\s*$/i,
node = /^\s*at (?:((?:\[object object\])?\S+(?: \[as \S+\])?) )?\(?(.*?):(\d+)(?::(\d+))?\)?\s*$/i,
lines = stackString.split('\n'),
stack = [],
parts,
element;
for (var i = 0, j = lines.length; i < j; ++i) {
if ((parts = gecko.exec(lines[i]))) {
element = {
'file': parts[3],
'methodName': parts[1] || UNKNOWN_FUNCTION,
'lineNumber': +parts[4],
'column': parts[5] ? +parts[5] : null
};
} else if ((parts = chrome.exec(lines[i]))) {
element = {
'file': parts[2],
'methodName': parts[1] || UNKNOWN_FUNCTION,
'lineNumber': +parts[3],
'column': parts[4] ? +parts[4] : null
};
} else if ((parts = node.exec(lines[i]))) {
element = {
'file': parts[2],
'methodName': parts[1] || UNKNOWN_FUNCTION,
'lineNumber': +parts[3],
'column': parts[4] ? +parts[4] : null
};
} else {
continue;
}
stack.push(element);
}
return stack;
}
};
module.exports = StackTraceParser;
});
__d('stringifySafe',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 stringifySafe
* @flow
*/
'use strict';
/**
* Tries to stringify with JSON.stringify and toString, but catches exceptions
* (e.g. from circular objects) and always returns a string and never throws.
*/
function stringifySafe(arg ) {
var ret;
var type = typeof arg;
if (arg === undefined) {
ret = 'undefined';
} else if (arg === null) {
ret = 'null';
} else if (type === 'string') {
ret = '"' + arg + '"';
} else if (type === 'function') {
try {
ret = arg.toString();
} catch (e) {
ret = '[function unknown]';
}
} else {
// Perform a try catch, just in case the object has a circular
// reference or stringify throws for some other reason.
try {
ret = JSON.stringify(arg);
} catch (e) {
if (typeof arg.toString === 'function') {
try {
ret = arg.toString();
} catch (E) {}
}
}
}
return ret || '["' + type + '" failed to stringify]';
}
module.exports = stringifySafe;
});
__d('Platform',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 Platform
* @flow
*/
'use strict';
var Platform = {
OS: 'ios',
};
module.exports = Platform;
});
__d('XMLHttpRequest',["NativeModules","crc32","XMLHttpRequestBase"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 XMLHttpRequest
* @flow
*/
'use strict';
var RCTDataManager = require('NativeModules').DataManager;
var crc32 = require('crc32');
var XMLHttpRequestBase = require('XMLHttpRequestBase');
for(var XMLHttpRequestBase____Key in XMLHttpRequestBase){if(XMLHttpRequestBase.hasOwnProperty(XMLHttpRequestBase____Key)){XMLHttpRequest[XMLHttpRequestBase____Key]=XMLHttpRequestBase[XMLHttpRequestBase____Key];}}var ____SuperProtoOfXMLHttpRequestBase=XMLHttpRequestBase===null?null:XMLHttpRequestBase.prototype;XMLHttpRequest.prototype=Object.create(____SuperProtoOfXMLHttpRequestBase);XMLHttpRequest.prototype.constructor=XMLHttpRequest;XMLHttpRequest.__superConstructor__=XMLHttpRequestBase;function XMLHttpRequest(){if(XMLHttpRequestBase!==null){XMLHttpRequestBase.apply(this,arguments);}}
XMLHttpRequest.prototype.sendImpl=function(method , url , headers , data ) {
RCTDataManager.queryData(
'http',
{
method: method,
url: url,
data: data,
headers: headers,
},
// TODO: Do we need this? is it used anywhere?
'h' + crc32(method + '|' + url + '|' + data),
function(result) {
result = JSON.parse(result);
this.callback(result.status, result.responseHeaders, result.responseText);
}.bind(this)
);
};
XMLHttpRequest.prototype.abortImpl=function() {
console.warn(
'XMLHttpRequest: abort() cancels JS callbacks ' +
'but not native HTTP request.'
);
};
module.exports = XMLHttpRequest;
});
__d('crc32',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* @generated SignedSource<<9bce659a43d6f6115b20a18f6c995d8a>>
*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* !! This file is a check-in of a static_upstream project! !!
* !! !!
* !! You should not modify this file directly. Instead: !!
* !! 1) Use `fjs use-upstream` to temporarily replace this with !!
* !! the latest version from upstream. !!
* !! 2) Make your changes, test them, etc. !!
* !! 3) Use `fjs push-upstream` to copy your changes back to !!
* !! static_upstream. !!
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule crc32
*/
/* jslint bitwise: true */
/**
* Copyright (c) 2006 Andrea Ercolino
* http://www.opensource.org/licenses/mit-license.php
*/
var table = '00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 ' +
'9E6495A3 0EDB8832 79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 ' +
'90BF1D91 1DB71064 6AB020F2 F3B97148 84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 ' +
'83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F 63066CD9 FA0F3D63 ' +
'8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD ' +
'A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ' +
'ABD13D59 26D930AC 51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 ' +
'B8BDA50F 2802B89E 5F058808 C60CD9B2 B10BE924 2F6F7C87 58684C11 C1611DAB ' +
'B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 06B6B51F 9FBFE4A5 ' +
'E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 ' +
'E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 ' +
'F50FC457 65B0D9C6 12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 ' +
'FBD44C65 4DB26158 3AB551CE A3BC0074 D4BB30E2 4ADFA541 3DD895D7 A4D1C46D ' +
'D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 33031DE5 AA0A4C5F ' +
'DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 ' +
'CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B ' +
'C0BA6CAD EDB88320 9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 ' +
'73DC1683 E3630B12 94643B84 0D6D6A3E 7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 ' +
'7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D 806567CB 196C3671 ' +
'6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 ' +
'60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD ' +
'48B2364B D80D2BDA AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF ' +
'4669BE79 CB61B38C BC66831A 256FD2A0 5268E236 CC0C7795 BB0B4703 220216B9 ' +
'5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 B5D0CF31 2CD99E8B ' +
'5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 ' +
'05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 ' +
'0BDBDF21 86D3D2D4 F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 ' +
'18B74777 88085AE6 FF0F6A70 66063BCA 11010B5C 8F659EFF F862AE69 616BFFD3 ' +
'166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 D06016F7 4969474D ' +
'3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F ' +
'30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 ' +
'23D967BF B3667A2E C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B ' +
'2D02EF8D';
/**
* @returns Number
*/
function crc32(str) {
var crc = 0;
var n = 0;
var x = 0;
crc = crc ^ (-1);
for (var i = 0, iTop = str.length; i < iTop; i++) {
n = (crc ^ str.charCodeAt(i)) & 0xFF;
x = "0x" + table.substr(n * 9, 8);
crc = (crc >>> 8) ^ x;
}
return crc ^ (-1);
}
module.exports = crc32;
});
__d('XMLHttpRequestBase',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @flow
* @providesModule XMLHttpRequestBase
*/
'use strict';
/**
* Shared base for platform-specific XMLHttpRequest implementations.
*/
function XMLHttpRequestBase() {
this.UNSENT = 0;
this.OPENED = 1;
this.HEADERS_RECEIVED = 2;
this.LOADING = 3;
this.DONE = 4;
this.onreadystatechange = undefined;
this.upload = undefined; /* Upload not supported */
this.readyState = this.UNSENT;
this.responseHeaders = undefined;
this.responseText = undefined;
this.status = undefined;
this.$XMLHttpRequestBase_method = null;
this.$XMLHttpRequestBase_url = null;
this.$XMLHttpRequestBase_headers = {};
this.$XMLHttpRequestBase_sent = false;
this.$XMLHttpRequestBase_aborted = false;
}
XMLHttpRequestBase.prototype.getAllResponseHeaders=function() {
if (this.responseHeaders) {
var headers = [];
for (var headerName in this.responseHeaders) {
headers.push(headerName + ': ' + this.responseHeaders[headerName]);
}
return headers.join('\n');
}
// according to the spec, return null <==> no response has been received
return null;
};
XMLHttpRequestBase.prototype.getResponseHeader=function(header ) {
if (this.responseHeaders) {
var value = this.responseHeaders[header.toLowerCase()];
return value !== undefined ? value : null;
}
return null;
};
XMLHttpRequestBase.prototype.setRequestHeader=function(header , value ) {
this.$XMLHttpRequestBase_headers[header] = value;
};
XMLHttpRequestBase.prototype.open=function(method , url , async ) {
/* Other optional arguments are not supported */
if (this.readyState !== this.UNSENT) {
throw new Error('Cannot open, already sending');
}
if (async !== undefined && !async) {
// async is default
throw new Error('Synchronous http requests are not supported');
}
this.$XMLHttpRequestBase_method = method;
this.$XMLHttpRequestBase_url = url;
this.$XMLHttpRequestBase_aborted = false;
this.$XMLHttpRequestBase_setReadyState(this.OPENED);
};
XMLHttpRequestBase.prototype.sendImpl=function(method , url , headers , data ) {
throw new Error('Subclass must define sendImpl method');
};
XMLHttpRequestBase.prototype.abortImpl=function() {
throw new Error('Subclass must define abortImpl method');
};
XMLHttpRequestBase.prototype.send=function(data ) {
if (this.readyState !== this.OPENED) {
throw new Error('Request has not been opened');
}
if (this.$XMLHttpRequestBase_sent) {
throw new Error('Request has already been sent');
}
this.$XMLHttpRequestBase_sent = true;
this.sendImpl(this.$XMLHttpRequestBase_method, this.$XMLHttpRequestBase_url, this.$XMLHttpRequestBase_headers, data);
};
XMLHttpRequestBase.prototype.abort=function() {
this.abortImpl();
// only call onreadystatechange if there is something to abort,
// below logic is per spec
if (!(this.readyState === this.UNSENT ||
(this.readyState === this.OPENED && !this.$XMLHttpRequestBase_sent) ||
this.readyState === this.DONE)) {
this.$XMLHttpRequestBase_sent = false;
this.$XMLHttpRequestBase_setReadyState(this.DONE);
}
if (this.readyState === this.DONE) {
this.$XMLHttpRequestBase_sendLoad();
}
this.readyState = this.UNSENT;
this.$XMLHttpRequestBase_aborted = true;
};
XMLHttpRequestBase.prototype.callback=function(status , responseHeaders , responseText ) {
if (this.$XMLHttpRequestBase_aborted) {
return;
}
this.status = status;
// Headers should be case-insensitive
var lcResponseHeaders = {};
for (var header in responseHeaders) {
lcResponseHeaders[header.toLowerCase()] = responseHeaders[header];
}
this.responseHeaders = lcResponseHeaders;
this.responseText = responseText;
this.$XMLHttpRequestBase_setReadyState(this.DONE);
this.$XMLHttpRequestBase_sendLoad();
};
XMLHttpRequestBase.prototype.$XMLHttpRequestBase_setReadyState=function(newState ) {
this.readyState = newState;
// TODO: workaround flow bug with nullable function checks
var onreadystatechange = this.onreadystatechange;
if (onreadystatechange) {
// We should send an event to handler, but since we don't process that
// event anywhere, let's leave it empty
onreadystatechange(null);
}
};
XMLHttpRequestBase.prototype.$XMLHttpRequestBase_sendLoad=function() {
// TODO: workaround flow bug with nullable function checks
var onload = this.onload;
if (onload) {
// We should send an event to handler, but since we don't process that
// event anywhere, let's leave it empty
onload(null);
}
};
module.exports = XMLHttpRequestBase;
});
__d('fetch',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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.
*
* This is a third-party polyfill grabbed from:
* https://github.com/github/fetch
*
* @providesModule fetch
* @nolint
*/
'use strict';
var self = {};
/**
* Copyright (c) 2014 GitHub, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* @preserve-header
*/
(function() {
'use strict';
if (self.fetch) {
return
}
function normalizeName(name) {
if (typeof name !== 'string') {
name = name.toString();
}
if (/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) {
throw new TypeError('Invalid character in header field name')
}
return name.toLowerCase()
}
function normalizeValue(value) {
if (typeof value !== 'string') {
value = value.toString();
}
return value
}
function Headers(headers) {
this.map = {}
var self = this
if (headers instanceof Headers) {
headers.forEach(function(name, values) {
values.forEach(function(value) {
self.append(name, value)
})
})
} else if (headers) {
Object.getOwnPropertyNames(headers).forEach(function(name) {
self.append(name, headers[name])
})
}
}
Headers.prototype.append = function(name, value) {
name = normalizeName(name)
value = normalizeValue(value)
var list = this.map[name]
if (!list) {
list = []
this.map[name] = list
}
list.push(value)
}
Headers.prototype['delete'] = function(name) {
delete this.map[normalizeName(name)]
}
Headers.prototype.get = function(name) {
var values = this.map[normalizeName(name)]
return values ? values[0] : null
}
Headers.prototype.getAll = function(name) {
return this.map[normalizeName(name)] || []
}
Headers.prototype.has = function(name) {
return this.map.hasOwnProperty(normalizeName(name))
}
Headers.prototype.set = function(name, value) {
this.map[normalizeName(name)] = [normalizeValue(value)]
}
// Instead of iterable for now.
Headers.prototype.forEach = function(callback) {
var self = this
Object.getOwnPropertyNames(this.map).forEach(function(name) {
callback(name, self.map[name])
})
}
function consumed(body) {
if (body.bodyUsed) {
return Promise.reject(new TypeError('Already read'))
}
body.bodyUsed = true
}
function fileReaderReady(reader) {
return new Promise(function(resolve, reject) {
reader.onload = function() {
resolve(reader.result)
}
reader.onerror = function() {
reject(reader.error)
}
})
}
function readBlobAsArrayBuffer(blob) {
var reader = new FileReader()
reader.readAsArrayBuffer(blob)
return fileReaderReady(reader)
}
function readBlobAsText(blob) {
var reader = new FileReader()
reader.readAsText(blob)
return fileReaderReady(reader)
}
var support = {
blob: 'FileReader' in self && 'Blob' in self && (function() {
try {
new Blob();
return true
} catch(e) {
return false
}
})(),
formData: 'FormData' in self
}
function Body() {
this.bodyUsed = false
this._initBody = function(body) {
this._bodyInit = body
if (typeof body === 'string') {
this._bodyText = body
} else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
this._bodyBlob = body
} else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
this._bodyFormData = body
} else if (!body) {
this._bodyText = ''
} else {
throw new Error('unsupported BodyInit type')
}
}
if (support.blob) {
this.blob = function() {
var rejected = consumed(this)
if (rejected) {
return rejected
}
if (this._bodyBlob) {
return Promise.resolve(this._bodyBlob)
} else if (this._bodyFormData) {
throw new Error('could not read FormData body as blob')
} else {
return Promise.resolve(new Blob([this._bodyText]))
}
}
this.arrayBuffer = function() {
return this.blob().then(readBlobAsArrayBuffer)
}
this.text = function() {
var rejected = consumed(this)
if (rejected) {
return rejected
}
if (this._bodyBlob) {
return readBlobAsText(this._bodyBlob)
} else if (this._bodyFormData) {
throw new Error('could not read FormData body as text')
} else {
return Promise.resolve(this._bodyText)
}
}
} else {
this.text = function() {
var rejected = consumed(this)
return rejected ? rejected : Promise.resolve(this._bodyText)
}
}
if (support.formData) {
this.formData = function() {
return this.text().then(decode)
}
}
this.json = function() {
return this.text().then(JSON.parse)
}
return this
}
// HTTP methods whose capitalization should be normalized
var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']
function normalizeMethod(method) {
var upcased = method.toUpperCase()
return (methods.indexOf(upcased) > -1) ? upcased : method
}
function Request(url, options) {
options = options || {}
this.url = url
this.credentials = options.credentials || 'omit'
this.headers = new Headers(options.headers)
this.method = normalizeMethod(options.method || 'GET')
this.mode = options.mode || null
this.referrer = null
if ((this.method === 'GET' || this.method === 'HEAD') && options.body) {
throw new TypeError('Body not allowed for GET or HEAD requests')
}
this._initBody(options.body)
}
function decode(body) {
var form = new FormData()
body.trim().split('&').forEach(function(bytes) {
if (bytes) {
var split = bytes.split('=')
var name = split.shift().replace(/\+/g, ' ')
var value = split.join('=').replace(/\+/g, ' ')
form.append(decodeURIComponent(name), decodeURIComponent(value))
}
})
return form
}
function headers(xhr) {
var head = new Headers()
var pairs = xhr.getAllResponseHeaders().trim().split('\n')
pairs.forEach(function(header) {
var split = header.trim().split(':')
var key = split.shift().trim()
var value = split.join(':').trim()
head.append(key, value)
})
return head
}
Body.call(Request.prototype)
function Response(bodyInit, options) {
if (!options) {
options = {}
}
this._initBody(bodyInit)
this.type = 'default'
this.url = null
this.status = options.status
this.ok = this.status >= 200 && this.status < 300
this.statusText = options.statusText
this.headers = options.headers instanceof Headers ? options.headers : new Headers(options.headers)
this.url = options.url || ''
}
Body.call(Response.prototype)
self.Headers = Headers;
self.Request = Request;
self.Response = Response;
self.fetch = function(input, init) {
// TODO: Request constructor should accept input, init
var request
if (Request.prototype.isPrototypeOf(input) && !init) {
request = input
} else {
request = new Request(input, init)
}
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest()
if (request.credentials === 'cors') {
xhr.withCredentials = true;
}
function responseURL() {
if ('responseURL' in xhr) {
return xhr.responseURL
}
// Avoid security warnings on getResponseHeader when not allowed by CORS
if (/^X-Request-URL:/m.test(xhr.getAllResponseHeaders())) {
return xhr.getResponseHeader('X-Request-URL')
}
return;
}
xhr.onload = function() {
var status = (xhr.status === 1223) ? 204 : xhr.status
if (status < 100 || status > 599) {
reject(new TypeError('Network request failed'))
return
}
var options = {
status: status,
statusText: xhr.statusText,
headers: headers(xhr),
url: responseURL()
}
var body = 'response' in xhr ? xhr.response : xhr.responseText;
resolve(new Response(body, options))
}
xhr.onerror = function() {
reject(new TypeError('Network request failed'))
}
xhr.open(request.method, request.url, true)
if ('responseType' in xhr && support.blob) {
xhr.responseType = 'blob'
}
request.headers.forEach(function(name, values) {
values.forEach(function(value) {
xhr.setRequestHeader(name, value)
})
})
xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit)
})
}
self.fetch.polyfill = true
})();
/** End of the third-party code */
module.exports = self;
});
__d('Geolocation',["RCTDeviceEventEmitter","NativeModules","invariant","logError","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 Geolocation
* @flow
*/
'use strict';
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
var RCTLocationObserver = require('NativeModules').LocationObserver;
var invariant = require('invariant');
var logError = require('logError');
var warning = require('warning');
var subscriptions = [];
var updatesEnabled = false;
/**
* You need to include the `NSLocationWhenInUseUsageDescription` key
* in Info.plist to enable geolocation. Geolocation is enabled by default
* when you create a project with `react-native init`.
*
* Geolocation follows the MDN specification:
* https://developer.mozilla.org/en-US/docs/Web/API/Geolocation
*/
var Geolocation = {
/*
* Invokes the success callback once with the latest location info. Supported
* options: timeout (ms), maximumAge (ms), enableHighAccuracy (bool)
*/
getCurrentPosition: function(
geo_success ,
geo_error ,
geo_options
) {
invariant(
typeof geo_success === 'function',
'Must provide a valid geo_success callback.'
);
RCTLocationObserver.getCurrentPosition(
geo_options || {},
geo_success,
geo_error || logError
);
},
/*
* Invokes the success callback whenever the location changes. Supported
* options: timeout (ms), maximumAge (ms), enableHighAccuracy (bool)
*/
watchPosition: function(success , error , options ) {
if (!updatesEnabled) {
RCTLocationObserver.startObserving(options || {});
updatesEnabled = true;
}
var watchID = subscriptions.length;
subscriptions.push([
RCTDeviceEventEmitter.addListener(
'geolocationDidChange',
success
),
error ? RCTDeviceEventEmitter.addListener(
'geolocationError',
error
) : null,
]);
return watchID;
},
clearWatch: function(watchID ) {
var sub = subscriptions[watchID];
if (!sub) {
// Silently exit when the watchID is invalid or already cleared
// This is consistent with timers
return;
}
sub[0].remove();
// array element refinements not yet enabled in Flow
var sub1 = sub[1]; sub1 && sub1.remove();
subscriptions[watchID] = undefined;
var noWatchers = true;
for (var ii = 0; ii < subscriptions.length; ii++) {
if (subscriptions[ii]) {
noWatchers = false; // still valid subscriptions
}
}
if (noWatchers) {
Geolocation.stopObserving();
}
},
stopObserving: function() {
if (updatesEnabled) {
RCTLocationObserver.stopObserving();
updatesEnabled = false;
for (var ii = 0; ii < subscriptions.length; ii++) {
var sub = subscriptions[ii];
if (sub) {
warning('Called stopObserving with existing subscriptions.');
sub[0].remove();
// array element refinements not yet enabled in Flow
var sub1 = sub[1]; sub1 && sub1.remove();
}
}
subscriptions = [];
}
}
}
module.exports = Geolocation;
});
__d('logError',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 logError
* @flow
*/
'use strict';
/**
* Small utility that can be used as an error handler. You cannot just pass
* `console.error` as a failure callback - it's not properly bound. If passes an
* `Error` object, it will print the message and stack.
*/
var logError = function() {
if (arguments.length === 1 && arguments[0] instanceof Error) {
var err = arguments[0];
console.error('Error: "' + err.message + '". Stack:\n' + err.stack);
} else {
console.error.apply(console, arguments);
}
};
module.exports = logError;
});
__d('EventPluginHub',["EventPluginRegistry","EventPluginUtils","accumulateInto","forEachAccumulated","invariant"],function(global, require, requireDynamic, requireLazy, 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 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;
invariant(
valid,
'InstanceHandle not injected before use!'
);
}
/**
* 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 (__DEV__) {
validateInstanceHandle();
}
},
getInstanceHandle: function() {
if (__DEV__) {
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) {
invariant(
!listener || typeof listener === 'function',
'Expected %s listener to be a function, instead got type %s',
registrationName, typeof listener
);
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);
invariant(
!eventQueue,
'processEventQueue(): Additional events were enqueued while processing ' +
'an event queue. Support for this has not yet been implemented.'
);
},
/**
* These are needed for tests only. Do not use!
*/
__purge: function() {
listenerBank = {};
},
__getListenerBank: function() {
return listenerBank;
}
};
module.exports = EventPluginHub;
});
__d('EventPluginRegistry',["invariant"],function(global, require, requireDynamic, requireLazy, 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 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);
invariant(
pluginIndex > -1,
'EventPluginRegistry: Cannot inject event plugins that do not exist in ' +
'the plugin ordering, `%s`.',
pluginName
);
if (EventPluginRegistry.plugins[pluginIndex]) {
continue;
}
invariant(
PluginModule.extractEvents,
'EventPluginRegistry: Event plugins must implement an `extractEvents` ' +
'method, but `%s` does not.',
pluginName
);
EventPluginRegistry.plugins[pluginIndex] = PluginModule;
var publishedEvents = PluginModule.eventTypes;
for (var eventName in publishedEvents) {
invariant(
publishEventForPlugin(
publishedEvents[eventName],
PluginModule,
eventName
),
'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.',
eventName,
pluginName
);
}
}
}
/**
* 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) {
invariant(
!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName),
'EventPluginHub: More than one plugin attempted to publish the same ' +
'event name, `%s`.',
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) {
invariant(
!EventPluginRegistry.registrationNameModules[registrationName],
'EventPluginHub: More than one plugin attempted to publish the same ' +
'registration name, `%s`.',
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) {
invariant(
!EventPluginOrder,
'EventPluginRegistry: Cannot inject event plugin ordering more than ' +
'once. You are likely trying to load more than one copy of React.'
);
// 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) {
invariant(
!namesToPlugins[pluginName],
'EventPluginRegistry: Cannot inject two different event plugins ' +
'using the same name, `%s`.',
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;
});
__d('EventPluginUtils',["EventConstants","invariant"],function(global, require, requireDynamic, requireLazy, 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 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 (__DEV__) {
invariant(
InjectedMount && InjectedMount.getNode,
'EventPluginUtils.injection.injectMount(...): Injected Mount module ' +
'is missing 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 (__DEV__) {
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;
invariant(
idsIsArr === listenersIsArr && IDsLen === listenersLen,
'EventPluginUtils: Invalid `event`.'
);
};
}
/**
* 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 (__DEV__) {
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 (__DEV__) {
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 (__DEV__) {
validateEventDispatches(event);
}
var dispatchListener = event._dispatchListeners;
var dispatchID = event._dispatchIDs;
invariant(
!Array.isArray(dispatchListener),
'executeDirectDispatch(...): Invalid `event`.'
);
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;
});
__d('EventConstants',["keyMirror"],function(global, require, requireDynamic, requireLazy, 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;
});
__d('accumulateInto',["invariant"],function(global, require, requireDynamic, requireLazy, 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 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) {
invariant(
next != null,
'accumulateInto(...): Accumulated items must not be null or undefined.'
);
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;
});
__d('forEachAccumulated',[],function(global, require, requireDynamic, requireLazy, 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;
});
__d('IOSDefaultEventPluginOrder',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 IOSDefaultEventPluginOrder
* @flow
*/
'use strict';
var IOSDefaultEventPluginOrder = [
'ResponderEventPlugin',
'IOSNativeBridgeEventPlugin'
];
module.exports = IOSDefaultEventPluginOrder;
});
__d('IOSNativeBridgeEventPlugin',["EventPropagators","NativeModules","SyntheticEvent","merge","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 IOSNativeBridgeEventPlugin
* @flow
*/
"use strict";
var EventPropagators = require('EventPropagators');
var NativeModules = require('NativeModules');
var SyntheticEvent = require('SyntheticEvent');
var merge = require('merge');
var warning = require('warning');
var RCTUIManager = NativeModules.UIManager;
var customBubblingEventTypes = RCTUIManager.customBubblingEventTypes;
var customDirectEventTypes = RCTUIManager.customDirectEventTypes;
var allTypesByEventName = {};
for (var bubblingTypeName in customBubblingEventTypes) {
allTypesByEventName[bubblingTypeName] = customBubblingEventTypes[bubblingTypeName];
}
for (var directTypeName in customDirectEventTypes) {
warning(
!customBubblingEventTypes[directTypeName],
"Event cannot be both direct and bubbling: %s",
directTypeName
);
allTypesByEventName[directTypeName] = customDirectEventTypes[directTypeName];
}
var IOSNativeBridgeEventPlugin = {
eventTypes: merge(customBubblingEventTypes, customDirectEventTypes),
/**
* @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 bubbleDispatchConfig = customBubblingEventTypes[topLevelType];
var directDispatchConfig = customDirectEventTypes[topLevelType];
var event = SyntheticEvent.getPooled(
bubbleDispatchConfig || directDispatchConfig,
topLevelTargetID,
nativeEvent
);
if (bubbleDispatchConfig) {
EventPropagators.accumulateTwoPhaseDispatches(event);
} else if (directDispatchConfig) {
EventPropagators.accumulateDirectDispatches(event);
} else {
return null;
}
return event;
}
};
module.exports = IOSNativeBridgeEventPlugin;
});
__d('EventPropagators',["EventConstants","EventPluginHub","accumulateInto","forEachAccumulated"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright 2013-2014 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 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 (__DEV__) {
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
);
}
}
/**
* Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID.
*/
function accumulateTwoPhaseDispatchesSingleSkipTarget(event) {
if (event && event.dispatchConfig.phasedRegistrationNames) {
EventPluginHub.injection.getInstanceHandle().traverseTwoPhaseSkipTarget(
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 accumulateTwoPhaseDispatchesSkipTarget(events) {
forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget);
}
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,
accumulateTwoPhaseDispatchesSkipTarget: accumulateTwoPhaseDispatchesSkipTarget,
accumulateDirectDispatches: accumulateDirectDispatches,
accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches
};
module.exports = EventPropagators;
});
__d('SyntheticEvent',["PooledClass","Object.assign","emptyFunction","getEventTarget"],function(global, require, requireDynamic, requireLazy, 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;
});
__d('getEventTarget',[],function(global, require, requireDynamic, requireLazy, 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;
});
__d('merge',["mergeInto"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* @generated SignedSource<<0e3063b19e14ed191102b1dffe45551f>>
*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* !! This file is a check-in of a static_upstream project! !!
* !! !!
* !! You should not modify this file directly. Instead: !!
* !! 1) Use `fjs use-upstream` to temporarily replace this with !!
* !! the latest version from upstream. !!
* !! 2) Make your changes, test them, etc. !!
* !! 3) Use `fjs push-upstream` to copy your changes back to !!
* !! static_upstream. !!
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
* Copyright 2013-2014 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 merge
*/
"use strict";
var mergeInto = require('mergeInto');
/**
* Shallow merges two structures into a return value, without mutating either.
*
* @param {?object} one Optional object with properties to merge from.
* @param {?object} two Optional object with properties to merge from.
* @return {object} The shallow extension of one by two.
*/
var merge = function(one, two) {
var result = {};
mergeInto(result, one);
mergeInto(result, two);
return result;
};
module.exports = merge;
});
__d('mergeInto',["mergeHelpers"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* @generated SignedSource<<d3caa35be27b17ea4dd4c76bef72d1ab>>
*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* !! This file is a check-in of a static_upstream project! !!
* !! !!
* !! You should not modify this file directly. Instead: !!
* !! 1) Use `fjs use-upstream` to temporarily replace this with !!
* !! the latest version from upstream. !!
* !! 2) Make your changes, test them, etc. !!
* !! 3) Use `fjs push-upstream` to copy your changes back to !!
* !! static_upstream. !!
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
* Copyright 2013-2014 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 mergeInto
* @typechecks static-only
*/
"use strict";
var mergeHelpers = require('mergeHelpers');
var checkMergeObjectArg = mergeHelpers.checkMergeObjectArg;
var checkMergeIntoObjectArg = mergeHelpers.checkMergeIntoObjectArg;
/**
* Shallow merges two structures by mutating the first parameter.
*
* @param {object|function} one Object to be merged into.
* @param {?object} two Optional object with properties to merge from.
*/
function mergeInto(one, two) {
checkMergeIntoObjectArg(one);
if (two != null) {
checkMergeObjectArg(two);
for (var key in two) {
if (!two.hasOwnProperty(key)) {
continue;
}
one[key] = two[key];
}
}
}
module.exports = mergeInto;
});
__d('mergeHelpers',["invariant","keyMirror"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* @generated SignedSource<<b68d78236d45828b3f7f7fcc740782a9>>
*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* !! This file is a check-in of a static_upstream project! !!
* !! !!
* !! You should not modify this file directly. Instead: !!
* !! 1) Use `fjs use-upstream` to temporarily replace this with !!
* !! the latest version from upstream. !!
* !! 2) Make your changes, test them, etc. !!
* !! 3) Use `fjs push-upstream` to copy your changes back to !!
* !! static_upstream. !!
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
* Copyright 2013-2014 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 mergeHelpers
*
* requiresPolyfills: Array.isArray
*/
"use strict";
var invariant = require('invariant');
var keyMirror = require('keyMirror');
/**
* Maximum number of levels to traverse. Will catch circular structures.
* @const
*/
var MAX_MERGE_DEPTH = 36;
/**
* We won't worry about edge cases like new String('x') or new Boolean(true).
* Functions are considered terminals, and arrays are not.
* @param {*} o The item/object/value to test.
* @return {boolean} true iff the argument is a terminal.
*/
var isTerminal = function(o) {
return typeof o !== 'object' || o === null;
};
var mergeHelpers = {
MAX_MERGE_DEPTH: MAX_MERGE_DEPTH,
isTerminal: isTerminal,
/**
* Converts null/undefined values into empty object.
*
* @param {?Object=} arg Argument to be normalized (nullable optional)
* @return {!Object}
*/
normalizeMergeArg: function(arg) {
return arg === undefined || arg === null ? {} : arg;
},
/**
* If merging Arrays, a merge strategy *must* be supplied. If not, it is
* likely the caller's fault. If this function is ever called with anything
* but `one` and `two` being `Array`s, it is the fault of the merge utilities.
*
* @param {*} one Array to merge into.
* @param {*} two Array to merge from.
*/
checkMergeArrayArgs: function(one, two) {
invariant(
Array.isArray(one) && Array.isArray(two),
'Tried to merge arrays, instead got %s and %s.',
one,
two
);
},
/**
* @param {*} one Object to merge into.
* @param {*} two Object to merge from.
*/
checkMergeObjectArgs: function(one, two) {
mergeHelpers.checkMergeObjectArg(one);
mergeHelpers.checkMergeObjectArg(two);
},
/**
* @param {*} arg
*/
checkMergeObjectArg: function(arg) {
invariant(
!isTerminal(arg) && !Array.isArray(arg),
'Tried to merge an object, instead got %s.',
arg
);
},
/**
* @param {*} arg
*/
checkMergeIntoObjectArg: function(arg) {
invariant(
(!isTerminal(arg) || typeof arg === 'function') && !Array.isArray(arg),
'Tried to merge into an object, instead got %s.',
arg
);
},
/**
* Checks that a merge was not given a circular object or an object that had
* too great of depth.
*
* @param {number} Level of recursion to validate against maximum.
*/
checkMergeLevel: function(level) {
invariant(
level < MAX_MERGE_DEPTH,
'Maximum deep merge depth exceeded. You may be attempting to merge ' +
'circular structures in an unsupported way.'
);
},
/**
* Checks that the supplied merge strategy is valid.
*
* @param {string} Array merge strategy.
*/
checkArrayStrategy: function(strategy) {
invariant(
strategy === undefined || strategy in mergeHelpers.ArrayStrategies,
'You must provide an array strategy to deep merge functions to ' +
'instruct the deep merge how to resolve merging two arrays.'
);
},
/**
* Set of possible behaviors of merge algorithms when encountering two Arrays
* that must be merged together.
* - `clobber`: The left `Array` is ignored.
* - `indexByIndex`: The result is achieved by recursively deep merging at
* each index. (not yet supported.)
*/
ArrayStrategies: keyMirror({
Clobber: true,
IndexByIndex: true
})
};
module.exports = mergeHelpers;
});
__d('NodeHandle',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* @providesModule NodeHandle
*/
/**
* A "handle" is a serializable representation of the underlying platform's
* native node abstraction. This allows reasoning about nodes behind a thread
* (worker) boundary. On some platforms (DOM main thread) the node handle *is*
* an actual DOM node - `NodeHandle` (and potentially other libraries)
* abstract away those differences so you can write code that doesn't depend
* on whether or not you are running in a worker. For example, you could write
* application code:
*
*
* SomeLibrary.measureNodeHandle(myNodeHandle, cb)
*
* Where `measureNodeHandle` knows how to handle actual DOM nodes if running
* in a worker thread, and knows how to handle numeric IDs if running in a
* worker thread.
*
* The only other requirement of a platform/environment is that it always be
* possible to extract the React rootNodeID in a blocking manner (see
* `getRootNodeID`).
*
* +------------------+ +------------------+ +------------------+
* | | | | | |
* | ReactJS | | YourUtilities | | Animation Utils |
* | | | | | |
* +------------------+ +------------------+ +------------------+
*
* +------------------------------------------------------------+
* | Async Platform Independent Node Interface |
* +------------------------------------------------------------+
* | |
* | NodeIterface: |
* | -measure(nodeHandle, cb) |
* | -setProperties(nodeHandle, cb) |
* | -manageChildren(nodeHandle, nodeHandles, cb) |
* | ... |
* | |
* | Note: This may be a simplification. We could break up much |
* | of this functionality into several smaller libraries, each |
* | one requiring a . |
* +------------------------------------------------------------+
*
* +------------------------------------------------------------+
* | Platform Implementations |
* | ----------------------------------------- |
* | React Canvas | React DOM Worker | React DOM main |
* +------------------------------------------------------------+
* | | | |
* |-measure(..) |-measure(..) |-measure(..) |
* |-setProperties(..) |-setProperties(..) |-setProperties(..) |
* |-manageChildren(..)|-manageChildren(..) |-manageChildren(..)|
* | ... | ... | ... |
* +-----------------------------o------------------------------+
* | Worker simply ^
* | marshals commands |
* | to Web DOM thread. |
* +---------------------+
*/
var NodeHandle = {
/**
* Injection
*/
injection: {
injectImplementation: function(Impl) {
NodeHandle._Implementation = Impl;
}
},
_Implementation: null,
/**
* @param {NodeHandle} nodeHandle The handle to the low level resource.
* @return {string} React root node ID.
*/
getRootNodeID: function(nodeHandle) {
return NodeHandle._Implementation.getRootNodeID(nodeHandle);
}
};
module.exports = NodeHandle;
});
__d('ReactComponentEnvironment',["invariant"],function(global, require, requireDynamic, requireLazy, 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 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) {
invariant(
!injected,
'ReactCompositeComponent: injectEnvironment() can only be called once.'
);
ReactComponentEnvironment.unmountIDFromEnvironment =
environment.unmountIDFromEnvironment;
ReactComponentEnvironment.replaceNodeWithMarkupByID =
environment.replaceNodeWithMarkupByID;
ReactComponentEnvironment.processChildrenUpdates =
environment.processChildrenUpdates;
injected = true;
}
}
};
module.exports = ReactComponentEnvironment;
});
__d('ReactDefaultBatchingStrategy',["ReactUpdates","Transaction","Object.assign","emptyFunction"],function(global, require, requireDynamic, requireLazy, 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;
});
__d('ReactEmptyComponent',["ReactElement","ReactInstanceMap","invariant"],function(global, require, requireDynamic, requireLazy, 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 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() {
invariant(
component,
'Trying to return null from a render, but no null placeholder component ' +
'was injected.'
);
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;
});
__d('ReactIOSComponentEnvironment',["ReactIOSDOMIDOperations","ReactIOSReconcileTransaction"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 ReactIOSComponentEnvironment
* @flow
*/
'use strict';
var ReactIOSDOMIDOperations = require('ReactIOSDOMIDOperations');
var ReactIOSReconcileTransaction = require('ReactIOSReconcileTransaction');
var ReactIOSComponentEnvironment = {
processChildrenUpdates: ReactIOSDOMIDOperations.dangerouslyProcessChildrenUpdates,
replaceNodeWithMarkupByID: ReactIOSDOMIDOperations.dangerouslyReplaceNodeWithMarkupByID,
/**
* Nothing to do for UIKit bridge.
*
* @private
*/
unmountIDFromEnvironment: function(/*rootNodeID*/) {
},
/**
* @param {DOMElement} Element to clear.
*/
clearNode: function(/*containerView*/) {
},
ReactReconcileTransaction: ReactIOSReconcileTransaction,
};
module.exports = ReactIOSComponentEnvironment;
});
__d('ReactIOSDOMIDOperations',["ReactIOSTagHandles","ReactMultiChildUpdateTypes","NativeModules","ReactPerf"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 ReactIOSDOMIDOperations
* @flow
*/
"use strict";
var ReactIOSTagHandles = require('ReactIOSTagHandles');
var ReactMultiChildUpdateTypes = require('ReactMultiChildUpdateTypes');
var RCTUIManager = require('NativeModules').UIManager;
var ReactPerf = require('ReactPerf');
/**
* Updates a component's children by processing a series of updates.
* For each of the update/create commands, the `fromIndex` refers to the index
* that the item existed at *before* any of the updates are applied, and the
* `toIndex` refers to the index after *all* of the updates are applied
* (including deletes/moves). TODO: refactor so this can be shared with
* DOMChildrenOperations.
*
* @param {array<object>} updates List of update configurations.
* @param {array<string>} markup List of markup strings - in the case of React
* IOS, the ids of new components assumed to be already created.
*/
var dangerouslyProcessChildrenUpdates = function(childrenUpdates, markupList) {
if (!childrenUpdates.length) {
return;
}
var byContainerTag = {};
// Group by parent ID - send them across the bridge in separate commands per
// containerID.
for (var i = 0; i < childrenUpdates.length; i++) {
var update = childrenUpdates[i];
var containerTag = ReactIOSTagHandles.mostRecentMountedNodeHandleForRootNodeID(update.parentID);
var updates = byContainerTag[containerTag] || (byContainerTag[containerTag] = {});
if (update.type === ReactMultiChildUpdateTypes.MOVE_EXISTING) {
(updates.moveFromIndices || (updates.moveFromIndices = [])).push(update.fromIndex);
(updates.moveToIndices || (updates.moveToIndices = [])).push(update.toIndex);
} else if (update.type === ReactMultiChildUpdateTypes.REMOVE_NODE) {
(updates.removeAtIndices || (updates.removeAtIndices = [])).push(update.fromIndex);
} else if (update.type === ReactMultiChildUpdateTypes.INSERT_MARKUP) {
var mountImage = markupList[update.markupIndex];
var tag = mountImage.tag;
var rootNodeID = mountImage.rootNodeID;
ReactIOSTagHandles.associateRootNodeIDWithMountedNodeHandle(rootNodeID, tag);
(updates.addAtIndices || (updates.addAtIndices = [])).push(update.toIndex);
(updates.addChildTags || (updates.addChildTags = [])).push(tag);
}
}
// Note this enumeration order will be different on V8! Move `byContainerTag`
// to a sparse array as soon as we confirm there are not horrible perf
// penalties.
for (var updateParentTagString in byContainerTag) {
var updateParentTagNumber = +updateParentTagString;
var childUpdatesToSend = byContainerTag[updateParentTagNumber];
RCTUIManager.manageChildren(
updateParentTagNumber,
childUpdatesToSend.moveFromIndices,
childUpdatesToSend.moveToIndices,
childUpdatesToSend.addChildTags,
childUpdatesToSend.addAtIndices,
childUpdatesToSend.removeAtIndices
);
}
};
/**
* Operations used to process updates to DOM nodes. This is made injectable via
* `ReactComponent.DOMIDOperations`.
*/
var ReactIOSDOMIDOperations = {
dangerouslyProcessChildrenUpdates: ReactPerf.measure(
// FIXME(frantic): #4441289 Hack to avoid modifying react-tools
'ReactDOMIDOperations',
'dangerouslyProcessChildrenUpdates',
dangerouslyProcessChildrenUpdates
),
/**
* Replaces a view that exists in the document with markup.
*
* @param {string} id ID of child to be replaced.
* @param {string} markup Mount image to replace child with id.
*/
dangerouslyReplaceNodeWithMarkupByID: ReactPerf.measure(
'ReactDOMIDOperations',
'dangerouslyReplaceNodeWithMarkupByID',
function(id, mountImage) {
var oldTag = ReactIOSTagHandles.mostRecentMountedNodeHandleForRootNodeID(id);
RCTUIManager.replaceExistingNonRootView(oldTag, mountImage.tag);
ReactIOSTagHandles.associateRootNodeIDWithMountedNodeHandle(id, mountImage.tag);
}
),
};
module.exports = ReactIOSDOMIDOperations;
});
__d('ReactIOSTagHandles',["invariant","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 ReactIOSTagHandles
* @flow
*/
'use strict';
var invariant = require('invariant');
var warning = require('warning');
/**
* Keeps track of allocating and associating native "tags" which are numeric,
* unique view IDs. All the native tags are negative numbers, to avoid
* collisions, but in the JS we keep track of them as positive integers to store
* them effectively in Arrays. So we must refer to them as "inverses" of the
* native tags (that are * normally negative).
*
* It *must* be the case that every `rootNodeID` always maps to the exact same
* `tag` forever. The easiest way to accomplish this is to never delete
* anything from this table.
* Why: Because `dangerouslyReplaceNodeWithMarkupByID` relies on being able to
* unmount a component with a `rootNodeID`, then mount a new one in its place,
*/
var INITIAL_TAG_COUNT = 1;
var ReactIOSTagHandles = {
tagsStartAt: INITIAL_TAG_COUNT,
tagCount: INITIAL_TAG_COUNT,
allocateTag: function() {
// Skip over root IDs as those are reserved for native
while (this.reactTagIsNativeTopRootID(ReactIOSTagHandles.tagCount)) {
ReactIOSTagHandles.tagCount++;
}
var tag = ReactIOSTagHandles.tagCount;
ReactIOSTagHandles.tagCount++;
return tag;
},
/**
* This associates the *last* observed *native* mounting between `rootNodeID`
* and some `tag`. This association doesn't imply that `rootNodeID` is still
* natively mounted as `tag`. The only reason why we don't clear the
* association when the `rootNodeID` is unmounted, is that we don't have a
* convenient time to disassociate them (otherwise we would).
* `unmountComponent` isn't the correct time because that doesn't imply that
* the native node has been natively unmounted.
*/
associateRootNodeIDWithMountedNodeHandle: function(
rootNodeID ,
tag
) {
warning(rootNodeID && tag, 'Root node or tag is null when associating');
if (rootNodeID && tag) {
ReactIOSTagHandles.tagToRootNodeID[tag] = rootNodeID;
ReactIOSTagHandles.rootNodeIDToTag[rootNodeID] = tag;
}
},
allocateRootNodeIDForTag: function(tag ) {
invariant(
this.reactTagIsNativeTopRootID(tag),
'Expect a native root tag, instead got ', tag
);
return '.r[' + tag + ']{TOP_LEVEL}';
},
reactTagIsNativeTopRootID: function(reactTag ) {
// We reserve all tags that are 1 mod 10 for native root views
return reactTag % 10 === 1;
},
/**
* Returns the native `nodeHandle` (`tag`) that was most recently *natively*
* mounted at the `rootNodeID`. Just because a React component has been
* mounted, that doesn't mean that its native node has been mounted. The
* native node is mounted when we actually make the call to insert the
* `nodeHandle` (`tag`) into the native hierarchy.
*
* @param {string} rootNodeID Root node ID to find most recently mounted tag
* for. Again, this doesn't imply that it is still currently mounted.
* @return {number} Tag ID of native view for most recent mounting of
* `rootNodeID`.
*/
mostRecentMountedNodeHandleForRootNodeID: function(
rootNodeID
) {
return ReactIOSTagHandles.rootNodeIDToTag[rootNodeID];
},
tagToRootNodeID: ([] ),
rootNodeIDToTag: ({} )
};
module.exports = ReactIOSTagHandles;
});
__d('ReactMultiChildUpdateTypes',["keyMirror"],function(global, require, requireDynamic, requireLazy, 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;
});
__d('ReactIOSReconcileTransaction',["CallbackQueue","PooledClass","Transaction"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 ReactIOSReconcileTransaction
* @flow
*/
"use strict";
var CallbackQueue = require('CallbackQueue');
var PooledClass = require('PooledClass');
var Transaction = require('Transaction');
/**
* 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();
},
/**
* After DOM is flushed, invoke all registered `onDOMReady` callbacks.
*/
close: function() {
this.reactMountReady.notifyAll();
}
};
/**
* 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 = [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 ReactIOSReconcileTransaction
*/
function ReactIOSReconcileTransaction() {
this.reinitializeTransaction();
this.reactMountReady = CallbackQueue.getPooled(null);
}
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.
* TODO: convert to ReactMountReady
*/
getReactMountReady: function() {
return this.reactMountReady;
},
/**
* `PooledClass` looks for this, and will invoke this before allowing this
* instance to be resused.
*/
destructor: function() {
CallbackQueue.release(this.reactMountReady);
this.reactMountReady = null;
}
};
Object.assign(
ReactIOSReconcileTransaction.prototype,
Transaction.Mixin,
ReactIOSReconcileTransaction,
Mixin
);
PooledClass.addPoolingTo(ReactIOSReconcileTransaction);
module.exports = ReactIOSReconcileTransaction;
});
__d('ReactIOSComponentMixin',["ReactIOSTagHandles","ReactInstanceMap"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 ReactIOSComponentMixin
* @flow
*/
'use strict';
var ReactIOSTagHandles = require('ReactIOSTagHandles');
var ReactInstanceMap = require('ReactInstanceMap');
/**
* ReactNative vs ReactWeb
* -----------------------
* React treats some pieces of data opaquely. This means that the information
* is first class (it can be passed around), but cannot be inspected. This
* allows us to build infrastructure that reasons about resources, without
* making assumptions about the nature of those resources, and this allows that
* infra to be shared across multiple platforms, where the resources are very
* different. General infra (such as `ReactMultiChild`) reasons opaquely about
* the data, but platform specific code (such as `ReactIOSNativeComponent`) can
* make assumptions about the data.
*
*
* `rootNodeID`, uniquely identifies a position in the generated native view
* tree. Many layers of composite components (created with `React.createClass`)
* can all share the same `rootNodeID`.
*
* `nodeHandle`: A sufficiently unambiguous way to refer to a lower level
* resource (dom node, native view etc). The `rootNodeID` is sufficient for web
* `nodeHandle`s, because the position in a tree is always enough to uniquely
* identify a DOM node (we never have nodes in some bank outside of the
* document). The same would be true for `ReactNative`, but we must maintain a
* mapping that we can send efficiently serializable
* strings across native boundaries.
*
* Opaque name TodaysWebReact FutureWebWorkerReact ReactNative
* ----------------------------------------------------------------------------
* nodeHandle N/A rootNodeID tag
*
*
* `mountImage`: A way to represent the potential to create lower level
* resources whos `nodeHandle` can be discovered immediately by knowing the
* `rootNodeID`. Today's web React represents this with `innerHTML` annotated
* with DOM ids that match the `rootNodeID`.
*
* Opaque name TodaysWebReact FutureWebWorkerReact ReactNative
* ----------------------------------------------------------------------------
* mountImage innerHTML innerHTML {rootNodeID, tag}
*
*/
var ReactIOSComponentMixin = {
/**
* This has no particular meaning in ReactIOS. If this were in the DOM, this
* would return the DOM node. There should be nothing that invokes this
* method. Any current callers of this are mistaken - they should be invoking
* `getNodeHandle`.
*/
getNativeNode: function() {
// TODO (balpert): Wrap iOS native components in a composite wrapper, then
// ReactInstanceMap.get here will always succeed
return ReactIOSTagHandles.rootNodeIDToTag[
(ReactInstanceMap.get(this) || this)._rootNodeID
];
},
getNodeHandle: function() {
return ReactIOSTagHandles.rootNodeIDToTag[
(ReactInstanceMap.get(this) || this)._rootNodeID
];
}
};
module.exports = ReactIOSComponentMixin;
});
__d('ReactIOSGlobalInteractionHandler',["InteractionManager"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 ReactIOSGlobalInteractionHandler
* @flow
*/
'use strict';
var InteractionManager = require('InteractionManager');
// Interaction handle is created/cleared when responder is granted or
// released/terminated.
var interactionHandle = null;
var ReactIOSGlobalInteractionHandler = {
onChange: function(numberActiveTouches ) {
if (numberActiveTouches === 0) {
if (interactionHandle) {
InteractionManager.clearInteractionHandle(interactionHandle);
interactionHandle = null;
}
} else if (!interactionHandle) {
interactionHandle = InteractionManager.createInteractionHandle();
}
}
};
module.exports = ReactIOSGlobalInteractionHandler;
});
__d('InteractionManager',["ErrorUtils","EventEmitter","Set","invariant","keyMirror","setImmediate"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 InteractionManager
* @flow
*/
'use strict';
var ErrorUtils = require('ErrorUtils');
var EventEmitter = require('EventEmitter');
var Set = require('Set');
var invariant = require('invariant');
var keyMirror = require('keyMirror');
var setImmediate = require('setImmediate');
var _emitter = new EventEmitter();
var _interactionSet = new Set();
var _addInteractionSet = new Set();
var _deleteInteractionSet = new Set();
var _nextUpdateHandle = null;
var _queue = [];
var _inc = 0;
/**
* InteractionManager allows long-running work to be scheduled after any
* interactions/animations have completed. In particular, this allows JavaScript
* animations to run smoothly.
*
* Applications can schedule tasks to run after interactions with the following:
*
* ```
* InteractionManager.runAfterInteractions(() => {
* // ...long-running synchronous task...
* });
* ```
*
* Compare this to other scheduling alternatives:
*
* - requestAnimationFrame(): for code that animates a view over time.
* - setImmediate/setTimeout(): run code later, note this may delay animations.
* - runAfterInteractions(): run code later, without delaying active animations.
*
* The touch handling system considers one or more active touches to be an
* 'interaction' and will delay `runAfterInteractions()` callbacks until all
* touches have ended or been cancelled.
*
* InteractionManager also allows applications to register animations by
* creating an interaction 'handle' on animation start, and clearing it upon
* completion:
*
* ```
* var handle = InteractionManager.createInteractionHandle();
* // run animation... (`runAfterInteractions` tasks are queued)
* // later, on animation completion:
* InteractionManager.clearInteractionHandle(handle);
* // queued tasks run if all handles were cleared
* ```
*/
var InteractionManager = {
Events: keyMirror({
interactionStart: true,
interactionComplete: true,
}),
/**
* Schedule a function to run after all interactions have completed.
*/
runAfterInteractions:function(callback ) {
invariant(
typeof callback === 'function',
'Must specify a function to schedule.'
);
scheduleUpdate();
_queue.push(callback);
},
/**
* Notify manager that an interaction has started.
*/
createInteractionHandle:function() {
scheduleUpdate();
var handle = ++_inc;
_addInteractionSet.add(handle);
return handle;
},
/**
* Notify manager that an interaction has completed.
*/
clearInteractionHandle:function(handle ) {
invariant(
!!handle,
'Must provide a handle to clear.'
);
scheduleUpdate();
_addInteractionSet["delete"](handle);
_deleteInteractionSet.add(handle);
},
addListener: _emitter.addListener.bind(_emitter),
};
/**
* Schedule an asynchronous update to the interaction state.
*/
function scheduleUpdate() {
if (!_nextUpdateHandle) {
_nextUpdateHandle = setImmediate(processUpdate);
}
}
/**
* Notify listeners, process queue, etc
*/
function processUpdate() {
_nextUpdateHandle = null;
var interactionCount = _interactionSet.size;
_addInteractionSet.forEach(function(handle)
{return _interactionSet.add(handle);}
);
_deleteInteractionSet.forEach(function(handle)
{return _interactionSet["delete"](handle);}
);
var nextInteractionCount = _interactionSet.size;
if (interactionCount !== 0 && nextInteractionCount === 0) {
// transition from 1+ --> 0 interactions
_emitter.emit(InteractionManager.Events.interactionComplete);
} else if (interactionCount === 0 && nextInteractionCount !== 0) {
// transition from 0 --> 1+ interactions
_emitter.emit(InteractionManager.Events.interactionStart);
}
// process the queue regardless of a transition
if (nextInteractionCount === 0) {
var queue = _queue;
_queue = [];
queue.forEach(function(callback) {
ErrorUtils.applyWithGuard(callback);
});
}
_addInteractionSet.clear();
_deleteInteractionSet.clear();
}
module.exports = InteractionManager;
});
__d('Set',["Map","toIterator","_shouldPolyfillES6Collection"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* @generated SignedSource<<1fe20877e83ba5d4d0ea68ab240df21c>>
*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* !! This file is a check-in of a static_upstream project! !!
* !! !!
* !! You should not modify this file directly. Instead: !!
* !! 1) Use `fjs use-upstream` to temporarily replace this with !!
* !! the latest version from upstream. !!
* !! 2) Make your changes, test them, etc. !!
* !! 3) Use `fjs push-upstream` to copy your changes back to !!
* !! static_upstream. !!
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
* Copyright 2013-2014 Facebook, Inc.
* @providesModule Set
* @preventMunge
* @typechecks
*/
var Map = require('Map');
var toIterator = require('toIterator');
var _shouldPolyfillES6Collection = require('_shouldPolyfillES6Collection');
module.exports = (function(global, undefined) {
// Since our implementation is spec-compliant for the most part we can safely
// delegate to a built-in version if exists and is implemented correctly.
// Firefox had gotten a few implementation details wrong across different
// versions so we guard against that.
// These checks are adapted from es6-shim https://fburl.com/34437854
if (!_shouldPolyfillES6Collection('Set')) {
return global.Set;
}
/**
* == ES6 Set Collection ==
*
* This module is meant to implement a Set collection as described in chapter
* 23.2 of the ES6 specification.
*
* Set objects are collections of unique values. Where values can be any
* JavaScript value.
* https://people.mozilla.org/~jorendorff/es6-draft.html#sec-map-objects
*
* There only two -- rather small -- diviations from the spec:
*
* 1. The use of frozen objects as keys. @see Map module for more on this.
*
* 2. The `size` property on a map object is a regular property and not a
* computed property on the prototype as described by the spec.
* The reason being is that we simply want to support ES3 environments
* which doesn't implement computed properties.
*
* == Usage ==
*
* var set = new set(iterable);
*
* set.set(value);
* set.has(value); // true
* set.delete(value); // true
*
* var iterator = set.keys();
* iterator.next(); // {value: value, done: false}
*
* var iterator = set.values();
* iterator.next(); // {value: value, done: false}
*
* var iterator = set.entries();
* iterator.next(); // {value: [value, value], done: false}
*
* set.forEach(function(value, value){ this === thisArg }, thisArg);
*
* set.clear(); // resets set.
*/
/**
* 23.2.1.1
*
* Takes an optional `iterable` (which is basically any object that
* implements a Symbol.iterator (@@iterator) method). That is a collection
* of values used to instantiate the set.
*
* @param {*} iterable
*/
function Set(iterable) {"use strict";
if (this == null ||
(typeof this !== 'object' && typeof this !== 'function')) {
throw new TypeError('Wrong set object type.');
}
initSet(this);
if (iterable != null) {
var it = toIterator(iterable);
var next;
while (!(next = it.next()).done) {
this.add(next.value);
}
}
}
/**
* 23.2.3.1
*
* If it doesn't already exist in the collection a `value` is added.
*
* @param {*} value
* @return {set}
*/
Set.prototype.add=function(value) {"use strict";
this._map.set(value, value);
this.size = this._map.size;
return this;
};
/**
* 23.2.3.2
*
* Clears the set.
*/
Set.prototype.clear=function() {"use strict";
initSet(this);
};
/**
* 23.2.3.4
*
* Deletes a `value` from the collection if it exists.
* Returns true if the value was found and deleted and false otherwise.
*
* @param {*} value
* @return {boolean}
*/
Set.prototype["delete"]=function(value) {"use strict";
var ret = this._map["delete"](value);
this.size = this._map.size;
return ret;
};
/**
* 23.2.3.5
*
* Returns an iterator over a collection of [value, value] tuples.
*/
Set.prototype.entries=function() {"use strict";
return this._map.entries();
};
/**
* 23.2.3.6
*
* Iterate over the collection calling `callback` with (value, value, set).
*
* @param {function} callback
*/
Set.prototype.forEach=function(callback) {"use strict";
var thisArg = arguments[1];
var it = this._map.keys();
var next;
while (!(next = it.next()).done) {
callback.call(thisArg, next.value, next.value, this);
}
};
/**
* 23.2.3.7
*
* Iterate over the collection calling `callback` with (value, value, set).
*
* @param {*} value
* @return {boolean}
*/
Set.prototype.has=function(value) {"use strict";
return this._map.has(value);
};
/**
* 23.2.3.7
*
* Returns an iterator over the colleciton of values.
*/
Set.prototype.values=function() {"use strict";
return this._map.values();
};
// 23.2.3.11
Set.prototype[toIterator.ITERATOR_SYMBOL] = Set.prototype.values;
// 23.2.3.7
Set.prototype.keys = Set.prototype.values;
function initSet(set) {
set._map = new Map();
set.size = set._map.size;
}
return Set;
})(/* jslint evil: true */ Function('return this')());
});
__d('Map',["guid","isNode","toIterator","_shouldPolyfillES6Collection"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* @generated SignedSource<<375749f44ce7c0f681fc1297943eaf74>>
*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* !! This file is a check-in of a static_upstream project! !!
* !! !!
* !! You should not modify this file directly. Instead: !!
* !! 1) Use `fjs use-upstream` to temporarily replace this with !!
* !! the latest version from upstream. !!
* !! 2) Make your changes, test them, etc. !!
* !! 3) Use `fjs push-upstream` to copy your changes back to !!
* !! static_upstream. !!
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
* Copyright 2013-2014 Facebook, Inc.
* @providesModule Map
* @preventMunge
* @typechecks
*/
var guid = require('guid');
var isNode = require('isNode');
var toIterator = require('toIterator');
var _shouldPolyfillES6Collection = require('_shouldPolyfillES6Collection');
module.exports = (function(global, undefined) {
// Since our implementation is spec-compliant for the most part we can safely
// delegate to a built-in version if exists and is implemented correctly.
// Firefox had gotten a few implementation details wrong across different
// versions so we guard against that.
if (!_shouldPolyfillES6Collection('Map')) {
return global.Map;
}
/**
* == ES6 Map Collection ==
*
* This module is meant to implement a Map collection as described in chapter
* 23.1 of the ES6 specification.
*
* Map objects are collections of key/value pairs where both the keys and
* values may be arbitrary ECMAScript language values. A distinct key value
* may only occur in one key/value pair within the Map's collection.
*
* https://people.mozilla.org/~jorendorff/es6-draft.html#sec-map-objects
*
* There only two -- rather small -- diviations from the spec:
*
* 1. The use of frozen objects as keys.
* We decided not to allow and simply throw an error. The reason being is
* we store a "hash" on the object for fast access to it's place in the
* internal map entries.
* If this turns out to be a popular use case it's possible to implement by
* overiding `Object.freeze` to store a "hash" property on the object
* for later use with the map.
*
* 2. The `size` property on a map object is a regular property and not a
* computed property on the prototype as described by the spec.
* The reason being is that we simply want to support ES3 environments
* which doesn't implement computed properties.
*
* == Usage ==
*
* var map = new Map(iterable);
*
* map.set(key, value);
* map.get(key); // value
* map.has(key); // true
* map.delete(key); // true
*
* var iterator = map.keys();
* iterator.next(); // {value: key, done: false}
*
* var iterator = map.values();
* iterator.next(); // {value: value, done: false}
*
* var iterator = map.entries();
* iterator.next(); // {value: [key, value], done: false}
*
* map.forEach(function(value, key){ this === thisArg }, thisArg);
*
* map.clear(); // resets map.
*/
/**
* Constants
*/
// Kinds of map iterations 23.1.5.3
var KIND_KEY = 'key';
var KIND_VALUE = 'value';
var KIND_KEY_VALUE = 'key+value';
// In older browsers we can't create a null-prototype object so we have to
// defend against key collisions with built-in methods.
var KEY_PREFIX = '$map_';
// This property will be used as the internal size variable to disallow
// writing and to issue warnings for writings in development.
var SECRET_SIZE_PROP;
if (__DEV__) {
SECRET_SIZE_PROP = '$size' + guid();
}
// In oldIE we use the DOM Node `uniqueID` property to get create the hash.
var OLD_IE_HASH_PREFIX = 'IE_HASH_';
/**
* 23.1.1.1
* Takes an `iterable` which is basically any object that implements a
* Symbol.iterator (@@iterator) method. The iterable is expected to be a
* collection of pairs. Each pair is a key/value pair that will be used
* to instantiate the map.
*
* @param {*} iterable
*/
function Map(iterable) {"use strict";
if (!isObject(this)) {
throw new TypeError('Wrong map object type.');
}
initMap(this);
if (iterable != null) {
var it = toIterator(iterable);
var next;
while (!(next = it.next()).done) {
if (!isObject(next.value)) {
throw new TypeError('Expected iterable items to be pair objects.');
}
this.set(next.value[0], next.value[1]);
}
}
}
/**
* 23.1.3.1
* Clears the map from all keys and values.
*/
Map.prototype.clear=function() {"use strict";
initMap(this);
};
/**
* 23.1.3.7
* Check if a key exists in the collection.
*
* @param {*} key
* @return {boolean}
*/
Map.prototype.has=function(key) {"use strict";
var index = getIndex(this, key);
return !!(index != null && this._mapData[index]);
};
/**
* 23.1.3.9
* Adds a key/value pair to the collection.
*
* @param {*} key
* @param {*} value
* @return {map}
*/
Map.prototype.set=function(key, value) {"use strict";
var index = getIndex(this, key);
if (index != null && this._mapData[index]) {
this._mapData[index][1] = value;
} else {
index = this._mapData.push([
key,
value
]) - 1;
setIndex(this, key, index);
if (__DEV__) {
this[SECRET_SIZE_PROP] += 1;
} else {
this.size += 1;
}
}
return this;
};
/**
* 23.1.3.6
* Gets a value associated with a key in the collection.
*
* @param {*} key
* @return {*}
*/
Map.prototype.get=function(key) {"use strict";
var index = getIndex(this, key);
if (index == null) {
return undefined;
} else {
return this._mapData[index][1];
}
};
/**
* 23.1.3.3
* Delete a key/value from the collection.
*
* @param {*} key
* @return {boolean} Whether the key was found and deleted.
*/
Map.prototype["delete"]=function(key) {"use strict";
var index = getIndex(this, key);
if (index != null && this._mapData[index]) {
setIndex(this, key, undefined);
this._mapData[index] = undefined;
if (__DEV__) {
this[SECRET_SIZE_PROP] -= 1;
} else {
this.size -= 1;
}
return true;
} else {
return false;
}
};
/**
* 23.1.3.4
* Returns an iterator over the key/value pairs (in the form of an Array) in
* the collection.
*
* @return {MapIterator}
*/
Map.prototype.entries=function() {"use strict";
return new MapIterator(this, KIND_KEY_VALUE);
};
/**
* 23.1.3.8
* Returns an iterator over the keys in the collection.
*
* @return {MapIterator}
*/
Map.prototype.keys=function() {"use strict";
return new MapIterator(this, KIND_KEY);
};
/**
* 23.1.3.11
* Returns an iterator over the values pairs in the collection.
*
* @return {MapIterator}
*/
Map.prototype.values=function() {"use strict";
return new MapIterator(this, KIND_VALUE);
};
/**
* 23.1.3.5
* Iterates over the key/value pairs in the collection calling `callback`
* with [value, key, map]. An optional `thisArg` can be passed to set the
* context when `callback` is called.
*
* @param {function} callback
* @param {?object} thisArg
*/
Map.prototype.forEach=function(callback, thisArg) {"use strict";
if (typeof callback !== 'function') {
throw new TypeError('Callback must be callable.');
}
var boundCallback = callback.bind(thisArg || undefined);
var mapData = this._mapData;
// Note that `mapData.length` should be computed on each iteration to
// support iterating over new items in the map that were added after the
// start of the iteration.
for (var i = 0; i < mapData.length; i++) {
var entry = mapData[i];
if (entry != null) {
boundCallback(entry[1], entry[0], this);
}
}
};
// 23.1.3.12
Map.prototype[toIterator.ITERATOR_SYMBOL] = Map.prototype.entries;
/**
* 23.1.5.1
* Create a `MapIterator` for a given `map`. While this class is private it
* will create objects that will be passed around publicily.
*
* @param {map} map
* @param {string} kind
*/
function MapIterator(map, kind) {"use strict";
if (!(isObject(map) && map['_mapData'])) {
throw new TypeError('Object is not a map.');
}
if ([KIND_KEY, KIND_KEY_VALUE, KIND_VALUE].indexOf(kind) === -1) {
throw new Error('Invalid iteration kind.');
}
this._map = map;
this._nextIndex = 0;
this._kind = kind;
}
/**
* 23.1.5.2.1
* Get the next iteration.
*
* @return {object}
*/
MapIterator.prototype.next=function() {"use strict";
if (!this instanceof Map) {
throw new TypeError('Expected to be called on a MapIterator.');
}
var map = this._map;
var index = this._nextIndex;
var kind = this._kind;
if (map == null) {
return createIterResultObject(undefined, true);
}
var entries = map['_mapData'];
while (index < entries.length) {
var record = entries[index];
index += 1;
this._nextIndex = index;
if (record) {
if (kind === KIND_KEY) {
return createIterResultObject(record[0], false);
} else if (kind === KIND_VALUE) {
return createIterResultObject(record[1], false);
} else if (kind) {
return createIterResultObject(record, false);
}
}
}
this._map = undefined;
return createIterResultObject(undefined, true);
};
// We can put this in the class definition once we have computed props
// transform.
// 23.1.5.2.2
MapIterator.prototype[toIterator.ITERATOR_SYMBOL] = function() {
return this;
}
/**
* Helper Functions.
*/
/**
* Return an index to map.[[MapData]] array for a given Key.
*
* @param {map} map
* @param {*} key
* @return {?number}
*/
function getIndex(map, key) {
if (isObject(key)) {
var hash = getHash(key);
return map._objectIndex[hash];
} else {
var prefixedKey = KEY_PREFIX + key;
if (typeof key === 'string') {
return map._stringIndex[prefixedKey];
} else {
return map._otherIndex[prefixedKey];
}
}
}
/**
* Setup an index that refer to the key's location in map.[[MapData]].
*
* @param {map} map
* @param {*} key
*/
function setIndex(map, key, index) {
var shouldDelete = index == null;
if (isObject(key)) {
var hash = getHash(key);
if (shouldDelete) {
delete map._objectIndex[hash];
} else {
map._objectIndex[hash] = index;
}
} else {
var prefixedKey = KEY_PREFIX + key;
if (typeof key === 'string') {
if (shouldDelete) {
delete map._stringIndex[prefixedKey];
} else {
map._stringIndex[prefixedKey] = index;
}
} else {
if (shouldDelete) {
delete map._otherIndex[prefixedKey];
} else {
map._otherIndex[prefixedKey] = index;
}
}
}
}
/**
* Instantiate a map with internal slots.
*
* @param {map} map
*/
function initMap(map) {
// Data structure design inspired by Traceur's Map implementation.
// We maintain an internal array for all the entries. The array is needed
// to remember order. However, to have a reasonable HashMap performance
// i.e. O(1) for insertion, deletion, and retrieval. We maintain indices
// in objects for fast look ups. Indices are split up according to data
// types to avoid collisions.
map._mapData = [];
// Object index maps from an object "hash" to index. The hash being a unique
// property of our choosing that we associate with the object. Association
// is done by ways of keeping a non-enumerable property on the object.
// Ideally these would be `Object.create(null)` objects but since we're
// trying to support ES3 we'll have to gaurd against collisions using
// prefixes on the keys rather than rely on null prototype objects.
map._objectIndex = {};
// String index maps from strings to index.
map._stringIndex = {};
// Numbers, booleans, undefined, and null.
map._otherIndex = {};
// Unfortunately we have to support ES3 and cannot have `Map.prototype.size`
// be a getter method but just a regular method. The biggest problem with
// this is safety. Clients can change the size property easily and possibly
// without noticing (e.g. `if (map.size = 1) {..}` kind of typo). What we
// can do to mitigate use getters and setters in development to disallow
// and issue a warning for changing the `size` property.
if (__DEV__) {
if (isES5) {
// If the `SECRET_SIZE_PROP` property is already defined then we're not
// in the first call to `initMap` (e.g. coming from `map.clear()`) so
// all we need to do is reset the size without defining the properties.
if (map.hasOwnProperty(SECRET_SIZE_PROP)) {
map[SECRET_SIZE_PROP] = 0;
} else {
Object.defineProperty(map, SECRET_SIZE_PROP, {
value: 0,
writable: true
});
Object.defineProperty(map, 'size', {
set: function(v) {
console.error(
'PLEASE FIX ME: You are changing the map size property which ' +
'should not be writable and will break in production.'
);
throw new Error('The map size property is not writable.');
},
get: function() {return map[SECRET_SIZE_PROP];}
});
}
// NOTE: Early return to implement immutable `.size` in DEV.
return;
}
}
// This is a diviation from the spec. `size` should be a getter on
// `Map.prototype`. However, we have to support IE8.
map.size = 0;
}
/**
* Check if something is an object.
*
* @param {*} o
* @return {boolean}
*/
function isObject(o) {
return o != null && (typeof o === 'object' || typeof o === 'function');
}
/**
* Create an iteration object.
*
* @param {*} value
* @param {boolean} done
* @return {object}
*/
function createIterResultObject(value, done) {
return {value:value, done:done};
}
// Are we in a legit ES5 environment. Spoiler alert: that doesn't include IE8.
var isES5 = (function() {
try {
Object.defineProperty({}, 'x', {});
return true;
} catch(e) {
return false;
}
})();
/**
* Check if an object can be extended.
*
* @param {object|array|function|regexp} o
* @return {boolean}
*/
function isExtensible(o) {
if (!isES5) {
return true;
} else {
return Object.isExtensible(o);
}
}
/**
* IE has a `uniqueID` set on every DOM node. So we construct the hash from
* this uniqueID to avoid memory leaks and the IE cloneNode bug where it
* clones properties in addition to the attributes.
*
* @param {object} node
* @return {?string}
*/
function getIENodeHash(node) {
var uniqueID;
switch (node.nodeType) {
case 1: // Element
uniqueID = node.uniqueID;
break;
case 9: // Document
uniqueID = node.documentElement.uniqueID;
break;
default:
return null;
}
if (uniqueID) {
return OLD_IE_HASH_PREFIX + uniqueID;
} else {
return null;
}
}
var getHash = (function() {
var propIsEnumerable = Object.prototype.propertyIsEnumerable;
var hashProperty = guid();
var hashCounter = 0;
/**
* Get the "hash" associated with an object.
*
* @param {object|array|function|regexp} o
* @return {number}
*/
return function getHash(o) {
if (o[hashProperty]) {
return o[hashProperty];
} else if (!isES5 &&
o.propertyIsEnumerable &&
o.propertyIsEnumerable[hashProperty]) {
return o.propertyIsEnumerable[hashProperty];
} else if (!isES5 &&
isNode(o) &&
getIENodeHash(o)) {
return getIENodeHash(o);
} else if (!isES5 && o[hashProperty]) {
return o[hashProperty];
}
if (isExtensible(o)) {
hashCounter += 1;
if (isES5) {
Object.defineProperty(o, hashProperty, {
enumerable: false,
writable: false,
configurable: false,
value: hashCounter
});
} else if (o.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. Addiotionally, since this is a function it
// will not show up in `JSON.stringify` which is what we want.
o.propertyIsEnumerable = function() {
return propIsEnumerable.apply(this, arguments);
};
o.propertyIsEnumerable[hashProperty] = hashCounter;
} else if (isNode(o)) {
// 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 `hashProperty` on the node
// itself.
o[hashProperty] = hashCounter;
} else {
throw new Error('Unable to set a non-enumerable property on object.');
}
return hashCounter;
} else {
throw new Error('Non-extensible objects are not allowed as keys.');
}
};
})();
return Map;
})(/* jslint evil: true */ Function('return this')());
});
__d('guid',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* @generated SignedSource<<4425c6f5a34b56ee4707e090f43fd075>>
*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* !! This file is a check-in of a static_upstream project! !!
* !! !!
* !! You should not modify this file directly. Instead: !!
* !! 1) Use `fjs use-upstream` to temporarily replace this with !!
* !! the latest version from upstream. !!
* !! 2) Make your changes, test them, etc. !!
* !! 3) Use `fjs push-upstream` to copy your changes back to !!
* !! static_upstream. !!
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
* Copyright 2004-present Facebook. All Rights Reserved.
*
* Module that provides a function for creating a unique identifier.
* The returned value does not conform to the GUID standard, but should
* be globally unique in the context of the browser.
*
* @providesModule guid
*
*/
/*jshint bitwise: false*/
function guid() {
return 'f' + (Math.random() * (1 << 30)).toString(16).replace('.', '');
}
module.exports = guid;
});
__d('isNode',[],function(global, require, requireDynamic, requireLazy, 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;
});
__d('toIterator',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* @generated SignedSource<<32241616e13b8a54d1a7baadce8eae5d>>
*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* !! This file is a check-in of a static_upstream project! !!
* !! !!
* !! You should not modify this file directly. Instead: !!
* !! 1) Use `fjs use-upstream` to temporarily replace this with !!
* !! the latest version from upstream. !!
* !! 2) Make your changes, test them, etc. !!
* !! 3) Use `fjs push-upstream` to copy your changes back to !!
* !! static_upstream. !!
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule toIterator
*
*/
/**
* Given an object `toIterator` will return the itrator for that object. If the
* object has a `Symbol.iterator` method we just call that. Otherwise we
* implement the ES6 `Array` and `String` Iterator.
*/
/**
* Constants
*/
var KIND_KEY = 'key';
var KIND_VALUE = 'value';
var KIND_KEY_VAL = 'key+value';
/*global Symbol: true*/
var ITERATOR_SYMBOL = (typeof Symbol === 'function')
? Symbol.iterator
: '@@iterator';
var toIterator = (function() {
if (!(Array.prototype[ITERATOR_SYMBOL] &&
String.prototype[ITERATOR_SYMBOL])) {
// IIFE to avoid creating classes for no reason because of hoisting.
return (function() {
// 22.1.5.1 CreateArrayIterator Abstract Operation
function ArrayIterator(array, kind) {"use strict";
if (!Array.isArray(array)) {
throw new TypeError('Object is not an Array');
}
this.$ArrayIterator_iteratedObject = array;
this.$ArrayIterator_kind = kind;
this.$ArrayIterator_nextIndex = 0;
}
// 22.1.5.2.1 %ArrayIteratorPrototype%.next()
ArrayIterator.prototype.next=function() {"use strict";
if (!this instanceof ArrayIterator) {
throw new TypeError('Object is not an ArrayIterator');
}
if (this.$ArrayIterator_iteratedObject == null) {
return createIterResultObject(undefined, true);
}
var array = this.$ArrayIterator_iteratedObject;
var len = this.$ArrayIterator_iteratedObject.length;
var index = this.$ArrayIterator_nextIndex;
var kind = this.$ArrayIterator_kind;
if (index >= len) {
this.$ArrayIterator_iteratedObject = undefined;
return createIterResultObject(undefined, true);
}
this.$ArrayIterator_nextIndex = index + 1;
if (kind === KIND_KEY) {
return createIterResultObject(index, false);
} else if (kind === KIND_VALUE) {
return createIterResultObject(array[index], false);
} else if (kind === KIND_KEY_VAL) {
return createIterResultObject([index, array[index]], false);
}
};
// 22.1.5.2.2 %ArrayIteratorPrototype%[@@iterator]()
ArrayIterator.prototype["@@iterator"]=function() {"use strict";
return this;
};
// 21.1.5.1 CreateStringIterator Abstract Operation
function StringIterator(string) {"use strict";
if (typeof string !== 'string') {
throw new TypeError('Object is not a string');
}
this.$StringIterator_iteratedString = string;
this.$StringIterator_nextIndex = 0;
}
// 21.1.5.2.1 %StringIteratorPrototype%.next()
StringIterator.prototype.next=function() {"use strict";
if (!this instanceof StringIterator) {
throw new TypeError('Object is not a StringIterator');
}
if (this.$StringIterator_iteratedString == null) {
return createIterResultObject(undefined, true);
}
var index = this.$StringIterator_nextIndex;
var s = this.$StringIterator_iteratedString;
var len = s.length;
if (index >= len) {
this.$StringIterator_iteratedString = undefined;
return createIterResultObject(undefined, true);
}
var ret;
var first = s.charCodeAt(index);
if (first < 0xD800 || first > 0xDBFF || index + 1 === len) {
ret = s[index];
} else {
var second = s.charCodeAt(index + 1);
if (second < 0xDC00 || second > 0xDFFF) {
ret = s[index];
} else {
ret = s[index] + s[index + 1];
}
}
this.$StringIterator_nextIndex = index + ret.length;
return createIterResultObject(ret, false);
};
// 21.1.5.2.2 %StringIteratorPrototype%[@@ITERATOR_SYMBOL]()
StringIterator.prototype["@@iterator"]=function() {"use strict";
return this;
};
// 7.4.7 createIterResultObject(value, done)
function createIterResultObject(value, done) {
return {value: value, done: done};
}
return function(object, kind) {
if (typeof object === 'string') {
return new StringIterator(object);
} else if (Array.isArray(object)) {
return new ArrayIterator(object, kind || KIND_VALUE);
} else {
return object[ITERATOR_SYMBOL]();
}
};
})();
} else {
return function(object) {
return object[ITERATOR_SYMBOL]();
};
}
})();
/**
* Export constants
*/
Object.assign(toIterator, {
KIND_KEY:KIND_KEY,
KIND_VALUE:KIND_VALUE,
KIND_KEY_VAL:KIND_KEY_VAL,
ITERATOR_SYMBOL:ITERATOR_SYMBOL
});
module.exports = toIterator;
});
__d('_shouldPolyfillES6Collection',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* @generated SignedSource<<6c1a82d2f5918f03f3f0e5825e1f32f3>>
*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* !! This file is a check-in of a static_upstream project! !!
* !! !!
* !! You should not modify this file directly. Instead: !!
* !! 1) Use `fjs use-upstream` to temporarily replace this with !!
* !! the latest version from upstream. !!
* !! 2) Make your changes, test them, etc. !!
* !! 3) Use `fjs push-upstream` to copy your changes back to !!
* !! static_upstream. !!
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
* Copyright 2013-2014 Facebook, Inc.
* @providesModule _shouldPolyfillES6Collection
* @preventMunge
* @typechecks
*/
/**
* Given a collection class name (Map or Set) return whether it's safe to use
* the native polyfill.
*
* @param {string} collectionName
*/
function shouldPolyfillES6Collection(collectionName) {
var Collection = global[collectionName];
if (Collection == null) {
return true;
}
var proto = Collection.prototype;
// These checks are adapted from es6-shim https://fburl.com/34437854
return Collection == null ||
typeof Collection !== 'function' ||
typeof proto.clear !== 'function' ||
new Collection().size !== 0 ||
typeof proto.keys !== 'function' ||
typeof proto.forEach !== 'function' ||
isCallableWithoutNew(Collection) ||
!supportsSubclassing(Collection);
}
/**
* Given a class can we subclass it?
*
* @param {function} Collection
*/
function supportsSubclassing(Collection) {
for(var Collection____Key in Collection){if(Collection.hasOwnProperty(Collection____Key)){SubCollection[Collection____Key]=Collection[Collection____Key];}}var ____SuperProtoOfCollection=Collection===null?null:Collection.prototype;SubCollection.prototype=Object.create(____SuperProtoOfCollection);SubCollection.prototype.constructor=SubCollection;SubCollection.__superConstructor__=Collection;function SubCollection(){"use strict";if(Collection!==null){Collection.apply(this,arguments);}}
try {
var s = (new SubCollection([]));
// Firefox 32 will throw a type error when any operation is called on a
// subclass.
s.size;
return s instanceof Collection;
} catch (e) {
return false;
}
}
/**
* Given a constructor can we call it without `new`?
*
* @param {function} Collection
*/
function isCallableWithoutNew(Collection) {
try {
Collection();
} catch (e) {
return false;
}
return true;
}
module.exports = shouldPolyfillES6Collection;
});
__d('ReactIOSGlobalResponderHandler',["NativeModules","ReactIOSTagHandles"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 ReactIOSGlobalResponderHandler
* @flow
*/
'use strict';
var RCTUIManager = require('NativeModules').UIManager;
var ReactIOSTagHandles = require('ReactIOSTagHandles');
var ReactIOSGlobalResponderHandler = {
onChange: function(from , to ) {
if (to !== null) {
RCTUIManager.setJSResponder(
ReactIOSTagHandles.mostRecentMountedNodeHandleForRootNodeID(to)
);
} else {
RCTUIManager.clearJSResponder();
}
}
};
module.exports = ReactIOSGlobalResponderHandler;
});
__d('ReactIOSMount',["NativeModules","ReactIOSTagHandles","ReactPerf","ReactReconciler","ReactUpdateQueue","ReactUpdates","emptyObject","instantiateReactComponent","invariant","shouldUpdateReactComponent"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 ReactIOSMount
* @flow
*/
'use strict';
var RCTUIManager = require('NativeModules').UIManager;
var ReactIOSTagHandles = require('ReactIOSTagHandles');
var ReactPerf = require('ReactPerf');
var ReactReconciler = require('ReactReconciler');
var ReactUpdateQueue = require('ReactUpdateQueue');
var ReactUpdates = require('ReactUpdates');
var emptyObject = require('emptyObject');
var instantiateReactComponent = require('instantiateReactComponent');
var invariant = require('invariant');
var shouldUpdateReactComponent = require('shouldUpdateReactComponent');
function instanceNumberToChildRootID(rootNodeID, instanceNumber) {
return rootNodeID + '[' + instanceNumber + ']';
}
/**
* Mounts this component and inserts it into the DOM.
*
* @param {ReactComponent} componentInstance The instance to mount.
* @param {number} rootID ID of the root node.
* @param {number} container container element to mount into.
* @param {ReactReconcileTransaction} transaction
*/
function mountComponentIntoNode(
componentInstance,
rootID,
container,
transaction) {
var markup = ReactReconciler.mountComponent(
componentInstance, rootID, transaction, emptyObject
);
componentInstance._isTopLevel = true;
ReactIOSMount._mountImageIntoNode(markup, container);
}
/**
* Batched mount.
*
* @param {ReactComponent} componentInstance The instance to mount.
* @param {number} rootID ID of the root node.
* @param {number} container container element to mount into.
*/
function batchedMountComponentIntoNode(
componentInstance,
rootID,
container) {
var transaction = ReactUpdates.ReactReconcileTransaction.getPooled();
transaction.perform(
mountComponentIntoNode,
null,
componentInstance,
rootID,
container,
transaction
);
ReactUpdates.ReactReconcileTransaction.release(transaction);
}
/**
* As soon as `ReactMount` is refactored to not rely on the DOM, we can share
* code between the two. For now, we'll hard code the ID logic.
*/
var ReactIOSMount = {
instanceCount: 0,
_instancesByContainerID: {},
/**
* @param {ReactComponent} instance Instance to render.
* @param {containerTag} containerView Handle to native view tag
*/
renderComponent: function(
nextElement ,
containerTag ,
callback
) {
var topRootNodeID = ReactIOSTagHandles.tagToRootNodeID[containerTag];
if (topRootNodeID) {
var prevComponent = ReactIOSMount._instancesByContainerID[topRootNodeID];
if (prevComponent) {
var prevElement = prevComponent._currentElement;
if (shouldUpdateReactComponent(prevElement, nextElement)) {
ReactUpdateQueue.enqueueElementInternal(prevComponent, nextElement);
if (callback) {
ReactUpdateQueue.enqueueCallbackInternal(prevComponent, callback);
}
return prevComponent;
} else {
ReactIOSMount.unmountComponentAtNode(containerTag);
}
}
}
if (!ReactIOSTagHandles.reactTagIsNativeTopRootID(containerTag)) {
console.error('You cannot render into anything but a top root');
return;
}
var topRootNodeID = ReactIOSTagHandles.allocateRootNodeIDForTag(containerTag);
ReactIOSTagHandles.associateRootNodeIDWithMountedNodeHandle(
topRootNodeID,
containerTag
);
var instance = instantiateReactComponent(nextElement);
ReactIOSMount._instancesByContainerID[topRootNodeID] = instance;
var childRootNodeID = instanceNumberToChildRootID(
topRootNodeID,
ReactIOSMount.instanceCount++
);
// 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,
instance,
childRootNodeID,
topRootNodeID
);
var component = instance.getPublicInstance();
if (callback) {
callback.call(component);
}
return component;
},
/**
* @param {View} view View tree image.
* @param {number} containerViewID View to insert sub-view into.
*/
_mountImageIntoNode: ReactPerf.measure(
// FIXME(frantic): #4441289 Hack to avoid modifying react-tools
'ReactComponentBrowserEnvironment',
'mountImageIntoNode',
function(mountImage, containerID) {
// Since we now know that the `mountImage` has been mounted, we can
// mark it as such.
ReactIOSTagHandles.associateRootNodeIDWithMountedNodeHandle(
mountImage.rootNodeID,
mountImage.tag
);
var addChildTags = [mountImage.tag];
var addAtIndices = [0];
RCTUIManager.manageChildren(
ReactIOSTagHandles.mostRecentMountedNodeHandleForRootNodeID(containerID),
null, // moveFromIndices
null, // moveToIndices
addChildTags,
addAtIndices,
null // removeAtIndices
);
}
),
/**
* Standard unmounting of the component that is rendered into `containerID`,
* but will also execute a command to remove the actual container view
* itself. This is useful when a client is cleaning up a React tree, and also
* knows that the container will no longer be needed. When executing
* asynchronously, it's easier to just have this method be the one that calls
* for removal of the view.
*/
unmountComponentAtNodeAndRemoveContainer: function(
containerTag
) {
ReactIOSMount.unmountComponentAtNode(containerTag);
// call back into native to remove all of the subviews from this container
RCTUIManager.removeRootView(containerTag);
},
/**
* Unmount component at container ID by iterating through each child component
* that has been rendered and unmounting it. There should just be one child
* component at this time.
*/
unmountComponentAtNode: function(containerTag ) {
if (!ReactIOSTagHandles.reactTagIsNativeTopRootID(containerTag)) {
console.error('You cannot render into anything but a top root');
return false;
}
var containerID = ReactIOSTagHandles.tagToRootNodeID[containerTag];
var instance = ReactIOSMount._instancesByContainerID[containerID];
if (!instance) {
return false;
}
ReactIOSMount.unmountComponentFromNode(instance, containerID);
delete ReactIOSMount._instancesByContainerID[containerID];
return true;
},
/**
* Unmounts a component and sends messages back to iOS to remove its subviews.
*
* @param {ReactComponent} instance React component instance.
* @param {string} containerID ID of container we're removing from.
* @final
* @internal
* @see {ReactIOSMount.unmountComponentAtNode}
*/
unmountComponentFromNode: function(
instance ,
containerID
) {
// Call back into native to remove all of the subviews from this container
ReactReconciler.unmountComponent(instance);
var containerTag =
ReactIOSTagHandles.mostRecentMountedNodeHandleForRootNodeID(containerID);
RCTUIManager.removeSubviewsFromContainerWithID(containerTag);
},
getNode: function (id ) {
return id;
}
};
ReactIOSMount.renderComponent = ReactPerf.measure(
'ReactMount',
'_renderNewRootComponent',
ReactIOSMount.renderComponent
);
module.exports = ReactIOSMount;
});
__d('instantiateReactComponent',["ReactCompositeComponent","ReactEmptyComponent","ReactNativeComponent","Object.assign","invariant","warning"],function(global, require, requireDynamic, requireLazy, 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 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 (__DEV__) {
warning(
element && (typeof element.type === 'function' ||
typeof element.type === 'string'),
'Only functions or strings can be mounted as React components.'
);
}
// 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 {
invariant(
false,
'Encountered invalid React node of type %s',
typeof node
);
}
if (__DEV__) {
warning(
typeof instance.construct === 'function' &&
typeof instance.mountComponent === 'function' &&
typeof instance.receiveComponent === 'function' &&
typeof instance.unmountComponent === 'function',
'Only React Components can be mounted.'
);
}
// 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 (__DEV__) {
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 (__DEV__) {
if (Object.preventExtensions) {
Object.preventExtensions(instance);
}
}
return instance;
}
module.exports = instantiateReactComponent;
});
__d('ReactCompositeComponent',["ReactComponentEnvironment","ReactContext","ReactCurrentOwner","ReactElement","ReactElementValidator","ReactInstanceMap","ReactLifeCycle","ReactNativeComponent","ReactPerf","ReactPropTypeLocations","ReactPropTypeLocationNames","ReactReconciler","ReactUpdates","Object.assign","emptyObject","invariant","shouldUpdateReactComponent","warning"],function(global, require, requireDynamic, requireLazy, 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 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 (__DEV__) {
// This will throw later in _renderValidatedComponent, but add an early
// warning now to help debugging
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'
);
}
// 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 (__DEV__) {
this._warnIfContextsDiffer(this._currentElement._context, context);
}
if (__DEV__) {
// 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.
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'
);
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'
);
warning(
!inst.propTypes,
'propTypes was defined as an instance property on %s. Use a static ' +
'property to define propTypes instead.',
this.getName() || 'a component'
);
warning(
!inst.contextTypes,
'contextTypes was defined as an instance property on %s. Use a ' +
'static property to define contextTypes instead.',
this.getName() || 'a component'
);
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')
);
}
var initialState = inst.state;
if (initialState === undefined) {
inst.state = initialState = null;
}
invariant(
typeof initialState === 'object' && !Array.isArray(initialState),
'%s.state: must be set to an object or null',
this.getName() || 'ReactCompositeComponent'
);
this._pendingStateQueue = null;
this._pendingReplaceState = false;
this._pendingForceUpdate = false;
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);
}
}
renderedElement = this._renderValidatedComponent();
} finally {
ReactLifeCycle.currentlyMountingInstance = previouslyMounting;
}
this._renderedComponent = this._instantiateReactComponent(
renderedElement,
this._currentElement.type // The wrapping type
);
var markup = ReactReconciler.mountComponent(
this._renderedComponent,
rootID,
transaction,
this._processChildContext(context)
);
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 (__DEV__) {
var Component = ReactNativeComponent.getComponentClassForElement(
this._currentElement
);
if (Component.contextTypes) {
this._checkPropTypes(
Component.contextTypes,
maskedContext,
ReactPropTypeLocations.context
);
}
}
return maskedContext;
},
/**
* @param {object} currentContext
* @return {object}
* @private
*/
_processChildContext: function(currentContext) {
var inst = this._instance;
var childContext = inst.getChildContext && inst.getChildContext();
if (childContext) {
invariant(
typeof inst.constructor.childContextTypes === 'object',
'%s.getChildContext(): childContextTypes must be defined in order to ' +
'use getChildContext().',
this.getName() || 'ReactCompositeComponent'
);
if (__DEV__) {
this._checkPropTypes(
inst.constructor.childContextTypes,
childContext,
ReactPropTypeLocations.childContext
);
}
for (var name in childContext) {
invariant(
name in inst.constructor.childContextTypes,
'%s.getChildContext(): key "%s" is not defined in childContextTypes.',
this.getName() || 'ReactCompositeComponent',
name
);
}
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 (__DEV__) {
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.
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
);
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
warning(
false,
'Failed Composite propType: %s%s',
error.message,
addendum
);
} else {
warning(
false,
'Failed Context Types: %s%s',
error.message,
addendum
);
}
}
}
}
},
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 (__DEV__) {
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];
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
);
}
},
/**
* 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 (__DEV__) {
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 (__DEV__) {
warning(
typeof shouldUpdate !== 'undefined',
'%s.shouldComponentUpdate(): Returned undefined instead of a ' +
'boolean value. Make sure to return true or false.',
this.getName() || 'ReactCompositeComponent'
);
}
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;
}
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 nextRenderedElement = this._renderValidatedComponent();
if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) {
ReactReconciler.receiveComponent(
prevComponentInstance,
nextRenderedElement,
transaction,
this._processChildContext(context)
);
} 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._processChildContext(context)
);
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 (__DEV__) {
// 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() {
var renderedComponent;
var previousContext = ReactContext.current;
ReactContext.current = this._processChildContext(
this._currentElement._context
);
ReactCurrentOwner.current = this;
try {
renderedComponent =
this._renderValidatedComponentWithoutOwnerOrContext();
} finally {
ReactContext.current = previousContext;
ReactCurrentOwner.current = null;
}
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'
);
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;
});
__d('shouldUpdateReactComponent',["warning"],function(global, require, requireDynamic, requireLazy, 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 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 (__DEV__) {
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;
}
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
);
}
}
}
}
return ownersMatch;
}
}
}
return false;
}
module.exports = shouldUpdateReactComponent;
});
__d('ReactIOSTextComponent',["ReactIOSTagHandles","NativeModules","Object.assign"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 ReactIOSTextComponent
*/
'use strict';
var ReactIOSTagHandles = require('ReactIOSTagHandles');
var RCTUIManager = require('NativeModules').UIManager;
var assign = require('Object.assign');
var ReactIOSTextComponent = function(props) {
// This constructor and its argument is currently used by mocks.
};
assign(ReactIOSTextComponent.prototype, {
construct: function(text) {
// This is really a ReactText (ReactNode), not a ReactElement
this._currentElement = text;
this._stringText = '' + text;
this._rootNodeID = null;
},
mountComponent: function(rootID, transaction, context) {
this._rootNodeID = rootID;
var tag = ReactIOSTagHandles.allocateTag();
RCTUIManager.createView(tag, 'RCTRawText', {text: this._stringText});
return {
rootNodeID: rootID,
tag: tag,
};
},
receiveComponent: function(nextText, transaction, context) {
if (nextText !== this._currentElement) {
this._currentElement = nextText;
var nextStringText = '' + nextText;
if (nextStringText !== this._stringText) {
this._stringText = nextStringText;
RCTUIManager.updateView(
ReactIOSTagHandles.mostRecentMountedNodeHandleForRootNodeID(
this._rootNodeID
),
'RCTRawText',
{text: this._stringText}
);
}
}
},
unmountComponent: function() {
this._currentElement = null;
this._stringText = null;
this._rootNodeID = null;
}
});
module.exports = ReactIOSTextComponent;
});
__d('ResponderEventPlugin',["EventConstants","EventPluginUtils","EventPropagators","NodeHandle","ReactInstanceHandles","ResponderSyntheticEvent","ResponderTouchHistoryStore","accumulate","invariant","keyOf"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright 2013-2014 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 ResponderEventPlugin
*/
'use strict';
var EventConstants = require('EventConstants');
var EventPluginUtils = require('EventPluginUtils');
var EventPropagators = require('EventPropagators');
var NodeHandle = require('NodeHandle');
var ReactInstanceHandles = require('ReactInstanceHandles');
var ResponderSyntheticEvent = require('ResponderSyntheticEvent');
var ResponderTouchHistoryStore = require('ResponderTouchHistoryStore');
var accumulate = require('accumulate');
var invariant = require('invariant');
var keyOf = require('keyOf');
var isStartish = EventPluginUtils.isStartish;
var isMoveish = EventPluginUtils.isMoveish;
var isEndish = EventPluginUtils.isEndish;
var executeDirectDispatch = EventPluginUtils.executeDirectDispatch;
var hasDispatches = EventPluginUtils.hasDispatches;
var executeDispatchesInOrderStopAtTrue =
EventPluginUtils.executeDispatchesInOrderStopAtTrue;
/**
* ID of element that should respond to touch/move types of interactions, as
* indicated explicitly by relevant callbacks.
*/
var responderID = null;
/**
* Count of current touches. A textInput should become responder iff the
* the selection changes while there is a touch on the screen.
*/
var trackedTouchCount = 0;
/**
* Last reported number of active touches.
*/
var previousActiveTouches = 0;
var changeResponder = function(nextResponderID) {
var oldResponderID = responderID;
responderID = nextResponderID;
if (ResponderEventPlugin.GlobalResponderHandler !== null) {
ResponderEventPlugin.GlobalResponderHandler.onChange(
oldResponderID,
nextResponderID
);
}
};
var eventTypes = {
/**
* On a `touchStart`/`mouseDown`, is it desired that this element become the
* responder?
*/
startShouldSetResponder: {
phasedRegistrationNames: {
bubbled: keyOf({onStartShouldSetResponder: null}),
captured: keyOf({onStartShouldSetResponderCapture: null})
}
},
/**
* On a `scroll`, is it desired that this element become the responder? This
* is usually not needed, but should be used to retroactively infer that a
* `touchStart` had occured during momentum scroll. During a momentum scroll,
* a touch start will be immediately followed by a scroll event if the view is
* currently scrolling.
*
* TODO: This shouldn't bubble.
*/
scrollShouldSetResponder: {
phasedRegistrationNames: {
bubbled: keyOf({onScrollShouldSetResponder: null}),
captured: keyOf({onScrollShouldSetResponderCapture: null})
}
},
/**
* On text selection change, should this element become the responder? This
* is needed for text inputs or other views with native selection, so the
* JS view can claim the responder.
*
* TODO: This shouldn't bubble.
*/
selectionChangeShouldSetResponder: {
phasedRegistrationNames: {
bubbled: keyOf({onSelectionChangeShouldSetResponder: null}),
captured: keyOf({onSelectionChangeShouldSetResponderCapture: null})
}
},
/**
* On a `touchMove`/`mouseMove`, is it desired that this element become the
* responder?
*/
moveShouldSetResponder: {
phasedRegistrationNames: {
bubbled: keyOf({onMoveShouldSetResponder: null}),
captured: keyOf({onMoveShouldSetResponderCapture: null})
}
},
/**
* Direct responder events dispatched directly to responder. Do not bubble.
*/
responderStart: {registrationName: keyOf({onResponderStart: null})},
responderMove: {registrationName: keyOf({onResponderMove: null})},
responderEnd: {registrationName: keyOf({onResponderEnd: null})},
responderRelease: {registrationName: keyOf({onResponderRelease: null})},
responderTerminationRequest: {
registrationName: keyOf({onResponderTerminationRequest: null})
},
responderGrant: {registrationName: keyOf({onResponderGrant: null})},
responderReject: {registrationName: keyOf({onResponderReject: null})},
responderTerminate: {registrationName: keyOf({onResponderTerminate: null})}
};
/**
*
* Responder System:
* ----------------
*
* - A global, solitary "interaction lock" on a view.
* - If a `NodeHandle` becomes the responder, it should convey visual feedback
* immediately to indicate so, either by highlighting or moving accordingly.
* - To be the responder means, that touches are exclusively important to that
* responder view, and no other view.
* - While touches are still occuring, the responder lock can be transfered to
* a new view, but only to increasingly "higher" views (meaning ancestors of
* the current responder).
*
* Responder being granted:
* ------------------------
*
* - Touch starts, moves, and scrolls can cause an ID to become the responder.
* - We capture/bubble `startShouldSetResponder`/`moveShouldSetResponder` to
* the "appropriate place".
* - If nothing is currently the responder, the "appropriate place" is the
* initiating event's `targetID`.
* - If something *is* already the responder, the "appropriate place" is the
* first common ancestor of the event target and the current `responderID`.
* - Some negotiation happens: See the timing diagram below.
* - Scrolled views automatically become responder. The reasoning is that a
* platform scroll view that isn't built on top of the responder system has
* began scrolling, and the active responder must now be notified that the
* interaction is no longer locked to it - the system has taken over.
*
* - Responder being released:
* As soon as no more touches that *started* inside of descendents of the
* *current* responderID, an `onResponderRelease` event is dispatched to the
* current responder, and the responder lock is released.
*
* TODO:
* - on "end", a callback hook for `onResponderEndShouldRemainResponder` that
* determines if the responder lock should remain.
* - If a view shouldn't "remain" the responder, any active touches should by
* default be considered "dead" and do not influence future negotiations or
* bubble paths. It should be as if those touches do not exist.
* -- For multitouch: Usually a translate-z will choose to "remain" responder
* after one out of many touches ended. For translate-y, usually the view
* doesn't wish to "remain" responder after one of many touches end.
* - Consider building this on top of a `stopPropagation` model similar to
* `W3C` events.
* - Ensure that `onResponderTerminate` is called on touch cancels, whether or
* not `onResponderTerminationRequest` returns `true` or `false`.
*
*/
/* Negotiation Performed
+-----------------------+
/ \
Process low level events to + Current Responder + wantsResponderID
determine who to perform negot-| (if any exists at all) |
iation/transition | Otherwise just pass through|
-------------------------------+----------------------------+------------------+
Bubble to find first ID | |
to return true:wantsResponderID| |
| |
+-------------+ | |
| onTouchStart| | |
+------+------+ none | |
| return| |
+-----------v-------------+true| +------------------------+ |
|onStartShouldSetResponder|----->|onResponderStart (cur) |<-----------+
+-----------+-------------+ | +------------------------+ | |
| | | +--------+-------+
| returned true for| false:REJECT +-------->|onResponderReject
| wantsResponderID | | | +----------------+
| (now attempt | +------------------+-----+ |
| handoff) | | onResponder | |
+------------------->| TerminationRequest| |
| +------------------+-----+ |
| | | +----------------+
| true:GRANT +-------->|onResponderGrant|
| | +--------+-------+
| +------------------------+ | |
| | onResponderTerminate |<-----------+
| +------------------+-----+ |
| | | +----------------+
| +-------->|onResponderStart|
| | +----------------+
Bubble to find first ID | |
to return true:wantsResponderID| |
| |
+-------------+ | |
| onTouchMove | | |
+------+------+ none | |
| return| |
+-----------v-------------+true| +------------------------+ |
|onMoveShouldSetResponder |----->|onResponderMove (cur) |<-----------+
+-----------+-------------+ | +------------------------+ | |
| | | +--------+-------+
| returned true for| false:REJECT +-------->|onResponderRejec|
| wantsResponderID | | | +----------------+
| (now attempt | +------------------+-----+ |
| handoff) | | onResponder | |
+------------------->| TerminationRequest| |
| +------------------+-----+ |
| | | +----------------+
| true:GRANT +-------->|onResponderGrant|
| | +--------+-------+
| +------------------------+ | |
| | onResponderTerminate |<-----------+
| +------------------+-----+ |
| | | +----------------+
| +-------->|onResponderMove |
| | +----------------+
| |
| |
Some active touch started| |
inside current responder | +------------------------+ |
+------------------------->| onResponderEnd | |
| | +------------------------+ |
+---+---------+ | |
| onTouchEnd | | |
+---+---------+ | |
| | +------------------------+ |
+------------------------->| onResponderEnd | |
No active touches started| +-----------+------------+ |
inside current responder | | |
| v |
| +------------------------+ |
| | onResponderRelease | |
| +------------------------+ |
| |
+ + */
/**
* A note about event ordering in the `EventPluginHub`.
*
* Suppose plugins are injected in the following order:
*
* `[R, S, C]`
*
* To help illustrate the example, assume `S` is `SimpleEventPlugin` (for
* `onClick` etc) and `R` is `ResponderEventPlugin`.
*
* "Deferred-Dispatched Events":
*
* - The current event plugin system will traverse the list of injected plugins,
* in order, and extract events by collecting the plugin's return value of
* `extractEvents()`.
* - These events that are returned from `extractEvents` are "deferred
* dispatched events".
* - When returned from `extractEvents`, deferred-dispatched events contain an
* "accumulation" of deferred dispatches.
* - These deferred dispatches are accumulated/collected before they are
* returned, but processed at a later time by the `EventPluginHub` (hence the
* name deferred).
*
* In the process of returning their deferred-dispatched events, event plugins
* themselves can dispatch events on-demand without returning them from
* `extractEvents`. Plugins might want to do this, so that they can use event
* dispatching as a tool that helps them decide which events should be extracted
* in the first place.
*
* "On-Demand-Dispatched Events":
*
* - On-demand-dispatched events are not returned from `extractEvents`.
* - On-demand-dispatched events are dispatched during the process of returning
* the deferred-dispatched events.
* - They should not have side effects.
* - They should be avoided, and/or eventually be replaced with another
* abstraction that allows event plugins to perform multiple "rounds" of event
* extraction.
*
* Therefore, the sequence of event dispatches becomes:
*
* - `R`s on-demand events (if any) (dispatched by `R` on-demand)
* - `S`s on-demand events (if any) (dispatched by `S` on-demand)
* - `C`s on-demand events (if any) (dispatched by `C` on-demand)
* - `R`s extracted events (if any) (dispatched by `EventPluginHub`)
* - `S`s extracted events (if any) (dispatched by `EventPluginHub`)
* - `C`s extracted events (if any) (dispatched by `EventPluginHub`)
*
* In the case of `ResponderEventPlugin`: If the `startShouldSetResponder`
* on-demand dispatch returns `true` (and some other details are satisfied) the
* `onResponderGrant` deferred dispatched event is returned from
* `extractEvents`. The sequence of dispatch executions in this case
* will appear as follows:
*
* - `startShouldSetResponder` (`ResponderEventPlugin` dispatches on-demand)
* - `touchStartCapture` (`EventPluginHub` dispatches as usual)
* - `touchStart` (`EventPluginHub` dispatches as usual)
* - `responderGrant/Reject` (`EventPluginHub` dispatches as usual)
*
* @param {string} topLevelType Record from `EventConstants`.
* @param {string} topLevelTargetID ID of deepest React rendered element.
* @param {object} nativeEvent Native browser event.
* @return {*} An accumulation of synthetic events.
*/
function setResponderAndExtractTransfer(
topLevelType,
topLevelTargetID,
nativeEvent) {
var shouldSetEventType =
isStartish(topLevelType) ? eventTypes.startShouldSetResponder :
isMoveish(topLevelType) ? eventTypes.moveShouldSetResponder :
topLevelType === EventConstants.topLevelTypes.topSelectionChange ?
eventTypes.selectionChangeShouldSetResponder :
eventTypes.scrollShouldSetResponder;
// TODO: stop one short of the the current responder.
var bubbleShouldSetFrom = !responderID ?
topLevelTargetID :
ReactInstanceHandles._getFirstCommonAncestorID(responderID, topLevelTargetID);
// When capturing/bubbling the "shouldSet" event, we want to skip the target
// (deepest ID) if it happens to be the current responder. The reasoning:
// It's strange to get an `onMoveShouldSetResponder` when you're *already*
// the responder.
var skipOverBubbleShouldSetFrom = bubbleShouldSetFrom === responderID;
var shouldSetEvent = ResponderSyntheticEvent.getPooled(
shouldSetEventType,
bubbleShouldSetFrom,
nativeEvent
);
shouldSetEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
if (skipOverBubbleShouldSetFrom) {
EventPropagators.accumulateTwoPhaseDispatchesSkipTarget(shouldSetEvent);
} else {
EventPropagators.accumulateTwoPhaseDispatches(shouldSetEvent);
}
var wantsResponderID = executeDispatchesInOrderStopAtTrue(shouldSetEvent);
if (!shouldSetEvent.isPersistent()) {
shouldSetEvent.constructor.release(shouldSetEvent);
}
if (!wantsResponderID || wantsResponderID === responderID) {
return null;
}
var extracted;
var grantEvent = ResponderSyntheticEvent.getPooled(
eventTypes.responderGrant,
wantsResponderID,
nativeEvent
);
grantEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
EventPropagators.accumulateDirectDispatches(grantEvent);
if (responderID) {
var terminationRequestEvent = ResponderSyntheticEvent.getPooled(
eventTypes.responderTerminationRequest,
responderID,
nativeEvent
);
terminationRequestEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
EventPropagators.accumulateDirectDispatches(terminationRequestEvent);
var shouldSwitch = !hasDispatches(terminationRequestEvent) ||
executeDirectDispatch(terminationRequestEvent);
if (!terminationRequestEvent.isPersistent()) {
terminationRequestEvent.constructor.release(terminationRequestEvent);
}
if (shouldSwitch) {
var terminateType = eventTypes.responderTerminate;
var terminateEvent = ResponderSyntheticEvent.getPooled(
terminateType,
responderID,
nativeEvent
);
terminateEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
EventPropagators.accumulateDirectDispatches(terminateEvent);
extracted = accumulate(extracted, [grantEvent, terminateEvent]);
changeResponder(wantsResponderID);
} else {
var rejectEvent = ResponderSyntheticEvent.getPooled(
eventTypes.responderReject,
wantsResponderID,
nativeEvent
);
rejectEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
EventPropagators.accumulateDirectDispatches(rejectEvent);
extracted = accumulate(extracted, rejectEvent);
}
} else {
extracted = accumulate(extracted, grantEvent);
changeResponder(wantsResponderID);
}
return extracted;
}
/**
* A transfer is a negotiation between a currently set responder and the next
* element to claim responder status. Any start event could trigger a transfer
* of responderID. Any move event could trigger a transfer.
*
* @param {string} topLevelType Record from `EventConstants`.
* @return {boolean} True if a transfer of responder could possibly occur.
*/
function canTriggerTransfer(topLevelType, topLevelTargetID) {
return topLevelTargetID && (
topLevelType === EventConstants.topLevelTypes.topScroll ||
(trackedTouchCount > 0 &&
topLevelType === EventConstants.topLevelTypes.topSelectionChange) ||
isStartish(topLevelType) ||
isMoveish(topLevelType)
);
}
/**
* Returns whether or not this touch end event makes it such that there are no
* longer any touches that started inside of the current `responderID`.
*
* @param {NativeEvent} nativeEvent Native touch end event.
* @return {bool} Whether or not this touch end event ends the responder.
*/
function noResponderTouches(nativeEvent) {
var touches = nativeEvent.touches;
if (!touches || touches.length === 0) {
return true;
}
for (var i = 0; i < touches.length; i++) {
var activeTouch = touches[i];
var target = activeTouch.target;
if (target !== null && target !== undefined && target !== 0) {
// Is the original touch location inside of the current responder?
var commonAncestor =
ReactInstanceHandles._getFirstCommonAncestorID(
responderID,
NodeHandle.getRootNodeID(target)
);
if (commonAncestor === responderID) {
return false;
}
}
}
return true;
}
var ResponderEventPlugin = {
getResponderID: function() {
return responderID;
},
eventTypes: eventTypes,
/**
* We must be resilient to `topLevelTargetID` being `undefined` on
* `touchMove`, or `touchEnd`. On certain platforms, this means that a native
* scroll has assumed control and the original touch targets are destroyed.
*
* @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 (isStartish(topLevelType)) {
trackedTouchCount += 1;
} else if (isEndish(topLevelType)) {
trackedTouchCount -= 1;
invariant(
trackedTouchCount >= 0,
'Ended a touch event which was not counted in trackedTouchCount.'
);
}
ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent);
var extracted = canTriggerTransfer(topLevelType, topLevelTargetID) ?
setResponderAndExtractTransfer(topLevelType, topLevelTargetID, nativeEvent) :
null;
// Responder may or may not have transfered on a new touch start/move.
// Regardless, whoever is the responder after any potential transfer, we
// direct all touch start/move/ends to them in the form of
// `onResponderMove/Start/End`. These will be called for *every* additional
// finger that move/start/end, dispatched directly to whoever is the
// current responder at that moment, until the responder is "released".
//
// These multiple individual change touch events are are always bookended
// by `onResponderGrant`, and one of
// (`onResponderRelease/onResponderTerminate`).
var isResponderTouchStart = responderID && isStartish(topLevelType);
var isResponderTouchMove = responderID && isMoveish(topLevelType);
var isResponderTouchEnd = responderID && isEndish(topLevelType);
var incrementalTouch =
isResponderTouchStart ? eventTypes.responderStart :
isResponderTouchMove ? eventTypes.responderMove :
isResponderTouchEnd ? eventTypes.responderEnd :
null;
if (incrementalTouch) {
var gesture =
ResponderSyntheticEvent.getPooled(incrementalTouch, responderID, nativeEvent);
gesture.touchHistory = ResponderTouchHistoryStore.touchHistory;
EventPropagators.accumulateDirectDispatches(gesture);
extracted = accumulate(extracted, gesture);
}
var isResponderTerminate =
responderID &&
topLevelType === EventConstants.topLevelTypes.topTouchCancel;
var isResponderRelease =
responderID &&
!isResponderTerminate &&
isEndish(topLevelType) &&
noResponderTouches(nativeEvent);
var finalTouch =
isResponderTerminate ? eventTypes.responderTerminate :
isResponderRelease ? eventTypes.responderRelease :
null;
if (finalTouch) {
var finalEvent =
ResponderSyntheticEvent.getPooled(finalTouch, responderID, nativeEvent);
finalEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
EventPropagators.accumulateDirectDispatches(finalEvent);
extracted = accumulate(extracted, finalEvent);
changeResponder(null);
}
var numberActiveTouches =
ResponderTouchHistoryStore.touchHistory.numberActiveTouches;
if (ResponderEventPlugin.GlobalInteractionHandler &&
numberActiveTouches !== previousActiveTouches) {
ResponderEventPlugin.GlobalInteractionHandler.onChange(
numberActiveTouches
);
}
previousActiveTouches = numberActiveTouches;
return extracted;
},
GlobalResponderHandler: null,
GlobalInteractionHandler: null,
injection: {
/**
* @param {{onChange: (ReactID, ReactID) => void} GlobalResponderHandler
* Object that handles any change in responder. Use this to inject
* integration with an existing touch handling system etc.
*/
injectGlobalResponderHandler: function(GlobalResponderHandler) {
ResponderEventPlugin.GlobalResponderHandler = GlobalResponderHandler;
},
/**
* @param {{onChange: (numberActiveTouches) => void} GlobalInteractionHandler
* Object that handles any change in the number of active touches.
*/
injectGlobalInteractionHandler: function(GlobalInteractionHandler) {
ResponderEventPlugin.GlobalInteractionHandler = GlobalInteractionHandler;
},
}
};
module.exports = ResponderEventPlugin;
});
__d('ResponderSyntheticEvent',["SyntheticEvent"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright 2013-2014 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 ResponderSyntheticEvent
* @typechecks static-only
*/
"use strict";
var SyntheticEvent = require('SyntheticEvent');
/**
* `touchHistory` isn't actually on the native event, but putting it in the
* interface will ensure that it is cleaned up when pooled/destroyed. The
* `ResponderEventPlugin` will populate it appropriately.
*/
var ResponderEventInterface = {
touchHistory: function(nativeEvent) {
return null; // Actually doesn't even look at the native event.
},
};
/**
* @param {object} dispatchConfig Configuration used to dispatch this event.
* @param {string} dispatchMarker Marker identifying the event target.
* @param {object} nativeEvent Native event.
* @extends {SyntheticEvent}
*/
function ResponderSyntheticEvent(dispatchConfig, dispatchMarker, nativeEvent) {
SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
}
SyntheticEvent.augmentClass(ResponderSyntheticEvent, ResponderEventInterface);
module.exports = ResponderSyntheticEvent;
});
__d('ResponderTouchHistoryStore',["EventPluginUtils","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* @providesModule ResponderTouchHistoryStore
*/
"use strict";
var EventPluginUtils = require('EventPluginUtils');
var invariant = require('invariant');
var isMoveish = EventPluginUtils.isMoveish;
var isStartish = EventPluginUtils.isStartish;
var isEndish = EventPluginUtils.isEndish;
var MAX_TOUCH_BANK = 20;
/**
* Touch position/time tracking information by touchID. Typically, we'll only
* see IDs with a range of 1-20 (they are recycled when touches end and then
* start again). This data is commonly needed by many different interaction
* logic modules so precomputing it is very helpful to do once.
* Each touch object in `touchBank` is of the following form:
* { touchActive: boolean,
* startTimeStamp: number,
* startPageX: number,
* startPageY: number,
* currentPageX: number,
* currentPageY: number,
* currentTimeStamp: number
* }
*/
var touchHistory = {
touchBank: [ ],
numberActiveTouches: 0,
// If there is only one active touch, we remember its location. This prevents
// us having to loop through all of the touches all the time in the most
// common case.
indexOfSingleActiveTouch: -1,
mostRecentTimeStamp: 0,
};
var timestampForTouch = function(touch) {
// The legacy internal implementation provides "timeStamp", which has been
// renamed to "timestamp". Let both work for now while we iron it out
// TODO (evv): rename timeStamp to timestamp in internal code
return touch.timeStamp || touch.timestamp;
};
/**
* TODO: Instead of making gestures recompute filtered velocity, we could
* include a built in velocity computation that can be reused globally.
* @param {Touch} touch Native touch object.
*/
var initializeTouchData = function(touch) {
return {
touchActive: true,
startTimeStamp: timestampForTouch(touch),
startPageX: touch.pageX,
startPageY: touch.pageY,
currentPageX: touch.pageX,
currentPageY: touch.pageY,
currentTimeStamp: timestampForTouch(touch),
previousPageX: touch.pageX,
previousPageY: touch.pageY,
previousTimeStamp: timestampForTouch(touch),
};
};
var reinitializeTouchTrack = function(touchTrack, touch) {
touchTrack.touchActive = true;
touchTrack.startTimeStamp = timestampForTouch(touch);
touchTrack.startPageX = touch.pageX;
touchTrack.startPageY = touch.pageY;
touchTrack.currentPageX = touch.pageX;
touchTrack.currentPageY = touch.pageY;
touchTrack.currentTimeStamp = timestampForTouch(touch);
touchTrack.previousPageX = touch.pageX;
touchTrack.previousPageY = touch.pageY;
touchTrack.previousTimeStamp = timestampForTouch(touch);
};
var validateTouch = function(touch) {
var identifier = touch.identifier;
invariant(identifier != null, 'Touch object is missing identifier');
if (identifier > MAX_TOUCH_BANK) {
console.warn(
'Touch identifier ' + identifier + ' is greater than maximum ' +
'supported ' + MAX_TOUCH_BANK + ' which causes performance issues ' +
'backfilling array locations for all of the indices.'
);
}
};
var recordStartTouchData = function(touch) {
var touchBank = touchHistory.touchBank;
var identifier = touch.identifier;
var touchTrack = touchBank[identifier];
if (__DEV__) {
validateTouch(touch);
}
if (!touchTrack) {
touchBank[touch.identifier] = initializeTouchData(touch);
} else {
reinitializeTouchTrack(touchTrack, touch);
}
touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
};
var recordMoveTouchData = function(touch) {
var touchBank = touchHistory.touchBank;
var touchTrack = touchBank[touch.identifier];
if (__DEV__) {
validateTouch(touch);
invariant(touchTrack, 'Touch data should have been recorded on start');
}
touchTrack.touchActive = true;
touchTrack.previousPageX = touchTrack.currentPageX;
touchTrack.previousPageY = touchTrack.currentPageY;
touchTrack.previousTimeStamp = touchTrack.currentTimeStamp;
touchTrack.currentPageX = touch.pageX;
touchTrack.currentPageY = touch.pageY;
touchTrack.currentTimeStamp = timestampForTouch(touch);
touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
};
var recordEndTouchData = function(touch) {
var touchBank = touchHistory.touchBank;
var touchTrack = touchBank[touch.identifier];
if (__DEV__) {
validateTouch(touch);
invariant(touchTrack, 'Touch data should have been recorded on start');
}
touchTrack.previousPageX = touchTrack.currentPageX;
touchTrack.previousPageY = touchTrack.currentPageY;
touchTrack.previousTimeStamp = touchTrack.currentTimeStamp;
touchTrack.currentPageX = touch.pageX;
touchTrack.currentPageY = touch.pageY;
touchTrack.currentTimeStamp = timestampForTouch(touch);
touchTrack.touchActive = false;
touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
};
var ResponderTouchHistoryStore = {
recordTouchTrack: function(topLevelType, nativeEvent) {
var touchBank = touchHistory.touchBank;
if (isMoveish(topLevelType)) {
nativeEvent.changedTouches.forEach(recordMoveTouchData);
} else if (isStartish(topLevelType)) {
nativeEvent.changedTouches.forEach(recordStartTouchData);
touchHistory.numberActiveTouches = nativeEvent.touches.length;
if (touchHistory.numberActiveTouches === 1) {
touchHistory.indexOfSingleActiveTouch = nativeEvent.touches[0].identifier;
}
} else if (isEndish(topLevelType)) {
nativeEvent.changedTouches.forEach(recordEndTouchData);
touchHistory.numberActiveTouches = nativeEvent.touches.length;
if (touchHistory.numberActiveTouches === 1) {
for (var i = 0; i < touchBank.length; i++) {
var touchTrackToCheck = touchBank[i];
if (touchTrackToCheck != null && touchTrackToCheck.touchActive) {
touchHistory.indexOfSingleActiveTouch = i;
break;
}
}
if (__DEV__) {
var activeTouchData = touchBank[touchHistory.indexOfSingleActiveTouch];
var foundActive = activeTouchData != null && !!activeTouchData.touchActive;
invariant(foundActive, 'Cannot find single active touch');
}
}
}
},
touchHistory: touchHistory,
};
module.exports = ResponderTouchHistoryStore;
});
__d('accumulate',["invariant"],function(global, require, requireDynamic, requireLazy, 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 accumulate
*/
'use strict';
var invariant = require('invariant');
/**
* Accumulates items that must not be null or undefined.
*
* This is used to conserve memory by avoiding array allocations.
*
* @return {*|array<*>} An accumulation of items.
*/
function accumulate(current, next) {
invariant(
next != null,
'accumulate(...): Accumulated items must be not be null or undefined.'
);
if (current == null) {
return next;
} else {
// 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) {
return current.concat(next);
} else {
if (nextIsArray) {
return [current].concat(next);
} else {
return [current, next];
}
}
}
}
module.exports = accumulate;
});
__d('UniversalWorkerNodeHandle',["ReactIOSTagHandles","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* @providesModule UniversalWorkerNodeHandle
*/
var ReactIOSTagHandles = require('ReactIOSTagHandles');
var invariant = require('invariant');
var UniversalWorkerNodeHandle = {
getRootNodeID: function(nodeHandle) {
invariant(
nodeHandle !== undefined && nodeHandle !== null && nodeHandle !== 0,
'No node handle defined'
);
return ReactIOSTagHandles.tagToRootNodeID[nodeHandle];
}
};
module.exports = UniversalWorkerNodeHandle;
});
__d('createReactIOSNativeComponentClass',["ReactElement","ReactIOSNativeComponent"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 createReactIOSNativeComponentClass
* @flow
*/
"use strict";
var ReactElement = require('ReactElement');
var ReactIOSNativeComponent = require('ReactIOSNativeComponent');
// See also ReactIOSNativeComponent
/**
* @param {string} config iOS View configuration.
* @private
*/
var createReactIOSNativeComponentClass = function(
viewConfig
) { // returning Function is lossy :/
var Constructor = function(element) {
this._currentElement = element;
this._rootNodeID = null;
this._renderedChildren = null;
this.previousFlattenedStyle = null;
};
Constructor.displayName = viewConfig.uiViewClassName;
Constructor.prototype = new ReactIOSNativeComponent(viewConfig);
return Constructor;
};
module.exports = createReactIOSNativeComponentClass;
});
__d('ReactIOSNativeComponent',["NativeMethodsMixin","ReactIOSComponentMixin","ReactIOSEventEmitter","ReactIOSStyleAttributes","ReactIOSTagHandles","ReactMultiChild","NativeModules","styleDiffer","deepFreezeAndThrowOnMutationInDev","diffRawProperties","flattenStyle","precomputeStyle","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 ReactIOSNativeComponent
* @flow
*/
'use strict';
var NativeMethodsMixin = require('NativeMethodsMixin');
var ReactIOSComponentMixin = require('ReactIOSComponentMixin');
var ReactIOSEventEmitter = require('ReactIOSEventEmitter');
var ReactIOSStyleAttributes = require('ReactIOSStyleAttributes');
var ReactIOSTagHandles = require('ReactIOSTagHandles');
var ReactMultiChild = require('ReactMultiChild');
var RCTUIManager = require('NativeModules').UIManager;
var styleDiffer = require('styleDiffer');
var deepFreezeAndThrowOnMutationInDev = require('deepFreezeAndThrowOnMutationInDev');
var diffRawProperties = require('diffRawProperties');
var flattenStyle = require('flattenStyle');
var precomputeStyle = require('precomputeStyle');
var warning = require('warning');
var registrationNames = ReactIOSEventEmitter.registrationNames;
var putListener = ReactIOSEventEmitter.putListener;
var deleteAllListeners = ReactIOSEventEmitter.deleteAllListeners;
/**
* @constructor ReactIOSNativeComponent
* @extends ReactComponent
* @extends ReactMultiChild
* @param {!object} UIKit View Configuration.
*/
var ReactIOSNativeComponent = function(
viewConfig
) {
this.viewConfig = viewConfig;
};
/**
* Generates and caches arrays of the form:
*
* [0, 1, 2, 3]
* [0, 1, 2, 3, 4]
* [0, 1]
*
* @param {number} size Size of array to generate.
* @return {Array<number>} Array with values that mirror the index.
*/
var cachedIndexArray = function(size) {
var cachedResult = cachedIndexArray._cache[size];
if (!cachedResult) {
var arr = [];
for (var i = 0; i < size; i++) {
arr[i] = i;
}
return cachedIndexArray._cache[size] = arr;
} else {
return cachedResult;
}
};
cachedIndexArray._cache = {};
/**
* Mixin for containers that contain UIViews. NOTE: markup is rendered markup
* which is a `viewID` ... see the return value for `mountComponent` !
*/
ReactIOSNativeComponent.Mixin = {
getPublicInstance: function() {
// TODO: This should probably use a composite wrapper
return this;
},
construct: function(element) {
this._currentElement = element;
},
unmountComponent: function() {
deleteAllListeners(this._rootNodeID);
this.unmountChildren();
this._rootNodeID = null;
},
/**
* Every native component is responsible for allocating its own `tag`, and
* issuing the native `createView` command. But it is not responsible for
* recording the fact that its own `rootNodeID` is associated with a
* `nodeHandle`. Only the code that actually adds its `nodeHandle` (`tag`) as
* a child of a container can confidently record that in
* `ReactIOSTagHandles`.
*/
initializeChildren: function(children, containerTag, transaction, context) {
var mountImages = this.mountChildren(children, transaction, context);
// In a well balanced tree, half of the nodes are in the bottom row and have
// no children - let's avoid calling out to the native bridge for a large
// portion of the children.
if (mountImages.length) {
var indexes = cachedIndexArray(mountImages.length);
// TODO: Pool these per platform view class. Reusing the `mountImages`
// array would likely be a jit deopt.
var createdTags = [];
for (var i = 0; i < mountImages.length; i++) {
var mountImage = mountImages[i];
var childTag = mountImage.tag;
var childID = mountImage.rootNodeID;
warning(
mountImage && mountImage.rootNodeID && mountImage.tag,
'Mount image returned does not have required data'
);
ReactIOSTagHandles.associateRootNodeIDWithMountedNodeHandle(
childID,
childTag
);
createdTags[i] = mountImage.tag;
}
RCTUIManager
.manageChildren(containerTag, null, null, createdTags, indexes, null);
}
},
/**
* Beware, this function has side effect to store this.previousFlattenedStyle!
*
* @param {!object} prevProps Previous properties
* @param {!object} nextProps Next properties
* @param {!object} validAttributes Set of valid attributes and how they
* should be diffed
*/
computeUpdatedProperties: function(prevProps, nextProps, validAttributes) {
if (__DEV__) {
for (var key in nextProps) {
if (nextProps.hasOwnProperty(key) &&
nextProps[key] &&
validAttributes[key]) {
deepFreezeAndThrowOnMutationInDev(nextProps[key]);
}
}
}
var updatePayload = diffRawProperties(
null, // updatePayload
prevProps,
nextProps,
validAttributes
);
// The style property is a deeply nested element which includes numbers
// to represent static objects. Most of the time, it doesn't change across
// renders, so it's faster to spend the time checking if it is different
// before actually doing the expensive flattening operation in order to
// compute the diff.
if (styleDiffer(nextProps.style, prevProps.style)) {
var nextFlattenedStyle = precomputeStyle(flattenStyle(nextProps.style));
updatePayload = diffRawProperties(
updatePayload,
this.previousFlattenedStyle,
nextFlattenedStyle,
ReactIOSStyleAttributes
);
this.previousFlattenedStyle = nextFlattenedStyle;
}
return updatePayload;
},
/**
* Updates the component's currently mounted representation.
*
* @param {object} nextElement
* @param {ReactReconcileTransaction} transaction
* @param {object} context
* @internal
*/
receiveComponent: function(nextElement, transaction, context) {
var prevElement = this._currentElement;
this._currentElement = nextElement;
var updatePayload = this.computeUpdatedProperties(
prevElement.props,
nextElement.props,
this.viewConfig.validAttributes
);
if (updatePayload) {
RCTUIManager.updateView(
ReactIOSTagHandles.mostRecentMountedNodeHandleForRootNodeID(this._rootNodeID),
this.viewConfig.uiViewClassName,
updatePayload
);
}
this._reconcileListenersUponUpdate(
prevElement.props,
nextElement.props
);
this.updateChildren(nextElement.props.children, transaction, context);
},
/**
* @param {object} initialProps Native component props.
*/
_registerListenersUponCreation: function(initialProps) {
for (var key in initialProps) {
// NOTE: The check for `!props[key]`, is only possible because this method
// registers listeners the *first* time a component is created.
if (registrationNames[key] && initialProps[key]) {
var listener = initialProps[key];
putListener(this._rootNodeID, key, listener);
}
}
},
/**
* Reconciles event listeners, adding or removing if necessary.
* @param {object} prevProps Native component props including events.
* @param {object} nextProps Next native component props including events.
*/
_reconcileListenersUponUpdate: function(prevProps, nextProps) {
for (var key in nextProps) {
if (registrationNames[key] && (nextProps[key] != prevProps[key])) {
putListener(this._rootNodeID, key, nextProps[key]);
}
}
},
/**
* @param {string} rootID Root ID of this subtree.
* @param {Transaction} transaction For creating/updating.
* @return {string} Unique iOS view tag.
*/
mountComponent: function(rootID, transaction, context) {
this._rootNodeID = rootID;
var tag = ReactIOSTagHandles.allocateTag();
this.previousFlattenedStyle = {};
var updatePayload = this.computeUpdatedProperties(
{}, // previous props
this._currentElement.props, // next props
this.viewConfig.validAttributes
);
RCTUIManager.createView(tag, this.viewConfig.uiViewClassName, updatePayload);
this._registerListenersUponCreation(this._currentElement.props);
this.initializeChildren(
this._currentElement.props.children,
tag,
transaction,
context
);
return {
rootNodeID: rootID,
tag: tag
};
}
};
/**
* Order of mixins is important. ReactIOSNativeComponent overrides methods in
* ReactMultiChild.
*/
Object.assign(
ReactIOSNativeComponent.prototype,
ReactMultiChild.Mixin,
ReactIOSNativeComponent.Mixin,
NativeMethodsMixin,
ReactIOSComponentMixin
);
module.exports = ReactIOSNativeComponent;
});
__d('NativeMethodsMixin',["NativeModules","TextInputState","flattenStyle","invariant","mergeFast","precomputeStyle"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 NativeMethodsMixin
* @flow
*/
'use strict';
var NativeModules = require('NativeModules');
var RCTPOPAnimationManager = NativeModules.POPAnimationManager;
var RCTUIManager = NativeModules.UIManager;
var TextInputState = require('TextInputState');
var flattenStyle = require('flattenStyle');
var invariant = require('invariant');
var mergeFast = require('mergeFast');
var precomputeStyle = require('precomputeStyle');
var animationIDInvariant = function(
funcName ,
anim
) {
invariant(
anim,
funcName + ' must be called with a valid animation ID returned from' +
' POPAnimation.createAnimation, received: "' + anim + '"'
);
};
var NativeMethodsMixin = {
addAnimation: function(anim , callback ) {
animationIDInvariant('addAnimation', anim);
RCTPOPAnimationManager.addAnimation(this.getNodeHandle(), anim, callback);
},
removeAnimation: function(anim ) {
animationIDInvariant('removeAnimation', anim);
RCTPOPAnimationManager.removeAnimation(this.getNodeHandle(), anim);
},
measure: function(callback ) {
RCTUIManager.measure(this.getNodeHandle(), callback);
},
measureLayout: function(
relativeToNativeNode ,
onSuccess ,
onFail /* currently unused */
) {
RCTUIManager.measureLayout(
this.getNodeHandle(),
relativeToNativeNode,
onFail,
onSuccess
);
},
/**
* This function sends props straight to native. They will not participate
* in future diff process, this means that if you do not include them in the
* next render, they will remain active.
*/
setNativeProps: function(nativeProps ) {
// nativeProps contains a style attribute that's going to be flattened
// and all the attributes expanded in place. In order to make this
// process do as few allocations and copies as possible, we return
// one if the other is empty. Only if both have values then we create
// a new object and merge.
var hasOnlyStyle = true;
for (var key in nativeProps) {
if (key !== 'style') {
hasOnlyStyle = false;
break;
}
}
var style = precomputeStyle(flattenStyle(nativeProps.style));
var props = null;
if (hasOnlyStyle) {
props = style;
} else if (!style) {
props = nativeProps;
} else {
props = mergeFast(nativeProps, style);
}
RCTUIManager.updateView(
this.getNodeHandle(),
this.viewConfig.uiViewClassName,
props
);
},
focus: function() {
TextInputState.focusTextInput(this.getNodeHandle());
},
blur: function() {
TextInputState.blurTextInput(this.getNodeHandle());
}
};
function throwOnStylesProp(component, props) {
if (props.styles !== undefined) {
var owner = component._owner || null;
var name = component.constructor.displayName;
var msg = '`styles` is not a supported property of `' + name + '`, did ' +
'you mean `style` (singular)?';
if (owner && owner.constructor && owner.constructor.displayName) {
msg += '\n\nCheck the `' + owner.constructor.displayName + '` parent ' +
' component.';
}
throw new Error(msg);
}
}
if (__DEV__) {
// hide this from Flow since we can't define these properties outside of
// __DEV__ without actually implementing them (setting them to undefined
// isn't allowed by ReactClass)
var NativeMethodsMixin_DEV = (NativeMethodsMixin );
invariant(
!NativeMethodsMixin_DEV.componentWillMount &&
!NativeMethodsMixin_DEV.componentWillReceiveProps,
'Do not override existing functions.'
);
NativeMethodsMixin_DEV.componentWillMount = function () {
throwOnStylesProp(this, this.props);
};
NativeMethodsMixin_DEV.componentWillReceiveProps = function (newProps) {
throwOnStylesProp(this, newProps);
};
}
module.exports = NativeMethodsMixin;
});
__d('TextInputState',["NativeModules"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 TextInputState
* @flow
*
* This class is responsible for coordinating the "focused"
* state for TextInputs. All calls relating to the keyboard
* should be funneled through here
*/
'use strict';
var RCTUIManager = require('NativeModules').UIManager;
var TextInputState = {
/**
* Internal state
*/
_currentlyFocusedID: (null ),
/**
* Returns the ID of the currently focused text field, if one exists
* If no text field is focused it returns null
*/
currentlyFocusedField: function() {
return this._currentlyFocusedID;
},
/**
* @param {string} TextInputID id of the text field to focus
* Focuses the specified text field
* noop if the text field was already focused
*/
focusTextInput: function(textFieldID ) {
if (this._currentlyFocusedID !== textFieldID && textFieldID !== null) {
this._currentlyFocusedID = textFieldID;
RCTUIManager.focus(textFieldID);
}
},
/**
* @param {string} textFieldID id of the text field to focus
* Unfocuses the specified text field
* noop if it wasn't focused
*/
blurTextInput: function(textFieldID ) {
if (this._currentlyFocusedID === textFieldID && textFieldID !== null) {
this._currentlyFocusedID = null;
RCTUIManager.blur(textFieldID);
}
}
};
module.exports = TextInputState;
});
__d('flattenStyle',["StyleSheetRegistry","invariant","mergeIntoFast"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 flattenStyle
* @flow
*/
'use strict';
var StyleSheetRegistry = require('StyleSheetRegistry');
var invariant = require('invariant');
var mergeIntoFast = require('mergeIntoFast');
function getStyle(style) {
if (typeof style === 'number') {
return StyleSheetRegistry.getStyleByID(style);
}
return style;
}
// TODO: Flow 0.7.0 doesn't refine bools properly so we have to use `any` to
// tell it that this can't be a bool anymore. Should be fixed in 0.8.0,
// after which this can take a ?StyleObj.
function flattenStyle(style ) {
if (!style) {
return undefined;
}
invariant(style !== true, 'style may be false but not true');
if (!Array.isArray(style)) {
return getStyle(style);
}
var result = {};
for (var i = 0; i < style.length; ++i) {
var computedStyle = flattenStyle(style[i]);
if (computedStyle) {
mergeIntoFast(result, computedStyle);
}
}
return result;
}
module.exports = flattenStyle;
});
__d('StyleSheetRegistry',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 StyleSheetRegistry
* @flow
*/
'use strict';
var styles = {};
var uniqueID = 1;
var emptyStyle = {};
function StyleSheetRegistry(){}
StyleSheetRegistry.registerStyle=function(style ) {
var id = ++uniqueID;
if (__DEV__) {
Object.freeze(style);
}
styles[id] = style;
return id;
};
StyleSheetRegistry.getStyleByID=function(id ) {
if (!id) {
// Used in the style={[condition && id]} pattern,
// we want it to be a no-op when the value is false or null
return emptyStyle;
}
var style = styles[id];
if (!style) {
console.warn('Invalid style with id `' + id + '`. Skipping ...');
return emptyStyle;
}
return style;
};
module.exports = StyleSheetRegistry;
});
__d('mergeIntoFast',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 mergeIntoFast
* @flow
*/
'use strict';
/**
* Faster version of `mergeInto` that doesn't check its arguments and
* also copies over prototye inherited properties.
*
* @param {object} one Object to assign to.
* @param {object} two Object to assign from.
*/
var mergeIntoFast = function(one , two ) {
for (var keyTwo in two) {
one[keyTwo] = two[keyTwo];
}
};
module.exports = mergeIntoFast;
});
__d('mergeFast',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 mergeFast
* @flow
*/
'use strict';
/**
* Faster version of `merge` that doesn't check its arguments and
* also merges prototye inherited properties.
*
* @param {object} one Any non-null object.
* @param {object} two Any non-null object.
* @return {object} Merging of two objects, including prototype
* inherited properties.
*/
var mergeFast = function(one , two ) {
var ret = {};
for (var keyOne in one) {
ret[keyOne] = one[keyOne];
}
for (var keyTwo in two) {
ret[keyTwo] = two[keyTwo];
}
return ret;
};
module.exports = mergeFast;
});
__d('precomputeStyle',["MatrixMath","deepFreezeAndThrowOnMutationInDev","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 precomputeStyle
* @flow
*/
'use strict';
var MatrixMath = require('MatrixMath');
var deepFreezeAndThrowOnMutationInDev = require('deepFreezeAndThrowOnMutationInDev');
var invariant = require('invariant');
/**
* This method provides a hook where flattened styles may be precomputed or
* otherwise prepared to become better input data for native code.
*/
function precomputeStyle(style ) {
if (!style || !style.transform) {
return style;
}
invariant(
!style.transformMatrix,
'transformMatrix and transform styles cannot be used on the same component'
);
var newStyle = _precomputeTransforms(Object.assign({},style));
deepFreezeAndThrowOnMutationInDev(newStyle);
return newStyle;
}
/**
* Generate a transform matrix based on the provided transforms, and use that
* within the style object instead.
*
* This allows us to provide an API that is similar to CSS and to have a
* universal, singular interface to native code.
*/
function _precomputeTransforms(style ) {
var $__0= style,transform=$__0.transform;
var result = MatrixMath.createIdentityMatrix();
transform.forEach(function(transformation) {
var key = Object.keys(transformation)[0];
var value = transformation[key];
if (__DEV__) {
_validateTransform(key, value, transformation);
}
switch (key) {
case 'matrix':
MatrixMath.multiplyInto(result, result, value);
break;
case 'rotate':
_multiplyTransform(result, MatrixMath.reuseRotateZCommand, [_convertToRadians(value)]);
break;
case 'scale':
_multiplyTransform(result, MatrixMath.reuseScaleCommand, [value]);
break;
case 'scaleX':
_multiplyTransform(result, MatrixMath.reuseScaleXCommand, [value]);
break;
case 'scaleY':
_multiplyTransform(result, MatrixMath.reuseScaleYCommand, [value]);
break;
case 'translate':
_multiplyTransform(result, MatrixMath.reuseTranslate3dCommand, [value[0], value[1], value[2] || 0]);
break;
case 'translateX':
_multiplyTransform(result, MatrixMath.reuseTranslate2dCommand, [value, 0]);
break;
case 'translateY':
_multiplyTransform(result, MatrixMath.reuseTranslate2dCommand, [0, value]);
break;
default:
throw new Error('Invalid transform name: ' + key);
}
});
return Object.assign({},
style,
{transformMatrix: result
});
}
/**
* Performs a destructive operation on a transform matrix.
*/
function _multiplyTransform(
result ,
matrixMathFunction ,
args
) {
var matrixToApply = MatrixMath.createIdentityMatrix();
var argsWithIdentity = [matrixToApply].concat(args);
matrixMathFunction.apply(this, argsWithIdentity);
MatrixMath.multiplyInto(result, result, matrixToApply);
}
/**
* Parses a string like '0.5rad' or '60deg' into radians expressed in a float.
* Note that validation on the string is done in `_validateTransform()`.
*/
function _convertToRadians(value ) {
var floatValue = parseFloat(value, 10);
return value.indexOf('rad') > -1 ? floatValue : floatValue * Math.PI / 180;
}
function _validateTransform(key, value, transformation) {
var multivalueTransforms = [
'matrix',
'translate',
];
if (multivalueTransforms.indexOf(key) !== -1) {
invariant(
Array.isArray(value),
'Transform with key of %s must have an array as the value: %s',
key,
JSON.stringify(transformation)
);
}
switch (key) {
case 'matrix':
invariant(
value.length === 9 || value.length === 16,
'Matrix transform must have a length of 9 (2d) or 16 (3d). ' +
'Provided matrix has a length of %s: %s',
value.length,
JSON.stringify(transformation)
);
break;
case 'translate':
break;
case 'rotate':
invariant(
typeof value === 'string',
'Transform with key of "%s" must be a string: %s',
key,
JSON.stringify(transformation)
);
invariant(
value.indexOf('deg') > -1 || value.indexOf('rad') > -1,
'Rotate transform must be expressed in degrees (deg) or radians ' +
'(rad): %s',
JSON.stringify(transformation)
);
break;
default:
invariant(
typeof value === 'number',
'Transform with key of "%s" must be a number: %s',
key,
JSON.stringify(transformation)
);
}
}
module.exports = precomputeStyle;
});
__d('MatrixMath',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule MatrixMath
*/
'use strict';
/**
* Memory conservative (mutative) matrix math utilities. Uses "command"
* matrices, which are reusable.
*/
var MatrixMath = {
createIdentityMatrix: function() {
return [
1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1
];
},
createCopy: function(m) {
return [
m[0], m[1], m[2], m[3],
m[4], m[5], m[6], m[7],
m[8], m[9], m[10], m[11],
m[12], m[13], m[14], m[15],
];
},
createTranslate2d: function(x, y) {
var mat = MatrixMath.createIdentityMatrix();
MatrixMath.reuseTranslate2dCommand(mat, x, y);
return mat;
},
reuseTranslate2dCommand: function(matrixCommand, x, y) {
matrixCommand[12] = x;
matrixCommand[13] = y;
},
reuseTranslate3dCommand: function(matrixCommand, x, y, z) {
matrixCommand[12] = x;
matrixCommand[13] = y;
matrixCommand[14] = z;
},
createScale: function(factor) {
var mat = MatrixMath.createIdentityMatrix();
MatrixMath.reuseScaleCommand(mat, factor);
return mat;
},
reuseScaleCommand: function(matrixCommand, factor) {
matrixCommand[0] = factor;
matrixCommand[5] = factor;
},
reuseScale3dCommand: function(matrixCommand, x, y, z) {
matrixCommand[0] = x;
matrixCommand[5] = y;
matrixCommand[10] = z;
},
reuseScaleXCommand:function(matrixCommand, factor) {
matrixCommand[0] = factor;
},
reuseScaleYCommand:function(matrixCommand, factor) {
matrixCommand[5] = factor;
},
reuseScaleZCommand:function(matrixCommand, factor) {
matrixCommand[10] = factor;
},
reuseRotateYCommand: function(matrixCommand, amount) {
matrixCommand[0] = Math.cos(amount);
matrixCommand[2] = Math.sin(amount);
matrixCommand[8] = Math.sin(-amount);
matrixCommand[10] = Math.cos(amount);
},
createRotateZ: function(radians) {
var mat = MatrixMath.createIdentityMatrix();
MatrixMath.reuseRotateZCommand(mat, radians);
return mat;
},
// http://www.w3.org/TR/css3-transforms/#recomposing-to-a-2d-matrix
reuseRotateZCommand: function(matrixCommand, radians) {
matrixCommand[0] = Math.cos(radians);
matrixCommand[1] = Math.sin(radians);
matrixCommand[4] = -Math.sin(radians);
matrixCommand[5] = Math.cos(radians);
},
multiplyInto: function(out, a, b) {
var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3];
out[0] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
out[1] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
out[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
out[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
b0 = b[4]; b1 = b[5]; b2 = b[6]; b3 = b[7];
out[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
out[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
out[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
out[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
b0 = b[8]; b1 = b[9]; b2 = b[10]; b3 = b[11];
out[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
out[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
out[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
out[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
b0 = b[12]; b1 = b[13]; b2 = b[14]; b3 = b[15];
out[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
out[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
out[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
out[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
}
};
module.exports = MatrixMath;
});
__d('deepFreezeAndThrowOnMutationInDev',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 deepFreezeAndThrowOnMutationInDev
* @flow
*/
'use strict';
/**
* If your application is accepting different values for the same field over
* time and is doing a diff on them, you can either (1) create a copy or
* (2) ensure that those values are not mutated behind two passes.
* This function helps you with (2) by freezing the object and throwing if
* the user subsequently modifies the value.
*
* There are two caveats with this function:
* - If the call site is not in strict mode, it will only throw when
* mutating existing fields, adding a new one
* will unfortunately fail silently :(
* - If the object is already frozen or sealed, it will not continue the
* deep traversal and will leave leaf nodes unfrozen.
*
* Freezing the object and adding the throw mechanism is expensive and will
* only be used in DEV.
*/
function deepFreezeAndThrowOnMutationInDev(object ) {
if (__DEV__) {
if (typeof object !== 'object' ||
object === null ||
Object.isFrozen(object) ||
Object.isSealed(object)) {
return;
}
for (var key in object) {
if (object.hasOwnProperty(key)) {
object.__defineGetter__(key, identity.bind(null, object[key]));
object.__defineSetter__(key, throwOnImmutableMutation.bind(null, key));
deepFreezeAndThrowOnMutationInDev(object[key]);
}
}
Object.freeze(object);
Object.seal(object);
}
}
function throwOnImmutableMutation(key, value) {
throw Error(
'You attempted to set the key `' + key + '` with the value `' +
JSON.stringify(value) + '` on an object that is meant to be immutable ' +
'and has been frozen.'
);
}
function identity(value) {
return value;
}
module.exports = deepFreezeAndThrowOnMutationInDev;
});
__d('ReactIOSEventEmitter',["EventPluginHub","ReactEventEmitterMixin","ReactIOSTagHandles","NodeHandle","EventConstants","merge","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 ReactIOSEventEmitter
* @flow
*/
"use strict";
var EventPluginHub = require('EventPluginHub');
var ReactEventEmitterMixin = require('ReactEventEmitterMixin');
var ReactIOSTagHandles = require('ReactIOSTagHandles');
var NodeHandle = require('NodeHandle');
var EventConstants = require('EventConstants');
var merge = require('merge');
var warning = require('warning');
var topLevelTypes = EventConstants.topLevelTypes;
/**
* Version of `ReactBrowserEventEmitter` that works on the receiving side of a
* serialized worker boundary.
*/
// Shared default empty native event - conserve memory.
var EMPTY_NATIVE_EVENT = {};
/**
* Selects a subsequence of `Touch`es, without destroying `touches`.
*
* @param {Array<Touch>} touches Deserialized touch objects.
* @param {Array<number>} indices Indices by which to pull subsequence.
* @return {Array<Touch>} Subsequence of touch objects.
*/
var touchSubsequence = function(touches, indices) {
var ret = [];
for (var i = 0; i < indices.length; i++) {
ret.push(touches[indices[i]]);
}
return ret;
};
/**
* TODO: Pool all of this.
*
* Destroys `touches` by removing touch objects at indices `indices`. This is
* to maintain compatibility with W3C touch "end" events, where the active
* touches don't include the set that has just been "ended".
*
* @param {Array<Touch>} touches Deserialized touch objects.
* @param {Array<number>} indices Indices to remove from `touches`.
* @return {Array<Touch>} Subsequence of removed touch objects.
*/
var removeTouchesAtIndices = function(
touches ,
indices
) {
var rippedOut = [];
// use an unsafe downcast to alias to nullable elements,
// so we can delete and then compact.
var temp = (touches );
for (var i = 0; i < indices.length; i++) {
var index = indices[i];
rippedOut.push(touches[index]);
temp[index] = null;
}
var fillAt = 0;
for (var j = 0; j < temp.length; j++) {
var cur = temp[j];
if (cur !== null) {
temp[fillAt++] = cur;
}
}
temp.length = fillAt;
return rippedOut;
};
/**
* `ReactIOSEventEmitter` is used to attach top-level event listeners. For example:
*
* ReactIOSEventEmitter.putListener('myID', 'onClick', myFunction);
*
* This would allocate a "registration" of `('onClick', myFunction)` on 'myID'.
*
* @internal
*/
var ReactIOSEventEmitter = merge(ReactEventEmitterMixin, {
registrationNames: EventPluginHub.registrationNameModules,
putListener: EventPluginHub.putListener,
getListener: EventPluginHub.getListener,
deleteListener: EventPluginHub.deleteListener,
deleteAllListeners: EventPluginHub.deleteAllListeners,
/**
* Internal version of `receiveEvent` in terms of normalized (non-tag)
* `rootNodeID`.
*
* @see receiveEvent.
*
* @param {rootNodeID} rootNodeID React root node ID that event occured on.
* @param {TopLevelType} topLevelType Top level type of event.
* @param {object} nativeEventParam Object passed from native.
*/
_receiveRootNodeIDEvent: function(
rootNodeID ,
topLevelType ,
nativeEventParam
) {
var nativeEvent = nativeEventParam || EMPTY_NATIVE_EVENT;
ReactIOSEventEmitter.handleTopLevel(
topLevelType,
rootNodeID,
rootNodeID,
nativeEvent
);
},
/**
* Publically exposed method on module for native objc to invoke when a top
* level event is extracted.
* @param {rootNodeID} rootNodeID React root node ID that event occured on.
* @param {TopLevelType} topLevelType Top level type of event.
* @param {object} nativeEventParam Object passed from native.
*/
receiveEvent: function(
tag ,
topLevelType ,
nativeEventParam
) {
var rootNodeID = ReactIOSTagHandles.tagToRootNodeID[tag];
ReactIOSEventEmitter._receiveRootNodeIDEvent(
rootNodeID,
topLevelType,
nativeEventParam
);
},
/**
* Simple multi-wrapper around `receiveEvent` that is intended to receive an
* efficient representation of `Touch` objects, and other information that
* can be used to construct W3C compliant `Event` and `Touch` lists.
*
* This may create dispatch behavior that differs than web touch handling. We
* loop through each of the changed touches and receive it as a single event.
* So two `touchStart`/`touchMove`s that occur simultaneously are received as
* two separate touch event dispatches - when they arguably should be one.
*
* This implementation reuses the `Touch` objects themselves as the `Event`s
* since we dispatch an event for each touch (though that might not be spec
* compliant). The main purpose of reusing them is to save allocations.
*
* TODO: Dispatch multiple changed touches in one event. The bubble path
* could be the first common ancestor of all the `changedTouches`.
*
* One difference between this behavior and W3C spec: cancelled touches will
* not appear in `.touches`, or in any future `.touches`, though they may
* still be "actively touching the surface".
*
* Web desktop polyfills only need to construct a fake touch event with
* identifier 0, also abandoning traditional click handlers.
*/
receiveTouches: function(
eventTopLevelType ,
touches ,
changedIndices
) {
var changedTouches =
eventTopLevelType === topLevelTypes.topTouchEnd ||
eventTopLevelType === topLevelTypes.topTouchCancel ?
removeTouchesAtIndices(touches, changedIndices) :
touchSubsequence(touches, changedIndices);
for (var jj = 0; jj < changedTouches.length; jj++) {
var touch = changedTouches[jj];
// Touch objects can fullfill the role of `DOM` `Event` objects if we set
// the `changedTouches`/`touches`. This saves allocations.
touch.changedTouches = changedTouches;
touch.touches = touches;
var nativeEvent = touch;
var rootNodeID = null;
var target = nativeEvent.target;
if (target !== null && target !== undefined) {
if (target < ReactIOSTagHandles.tagsStartAt) {
if (__DEV__) {
warning(
false,
'A view is reporting that a touch occured on tag zero.'
);
}
} else {
rootNodeID = NodeHandle.getRootNodeID(target);
}
}
ReactIOSEventEmitter._receiveRootNodeIDEvent(
rootNodeID,
eventTopLevelType,
nativeEvent
);
}
}
});
module.exports = ReactIOSEventEmitter;
});
__d('ReactEventEmitterMixin',["EventPluginHub"],function(global, require, requireDynamic, requireLazy, 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;
});
__d('ReactIOSStyleAttributes',["ImageStylePropTypes","TextStylePropTypes","ViewStylePropTypes","keyMirror","matricesDiffer","sizesDiffer"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 ReactIOSStyleAttributes
* @flow
*/
'use strict';
var ImageStylePropTypes = require('ImageStylePropTypes');
var TextStylePropTypes = require('TextStylePropTypes');
var ViewStylePropTypes = require('ViewStylePropTypes');
var keyMirror = require('keyMirror');
var matricesDiffer = require('matricesDiffer');
var sizesDiffer = require('sizesDiffer');
var ReactIOSStyleAttributes = Object.assign({},
keyMirror(ViewStylePropTypes),
keyMirror(TextStylePropTypes),
keyMirror(ImageStylePropTypes)
);
ReactIOSStyleAttributes.transformMatrix = { diff: matricesDiffer };
ReactIOSStyleAttributes.shadowOffset = { diff: sizesDiffer };
module.exports = ReactIOSStyleAttributes;
});
__d('ImageStylePropTypes',["ImageResizeMode","LayoutPropTypes","ReactPropTypes","TransformPropTypes"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 ImageStylePropTypes
* @flow
*/
'use strict';
var ImageResizeMode = require('ImageResizeMode');
var LayoutPropTypes = require('LayoutPropTypes');
var ReactPropTypes = require('ReactPropTypes');
var TransformPropTypes = require('TransformPropTypes');
var ImageStylePropTypes = Object.assign({},
LayoutPropTypes,
TransformPropTypes,
{resizeMode: ReactPropTypes.oneOf(Object.keys(ImageResizeMode)),
backgroundColor: ReactPropTypes.string,
borderColor: ReactPropTypes.string,
borderWidth: ReactPropTypes.number,
borderRadius: ReactPropTypes.number,
// iOS-Specific style to "tint" an image.
// It changes the color of all the non-transparent pixels to the tintColor
tintColor: ReactPropTypes.string,
opacity: ReactPropTypes.number
});
module.exports = ImageStylePropTypes;
});
__d('ImageResizeMode',["keyMirror"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 ImageResizeMode
* @flow
*/
'use strict';
var keyMirror = require('keyMirror');
/**
* ImageResizeMode - Enum for different image resizing modes, set via
* `resizeMode` style property on `<Image>` components.
*/
var ImageResizeMode = keyMirror({
/**
* contain - The image will be resized such that it will be completely
* visible, contained within the frame of the View.
*/
contain: null,
/**
* cover - The image will be resized such that the entire area of the view
* is covered by the image, potentially clipping parts of the image.
*/
cover: null,
/**
* stretch - The image will be stretched to fill the entire frame of the
* view without clipping. This may change the aspect ratio of the image,
* distoring it.
*/
stretch: null,
});
module.exports = ImageResizeMode;
});
__d('LayoutPropTypes',["ReactPropTypes"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 LayoutPropTypes
* @flow
*/
'use strict';
var ReactPropTypes = require('ReactPropTypes');
/**
* These properties are a subset of our styles that are consumed by the layout
* algorithm and affect the positioning and sizing of views.
*/
var LayoutPropTypes = {
width: ReactPropTypes.number,
height: ReactPropTypes.number,
top: ReactPropTypes.number,
left: ReactPropTypes.number,
right: ReactPropTypes.number,
bottom: ReactPropTypes.number,
margin: ReactPropTypes.number,
marginVertical: ReactPropTypes.number,
marginHorizontal: ReactPropTypes.number,
marginTop: ReactPropTypes.number,
marginBottom: ReactPropTypes.number,
marginLeft: ReactPropTypes.number,
marginRight: ReactPropTypes.number,
padding: ReactPropTypes.number,
paddingVertical: ReactPropTypes.number,
paddingHorizontal: ReactPropTypes.number,
paddingTop: ReactPropTypes.number,
paddingBottom: ReactPropTypes.number,
paddingLeft: ReactPropTypes.number,
paddingRight: ReactPropTypes.number,
borderWidth: ReactPropTypes.number,
borderTopWidth: ReactPropTypes.number,
borderRightWidth: ReactPropTypes.number,
borderBottomWidth: ReactPropTypes.number,
borderLeftWidth: ReactPropTypes.number,
position: ReactPropTypes.oneOf([
'absolute',
'relative'
]),
// https://developer.mozilla.org/en-US/docs/Web/CSS/flex-direction
flexDirection: ReactPropTypes.oneOf([
'row',
'column'
]),
// https://developer.mozilla.org/en-US/docs/Web/CSS/flex-wrap
flexWrap: ReactPropTypes.oneOf([
'wrap',
'nowrap'
]),
// How to align children in the main direction
// https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content
justifyContent: ReactPropTypes.oneOf([
'flex-start',
'flex-end',
'center',
'space-between',
'space-around'
]),
// How to align children in the cross direction
// https://developer.mozilla.org/en-US/docs/Web/CSS/align-items
alignItems: ReactPropTypes.oneOf([
'flex-start',
'flex-end',
'center',
'stretch'
]),
// How to align the element in the cross direction
// https://developer.mozilla.org/en-US/docs/Web/CSS/align-items
alignSelf: ReactPropTypes.oneOf([
'auto',
'flex-start',
'flex-end',
'center',
'stretch'
]),
// https://developer.mozilla.org/en-US/docs/Web/CSS/flex
flex: ReactPropTypes.number,
};
module.exports = LayoutPropTypes;
});
__d('ReactPropTypes',["ReactElement","ReactFragment","ReactPropTypeLocationNames","emptyFunction"],function(global, require, requireDynamic, requireLazy, 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;
});
__d('TransformPropTypes',["ReactPropTypes"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 TransformPropTypes
* @flow
*/
'use strict';
var ReactPropTypes = require('ReactPropTypes');
var TransformPropTypes = {
transform: ReactPropTypes.arrayOf(
ReactPropTypes.oneOfType([
ReactPropTypes.shape({rotate: ReactPropTypes.string}),
ReactPropTypes.shape({scaleX: ReactPropTypes.number}),
ReactPropTypes.shape({scaleY: ReactPropTypes.number}),
ReactPropTypes.shape({translateX: ReactPropTypes.number}),
ReactPropTypes.shape({translateY: ReactPropTypes.number})
])
),
transformMatrix: ReactPropTypes.arrayOf(ReactPropTypes.number),
// DEPRECATED
rotation: ReactPropTypes.number,
scaleX: ReactPropTypes.number,
scaleY: ReactPropTypes.number,
translateX: ReactPropTypes.number,
translateY: ReactPropTypes.number,
};
module.exports = TransformPropTypes;
});
__d('TextStylePropTypes',["ReactPropTypes","ViewStylePropTypes"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 TextStylePropTypes
* @flow
*/
'use strict';
var ReactPropTypes = require('ReactPropTypes');
var ViewStylePropTypes = require('ViewStylePropTypes');
// TODO: use spread instead of Object.assign/create after #6560135 is fixed
var TextStylePropTypes = Object.assign(Object.create(ViewStylePropTypes), {
fontFamily: ReactPropTypes.string,
fontSize: ReactPropTypes.number,
fontWeight: ReactPropTypes.oneOf(
['normal' /*default*/, 'bold',
'100', '200', '300', '400', '500', '600', '700', '800', '900']
),
fontStyle: ReactPropTypes.oneOf(['normal', 'italic']),
lineHeight: ReactPropTypes.number,
color: ReactPropTypes.string,
containerBackgroundColor: ReactPropTypes.string,
textAlign: ReactPropTypes.oneOf(
['auto' /*default*/, 'left', 'right', 'center']
),
writingDirection: ReactPropTypes.oneOf(
['auto' /*default*/, 'ltr', 'rtl']
),
});
// Text doesn't support padding correctly (#4841912)
var unsupportedProps = Object.keys({
padding: null,
paddingTop: null,
paddingLeft: null,
paddingRight: null,
paddingBottom: null,
paddingVertical: null,
paddingHorizontal: null,
});
for (var ii = 0; ii < unsupportedProps.length; ii++) {
delete TextStylePropTypes[unsupportedProps[ii]];
}
module.exports = TextStylePropTypes;
});
__d('ViewStylePropTypes',["LayoutPropTypes","ReactPropTypes","TransformPropTypes"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 ViewStylePropTypes
* @flow
*/
'use strict';
var LayoutPropTypes = require('LayoutPropTypes');
var ReactPropTypes = require('ReactPropTypes');
var TransformPropTypes = require('TransformPropTypes');
/**
* Warning: Some of these properties may not be supported in all releases.
*/
var ViewStylePropTypes = Object.assign({},
LayoutPropTypes,
TransformPropTypes,
{backgroundColor: ReactPropTypes.string,
borderColor: ReactPropTypes.string,
borderTopColor: ReactPropTypes.string,
borderRightColor: ReactPropTypes.string,
borderBottomColor: ReactPropTypes.string,
borderLeftColor: ReactPropTypes.string,
borderRadius: ReactPropTypes.number,
opacity: ReactPropTypes.number,
overflow: ReactPropTypes.oneOf(['visible', 'hidden']),
shadowColor: ReactPropTypes.string,
shadowOffset: ReactPropTypes.shape(
{width: ReactPropTypes.number, height: ReactPropTypes.number}
),
shadowOpacity: ReactPropTypes.number,
shadowRadius: ReactPropTypes.number
});
module.exports = ViewStylePropTypes;
});
__d('matricesDiffer',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 matricesDiffer
*/
'use strict';
/**
* Unrolls an array comparison specially for matrices. Prioritizes
* checking of indices that are most likely to change so that the comparison
* bails as early as possible.
*
* @param {MatrixMath.Matrix} one First matrix.
* @param {MatrixMath.Matrix} two Second matrix.
* @return {boolean} Whether or not the two matrices differ.
*/
var matricesDiffer = function(one, two) {
if (one === two) {
return false;
}
return !one || !two ||
one[12] !== two[12] ||
one[13] !== two[13] ||
one[14] !== two[14] ||
one[5] !== two[5] ||
one[10] !== two[10] ||
one[1] !== two[1] ||
one[2] !== two[2] ||
one[3] !== two[3] ||
one[4] !== two[4] ||
one[6] !== two[6] ||
one[7] !== two[7] ||
one[8] !== two[8] ||
one[9] !== two[9] ||
one[11] !== two[11] ||
one[15] !== two[15];
};
module.exports = matricesDiffer;
});
__d('sizesDiffer',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule sizesDiffer
*/
'use strict';
var dummySize = {width: undefined, height: undefined};
var sizesDiffer = function(one, two) {
one = one || dummySize;
two = two || dummySize;
return one !== two && (
one.width !== two.width ||
one.height !== two.height
);
};
module.exports = sizesDiffer;
});
__d('ReactMultiChild',["ReactComponentEnvironment","ReactMultiChildUpdateTypes","ReactReconciler","ReactChildReconciler"],function(global, require, requireDynamic, requireLazy, 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;
});
__d('ReactChildReconciler',["ReactReconciler","flattenChildren","instantiateReactComponent","shouldUpdateReactComponent"],function(global, require, requireDynamic, requireLazy, 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;
});
__d('flattenChildren',["traverseAllChildren","warning"],function(global, require, requireDynamic, requireLazy, 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 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 (__DEV__) {
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
);
}
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;
});
__d('styleDiffer',["deepDiffer"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 styleDiffer
* @flow
*/
'use strict';
var deepDiffer = require('deepDiffer');
function styleDiffer(a , b ) {
return !styleEqual(a, b);
}
function styleEqual(a , b ) {
if (!a) {
return !b;
}
if (!b) {
return !a;
}
if (typeof a !== typeof b) {
return false;
}
if (typeof a === 'number') {
return a === b;
}
if (Array.isArray(a)) {
if (!Array.isArray(b) || a.length !== b.length) {
return false;
}
for (var i = 0; i < a.length; ++i) {
if (!styleEqual(a[i], b[i])) {
return false;
}
}
return true;
}
for (var key in a) {
if (deepDiffer(a[key], b[key])) {
return false;
}
}
for (var key in b) {
if (!a.hasOwnProperty(key)) {
return false;
}
}
return true;
}
module.exports = styleDiffer;
});
__d('deepDiffer',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 deepDiffer
* @flow
*/
'use strict';
/*
* @returns {bool} true if different, false if equal
*/
var deepDiffer = function(one , two ) {
if (one === two) {
// Short circuit on identical object references instead of traversing them.
return false;
}
if ((typeof one === 'function') && (typeof two === 'function')) {
// We consider all functions equal
return false;
}
if ((typeof one !== 'object') || (one === null)) {
// Primitives can be directly compared
return one !== two;
}
if ((typeof two !== 'object') || (two === null)) {
// We know they are different because the previous case would have triggered
// otherwise.
return true;
}
if (one.constructor !== two.constructor) {
return true;
}
if (Array.isArray(one)) {
// We know two is also an array because the constructors are equal
var len = one.length;
if (two.length !== len) {
return true;
}
for (var ii = 0; ii < len; ii++) {
if (deepDiffer(one[ii], two[ii])) {
return true;
}
}
} else {
for (var key in one) {
if (deepDiffer(one[key], two[key])) {
return true;
}
}
for (var twoKey in two) {
// The only case we haven't checked yet is keys that are in two but aren't
// in one, which means they are different.
if (one[twoKey] === undefined && two[twoKey] !== undefined) {
return true;
}
}
}
return false;
};
module.exports = deepDiffer;
});
__d('diffRawProperties',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 diffRawProperties
* @flow
*/
'use strict';
/**
* diffRawProperties takes two sets of props and a set of valid attributes
* and write to updatePayload the values that changed or were deleted
*
* @param {?object} updatePayload Overriden with the props that changed.
* @param {!object} prevProps Previous properties to diff against current
* properties. These properties are as supplied to component construction.
* @param {!object} prevProps Next "current" properties to diff against
* previous. These properties are as supplied to component construction.
* @return {?object}
*/
function diffRawProperties(
updatePayload ,
prevProps ,
nextProps ,
validAttributes
) {
var validAttributeConfig;
var nextProp;
var prevProp;
var isScalar;
var shouldUpdate;
if (nextProps) {
for (var propKey in nextProps) {
validAttributeConfig = validAttributes[propKey];
if (!validAttributeConfig) {
continue; // not a valid native prop
}
prevProp = prevProps && prevProps[propKey];
nextProp = nextProps[propKey];
// functions are converted to booleans as markers that the associated
// events should be sent from native.
if (typeof prevProp === 'function') {
prevProp = true;
}
if (typeof nextProp === 'function') {
nextProp = true;
}
if (prevProp !== nextProp) {
// If you want a property's diff to be detected, you must configure it
// to be so - *or* it must be a scalar property. For now, we'll allow
// creation with any attribute that is not scalar, but we should
// eventually even reject those unless they are properly configured.
isScalar = typeof nextProp !== 'object' || nextProp === null;
shouldUpdate = isScalar ||
!prevProp ||
validAttributeConfig.diff &&
validAttributeConfig.diff(prevProp, nextProp);
if (shouldUpdate) {
updatePayload = updatePayload || {};
updatePayload[propKey] = nextProp;
}
}
}
}
// Also iterate through all the previous props to catch any that have been
// removed and make sure native gets the signal so it can reset them to the
// default.
if (prevProps) {
for (var propKey in prevProps) {
validAttributeConfig = validAttributes[propKey];
if (!validAttributeConfig) {
continue; // not a valid native prop
}
if (updatePayload && updatePayload[propKey] !== undefined) {
continue; // Prop already specified
}
prevProp = prevProps[propKey];
nextProp = nextProps && nextProps[propKey];
// functions are converted to booleans as markers that the associated
// events should be sent from native.
if (typeof prevProp === 'function') {
prevProp = true;
}
if (typeof nextProp === 'function') {
nextProp = true;
}
if (prevProp !== nextProp) {
if (nextProp === undefined) {
nextProp = null; // null is a sentinel we explicitly send to native
}
// If you want a property's diff to be detected, you must configure it
// to be so - *or* it must be a scalar property. For now, we'll allow
// creation with any attribute that is not scalar, but we should
// eventually even reject those unless they are properly configured.
isScalar = typeof nextProp !== 'object' || nextProp === null;
shouldUpdate = isScalar && prevProp !== nextProp ||
validAttributeConfig.diff &&
validAttributeConfig.diff(prevProp, nextProp);
if (shouldUpdate) {
updatePayload = updatePayload || {};
updatePayload[propKey] = nextProp;
}
}
}
}
return updatePayload;
}
module.exports = diffRawProperties;
});
__d('RCTEventEmitter',["ReactIOSEventEmitter"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 RCTEventEmitter
* @flow
*/
'use strict';
var ReactIOSEventEmitter = require('ReactIOSEventEmitter');
// Completely locally implemented - no native hooks.
module.exports = ReactIOSEventEmitter;
});
__d('RCTLog',["invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 RCTLog
* @flow
*/
/* globals nativeLoggingHook */
'use strict';
var invariant = require('invariant');
var levelsMap = {
log: 'log',
info: 'info',
warn: 'warn',
error: 'error',
mustfix: 'error',
};
function RCTLog(){}
// level one of log, info, warn, error, mustfix
RCTLog.logIfNoNativeHook=function() {
var args = Array.prototype.slice.call(arguments);
var level = args.shift();
var logFn = levelsMap[level];
invariant(
logFn,
'Level "' + level + '" not one of ' + Object.keys(levelsMap)
);
if (typeof global.nativeLoggingHook === 'undefined') {
// We already printed in xcode, so only log here if using a js debugger
console[logFn].apply(console, args);
}
return true;
};
module.exports = RCTLog;
});
__d('RCTJSTimers',["JSTimersExecution"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 RCTJSTimers
* @flow
*/
'use strict';
var JSTimersExecution = require('JSTimersExecution');
var RCTJSTimers = JSTimersExecution;
module.exports = RCTJSTimers;
});
__d('deprecated',["Object.assign","warning"],function(global, require, requireDynamic, requireLazy, 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 deprecated
*/
'use strict';
var assign = require('Object.assign');
var warning = require('warning');
/**
* This will log a single deprecation notice per function and forward the call
* on to the new API.
*
* @param {string} namespace The namespace of the call, eg 'React'
* @param {string} oldName The old function name, eg 'renderComponent'
* @param {string} newName The new function name, eg 'render'
* @param {*} ctx The context this forwarded call should run in
* @param {function} fn The function to forward on to
* @return {*} Will be the value as returned from `fn`
*/
function deprecated(namespace, oldName, newName, ctx, fn) {
var warned = false;
if (__DEV__) {
var newFn = function() {
warning(
warned,
'%s.%s will be deprecated in a future version. ' +
'Use %s.%s instead.',
namespace,
oldName,
namespace,
newName
);
warned = true;
return fn.apply(ctx, arguments);
};
newFn.displayName = (namespace + "_" + oldName);
// We need to make sure all properties of the original fn are copied over.
// In particular, this is needed to support PropTypes
return assign(newFn, fn);
}
return fn;
}
module.exports = deprecated;
});
__d('onlyChild',["ReactElement","invariant"],function(global, require, requireDynamic, requireLazy, 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 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) {
invariant(
ReactElement.isValidElement(children),
'onlyChild must be passed a children with exactly one child.'
);
return children;
}
module.exports = onlyChild;
});
__d('ActivityIndicatorIOS',["NativeMethodsMixin","NativeModules","ReactPropTypes","React","StyleSheet","View","requireNativeComponent","verifyPropTypes"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 ActivityIndicatorIOS
* @flow
*/
'use strict';
var NativeMethodsMixin = require('NativeMethodsMixin');
var NativeModules = require('NativeModules');
var PropTypes = require('ReactPropTypes');
var React = require('React');
var StyleSheet = require('StyleSheet');
var View = require('View');
var requireNativeComponent = require('requireNativeComponent');
var verifyPropTypes = require('verifyPropTypes');
var GRAY = '#999999';
var ActivityIndicatorIOS = React.createClass({displayName: "ActivityIndicatorIOS",
mixins: [NativeMethodsMixin],
propTypes: {
/**
* Whether to show the indicator (true, the default) or hide it (false).
*/
animating: PropTypes.bool,
/**
* The foreground color of the spinner (default is gray).
*/
color: PropTypes.string,
/**
* Whether the indicator should hide when not animating (true by default).
*/
hidesWhenStopped: PropTypes.bool,
/**
* Size of the indicator. Small has a height of 20, large has a height of 36.
*/
size: PropTypes.oneOf([
'small',
'large',
]),
},
getDefaultProps: function() {
return {
animating: true,
color: GRAY,
hidesWhenStopped: true,
size: 'small',
};
},
render: function() {
var $__0= this.props,style=$__0.style,props=(function(source, exclusion) {var rest = {};var hasOwn = Object.prototype.hasOwnProperty;if (source == null) {throw new TypeError();}for (var key in source) {if (hasOwn.call(source, key) && !hasOwn.call(exclusion, key)) {rest[key] = source[key];}}return rest;})($__0,{style:1});
var sizeStyle = (this.props.size === 'large') ? styles.sizeLarge : styles.sizeSmall;
return (
React.createElement(View, {style: [styles.container, sizeStyle, style]},
React.createElement(RCTActivityIndicatorView, React.__spread({}, props))
)
);
}
});
var styles = StyleSheet.create({
container: {
alignItems: 'center',
justifyContent: 'center',
},
sizeSmall: {
height: 20,
},
sizeLarge: {
height: 36,
}
});
var RCTActivityIndicatorView = requireNativeComponent(
'RCTActivityIndicatorView',
null
);
if (__DEV__) {
var nativeOnlyProps = {activityIndicatorViewStyle: true};
verifyPropTypes(
ActivityIndicatorIOS,
RCTActivityIndicatorView.viewConfig,
nativeOnlyProps
);
}
module.exports = ActivityIndicatorIOS;
});
__d('StyleSheet',["StyleSheetRegistry","StyleSheetValidation"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 StyleSheet
* @flow
*/
'use strict';
var StyleSheetRegistry = require('StyleSheetRegistry');
var StyleSheetValidation = require('StyleSheetValidation');
/**
* A StyleSheet is an abstraction similar to CSS StyleSheets
*
* Create a new StyleSheet:
*
* ```
* var styles = StyleSheet.create({
* container: {
* borderRadius: 4,
* borderWidth: 0.5,
* borderColor: '#d6d7da',
* },
* title: {
* fontSize: 19,
* fontWeight: 'bold',
* },
* activeTitle: {
* color: 'red',
* },
* });
* ```
*
* Use a StyleSheet:
*
* ```
* <View style={styles.container}>
* <Text style={[styles.title, this.props.isActive && styles.activeTitle]} />
* </View>
* ```
*
* Code quality:
*
* - By moving styles away from the render function, you're making the code
* easier to understand.
* - Naming the styles is a good way to add meaning to the low level components
* in the render function.
*
* Performance:
*
* - Making a stylesheet from a style object makes it possible to refer to it
* by ID instead of creating a new style object every time.
* - It also allows to send the style only once through the bridge. All
* subsequent uses are going to refer an id (not implemented yet).
*/
function StyleSheet(){}
StyleSheet.create=function(obj ) {
var result = {};
for (var key in obj) {
StyleSheetValidation.validateStyle(key, obj);
result[key] = StyleSheetRegistry.registerStyle(obj[key]);
}
return result;
};
module.exports = StyleSheet;
});
__d('StyleSheetValidation',["ImageStylePropTypes","ReactPropTypeLocations","TextStylePropTypes","ViewStylePropTypes","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 StyleSheetValidation
* @flow
*/
'use strict';
var ImageStylePropTypes = require('ImageStylePropTypes');
var ReactPropTypeLocations = require('ReactPropTypeLocations');
var TextStylePropTypes = require('TextStylePropTypes');
var ViewStylePropTypes = require('ViewStylePropTypes');
var invariant = require('invariant');
function StyleSheetValidation(){}
StyleSheetValidation.validateStyleProp=function(prop, style, caller) {
if (!__DEV__) {
return;
}
if (allStylePropTypes[prop] === undefined) {
var message1 = '"' + prop + '" is not a valid style property.';
var message2 = '\nValid style props: ' +
JSON.stringify(Object.keys(allStylePropTypes), null, ' ');
styleError(message1, style, caller, message2);
}
var error = allStylePropTypes[prop](
style,
prop,
caller,
ReactPropTypeLocations.prop
);
if (error) {
styleError(error.message, style, caller);
}
};
StyleSheetValidation.validateStyle=function(name, styles) {
if (!__DEV__) {
return;
}
for (var prop in styles[name]) {
StyleSheetValidation.validateStyleProp(prop, styles[name], 'StyleSheet ' + name);
}
};
StyleSheetValidation.addValidStylePropTypes=function(stylePropTypes) {
for (var key in stylePropTypes) {
invariant(
allStylePropTypes[key] === undefined ||
allStylePropTypes[key] === stylePropTypes[key],
'Attemped to redefine existing style prop type "' + key + '".'
);
allStylePropTypes[key] = stylePropTypes[key];
}
};
var styleError = function(message1, style, caller , message2 ) {
invariant(
false,
message1 + '\n' + (caller || '<<unknown>>') + ': ' +
JSON.stringify(style, null, ' ') + (message2 || '')
);
};
var allStylePropTypes = {};
StyleSheetValidation.addValidStylePropTypes(ImageStylePropTypes);
StyleSheetValidation.addValidStylePropTypes(TextStylePropTypes);
StyleSheetValidation.addValidStylePropTypes(ViewStylePropTypes);
module.exports = StyleSheetValidation;
});
__d('View',["NativeMethodsMixin","ReactPropTypes","NativeModules","React","ReactIOSStyleAttributes","ReactIOSViewAttributes","StyleSheetPropType","ViewStylePropTypes","createReactIOSNativeComponentClass"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 View
* @flow
*/
'use strict';
var NativeMethodsMixin = require('NativeMethodsMixin');
var PropTypes = require('ReactPropTypes');
var RCTUIManager = require('NativeModules').UIManager;
var React = require('React');
var ReactIOSStyleAttributes = require('ReactIOSStyleAttributes');
var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
var StyleSheetPropType = require('StyleSheetPropType');
var ViewStylePropTypes = require('ViewStylePropTypes');
var createReactIOSNativeComponentClass = require('createReactIOSNativeComponentClass');
var stylePropType = StyleSheetPropType(ViewStylePropTypes);
/**
* The most fundamental component for building UI, `View` is a
* container that supports layout with flexbox, style, some touch handling, and
* accessibility controls, and is designed to be nested inside other views and
* to have 0 to many children of any type. `View` maps directly to the native
* view equivalent on whatever platform React is running on, whether that is a
* `UIView`, `<div>`, `android.view`, etc. This example creates a `View` that
* wraps two colored boxes and custom component in a row with padding.
*
* ```
* <View style={{flexDirection: 'row', height: 100, padding: 20}}>
* <View style={{backgroundColor: 'blue', flex: 0.3}} />
* <View style={{backgroundColor: 'red', flex: 0.5}} />
* <MyCustomComponent {...customProps} />
* </View>
* ```
*
* `View`s are designed to be used with `StyleSheet`s for clarity and
* performance, although inline styles are also supported.
*/
var View = React.createClass({displayName: "View",
mixins: [NativeMethodsMixin],
/**
* `NativeMethodsMixin` will look for this when invoking `setNativeProps`. We
* make `this` look like an actual native component class.
*/
viewConfig: {
uiViewClassName: 'RCTView',
validAttributes: ReactIOSViewAttributes.RCTView
},
propTypes: {
/**
* When true, indicates that the view is an accessibility element. By default,
* all the touchable elements are accessible.
*/
accessible: PropTypes.bool,
/**
* Overrides the text that's read by the screen reader when the user interacts
* with the element. By default, the label is constructed by traversing all the
* children and accumulating all the Text nodes separated by space.
*/
accessibilityLabel: PropTypes.string,
/**
* Used to locate this view in end-to-end tests.
*/
testID: PropTypes.string,
/**
* For most touch interactions, you'll simply want to wrap your component in
* `TouchableHighlight` or `TouchableOpacity`. Check out `Touchable.js`,
* `ScrollResponder.js` and `ResponderEventPlugin.js` for more discussion.
*/
onMoveShouldSetResponder: PropTypes.func,
onResponderGrant: PropTypes.func,
onResponderMove: PropTypes.func,
onResponderReject: PropTypes.func,
onResponderRelease: PropTypes.func,
onResponderTerminate: PropTypes.func,
onResponderTerminationRequest: PropTypes.func,
onStartShouldSetResponder: PropTypes.func,
onStartShouldSetResponderCapture: PropTypes.func,
/**
* Invoked on mount and layout changes with {x, y, width, height}.
*/
onLayout: PropTypes.func,
/**
* In the absence of `auto` property, `none` is much like `CSS`'s `none`
* value. `box-none` is as if you had applied the `CSS` class:
*
* ```
* .box-none {
* pointer-events: none;
* }
* .box-none * {
* pointer-events: all;
* }
* ```
*
* `box-only` is the equivalent of
*
* ```
* .box-only {
* pointer-events: all;
* }
* .box-only * {
* pointer-events: none;
* }
* ```
*
* But since `pointerEvents` does not affect layout/appearance, and we are
* already deviating from the spec by adding additional modes, we opt to not
* include `pointerEvents` on `style`. On some platforms, we would need to
* implement it as a `className` anyways. Using `style` or not is an
* implementation detail of the platform.
*/
pointerEvents: PropTypes.oneOf([
'box-none',
'none',
'box-only',
'auto',
]),
style: stylePropType,
/**
* This is a special performance property exposed by RCTView and is useful
* for scrolling content when there are many subviews, most of which are
* offscreen. For this property to be effective, it must be applied to a
* view that contains many subviews that extend outside its bound. The
* subviews must also have overflow: hidden, as should the containing view
* (or one of its superviews).
*/
removeClippedSubviews: PropTypes.bool,
/**
* Whether this view should render itself (and all of its children) into a
* single hardware texture on the GPU.
*
* On Android, this is useful for animations and interactions that only
* modify opacity, rotation, translation, and/or scale: in those cases, the
* view doesn't have to be redrawn and display lists don't need to be
* re-executed. The texture can just be re-used and re-composited with
* different parameters. The downside is that this can use up limited video
* memory, so this prop should be set back to false at the end of the
* interaction/animation.
*/
renderToHardwareTextureAndroid: PropTypes.bool,
},
render: function() {
return React.createElement(RCTView, React.__spread({}, this.props));
},
});
var RCTView = createReactIOSNativeComponentClass({
validAttributes: ReactIOSViewAttributes.RCTView,
uiViewClassName: 'RCTView',
});
RCTView.propTypes = View.propTypes;
if (__DEV__) {
var viewConfig = RCTUIManager.viewConfigs && RCTUIManager.viewConfigs.RCTView || {};
for (var prop in viewConfig.nativeProps) {
var viewAny = View; // Appease flow
if (!viewAny.propTypes[prop] && !ReactIOSStyleAttributes[prop]) {
throw new Error(
'View is missing propType for native prop `' + prop + '`'
);
}
}
}
var ViewToExport = RCTView;
if (__DEV__) {
ViewToExport = View;
}
module.exports = ViewToExport;
});
__d('ReactIOSViewAttributes',["merge"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 ReactIOSViewAttributes
* @flow
*/
'use strict';
var merge = require('merge');
var ReactIOSViewAttributes = {};
ReactIOSViewAttributes.UIView = {
pointerEvents: true,
accessible: true,
accessibilityLabel: true,
testID: true,
onLayout: true,
};
ReactIOSViewAttributes.RCTView = merge(
ReactIOSViewAttributes.UIView, {
// This is a special performance property exposed by RCTView and useful for
// scrolling content when there are many subviews, most of which are offscreen.
// For this property to be effective, it must be applied to a view that contains
// many subviews that extend outside its bound. The subviews must also have
// overflow: hidden, as should the containing view (or one of its superviews).
removeClippedSubviews: true,
});
module.exports = ReactIOSViewAttributes;
});
__d('StyleSheetPropType',["createStrictShapeTypeChecker","flattenStyle"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 StyleSheetPropType
* @flow
*/
'use strict';
var createStrictShapeTypeChecker = require('createStrictShapeTypeChecker');
var flattenStyle = require('flattenStyle');
function StyleSheetPropType(
shape
) {
var shapePropType = createStrictShapeTypeChecker(shape);
return function(props, propName, componentName, location ) {
var newProps = props;
if (props[propName]) {
// Just make a dummy prop object with only the flattened style
newProps = {};
newProps[propName] = flattenStyle(props[propName]);
}
return shapePropType(newProps, propName, componentName, location);
};
}
module.exports = StyleSheetPropType;
});
__d('createStrictShapeTypeChecker',["ReactPropTypeLocationNames","invariant","merge"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 createStrictShapeTypeChecker
* @flow
*/
'use strict';
var ReactPropTypeLocationNames = require('ReactPropTypeLocationNames');
var invariant = require('invariant');
var merge = require('merge');
function createStrictShapeTypeChecker(
shapeTypes
) {
function checkType(isRequired, props, propName, componentName, location ) {
if (!props[propName]) {
if (isRequired) {
invariant(
false,
("Required object `" + propName + "` was not specified in ")+
("`" + componentName + "`.")
);
}
return;
}
var propValue = props[propName];
var propType = typeof propValue;
var locationName =
location && ReactPropTypeLocationNames[location] || '(unknown)';
if (propType !== 'object') {
invariant(
false,
("Invalid " + locationName + " `" + propName + "` of type `" + propType + "` ") +
("supplied to `" + componentName + "`, expected `object`.")
);
}
// We need to check all keys in case some are required but missing from
// props.
var allKeys = merge(props[propName], shapeTypes);
for (var key in allKeys) {
var checker = shapeTypes[key];
if (!checker) {
invariant(
false,
("Invalid props." + propName + " key `" + key + "` supplied to `" + componentName + "`.") +
("\nBad object: ") + JSON.stringify(props[propName], null, ' ') +
("\nValid keys: ") + JSON.stringify(Object.keys(shapeTypes), null, ' ')
);
}
var error = checker(propValue, key, componentName, location);
if (error) {
invariant(
false,
error.message +
("\nBad object: ") + JSON.stringify(props[propName], null, ' ')
);
}
}
}
function chainedCheckType(
props ,
propName ,
componentName ,
location
) {
return checkType(false, props, propName, componentName, location);
}
chainedCheckType.isRequired = checkType.bind(null, true);
return chainedCheckType;
}
module.exports = createStrictShapeTypeChecker;
});
__d('requireNativeComponent',["NativeModules","UnimplementedView","createReactIOSNativeComponentClass","deepDiffer","insetsDiffer","pointsDiffer","matricesDiffer","sizesDiffer","verifyPropTypes"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 requireNativeComponent
* @flow
*/
'use strict';
var RCTUIManager = require('NativeModules').UIManager;
var UnimplementedView = require('UnimplementedView');
var createReactIOSNativeComponentClass = require('createReactIOSNativeComponentClass');
var deepDiffer = require('deepDiffer');
var insetsDiffer = require('insetsDiffer');
var pointsDiffer = require('pointsDiffer');
var matricesDiffer = require('matricesDiffer');
var sizesDiffer = require('sizesDiffer');
var verifyPropTypes = require('verifyPropTypes');
/**
* Used to create React components that directly wrap native component
* implementations. Config information is extracted from data exported from the
* RCTUIManager module. You should also wrap the native component in a
* hand-written component with full propTypes definitions and other
* documentation - pass the hand-written component in as `wrapperComponent` to
* verify all the native props are documented via `propTypes`.
*
* If some native props shouldn't be exposed in the wrapper interface, you can
* pass null for `wrapperComponent` and call `verifyPropTypes` directly
* with `nativePropsToIgnore`;
*
* Common types are lined up with the appropriate prop differs with
* `TypeToDifferMap`. Non-scalar types not in the map default to `deepDiffer`.
*/
function requireNativeComponent(
viewName ,
wrapperComponent
) {
var viewConfig = RCTUIManager[viewName];
if (!viewConfig || !viewConfig.nativeProps) {
return UnimplementedView;
}
var nativeProps = Object.assign({},
RCTUIManager.RCTView.nativeProps,
viewConfig.nativeProps
);
viewConfig.uiViewClassName = viewName;
viewConfig.validAttributes = {};
for (var key in nativeProps) {
// TODO: deep diff by default in diffRawProperties instead of setting it here
var differ = TypeToDifferMap[nativeProps[key]] || deepDiffer;
viewConfig.validAttributes[key] = {diff: differ};
}
if (__DEV__) {
wrapperComponent && verifyPropTypes(wrapperComponent, viewConfig);
}
return createReactIOSNativeComponentClass(viewConfig);
}
var TypeToDifferMap = {
// iOS Types
CATransform3D: matricesDiffer,
CGPoint: pointsDiffer,
CGSize: sizesDiffer,
UIEdgeInsets: insetsDiffer,
// Android Types
// (not yet implemented)
};
module.exports = requireNativeComponent;
});
__d('UnimplementedView',["React","StyleSheet","View"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Common implementation for a simple stubbed view. Simply applies the view's styles to the inner
* View component and renders its children.
*
* @providesModule UnimplementedView
*/
'use strict';
var React = require('React');
var StyleSheet = require('StyleSheet');
var View = require('View');
var UnimplementedView = React.createClass({displayName: "UnimplementedView",
setNativeProps: function() {
// Do nothing.
// This method is required in order to use this view as a Touchable* child.
// See ensureComponentIsNative.js for more info
},
render: function() {
return (
React.createElement(View, {style: [styles.unimplementedView, this.props.style]},
this.props.children
)
);
},
});
var styles = StyleSheet.create({
unimplementedView: {
borderWidth: 1,
borderColor: 'red',
alignSelf: 'flex-start',
}
});
module.exports = UnimplementedView;
});
__d('insetsDiffer',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 insetsDiffer
* @flow
*/
'use strict';
var dummyInsets = {
top: undefined,
left: undefined,
right: undefined,
bottom: undefined,
};
var insetsDiffer = function(
one ,
two
) {
one = one || dummyInsets;
two = two || dummyInsets;
return one !== two && (
one.top !== two.top ||
one.left !== two.left ||
one.right !== two.right ||
one.bottom !== two.bottom
);
};
module.exports = insetsDiffer;
});
__d('pointsDiffer',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 pointsDiffer
* @flow
*/
'use strict';
var dummyPoint = {x: undefined, y: undefined};
var pointsDiffer = function(one , two ) {
one = one || dummyPoint;
two = two || dummyPoint;
return one !== two && (
one.x !== two.x ||
one.y !== two.y
);
};
module.exports = pointsDiffer;
});
__d('verifyPropTypes',["ReactIOSStyleAttributes","View"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 verifyPropTypes
* @flow
*/
'use strict';
var ReactIOSStyleAttributes = require('ReactIOSStyleAttributes');
var View = require('View');
function verifyPropTypes(
component ,
viewConfig ,
nativePropsToIgnore
) {
if (!viewConfig) {
return; // This happens for UnimplementedView.
}
var nativeProps = viewConfig.nativeProps;
for (var prop in nativeProps) {
if (!component.propTypes[prop] &&
!View.propTypes[prop] &&
!ReactIOSStyleAttributes[prop] &&
(!nativePropsToIgnore || !nativePropsToIgnore[prop])) {
throw new Error(
'`' + component.displayName + '` has no propType for native prop `' +
viewConfig.uiViewClassName + '.' + prop + '` of native type `' +
nativeProps[prop].type + '`'
);
}
}
}
module.exports = verifyPropTypes;
});
__d('DatePickerIOS',["NativeMethodsMixin","ReactPropTypes","React","NativeModules","StyleSheet","View","requireNativeComponent"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 DatePickerIOS
* @flow
*
* This is a controlled component version of RCTDatePickerIOS
*/
'use strict';
var NativeMethodsMixin = require('NativeMethodsMixin');
var PropTypes = require('ReactPropTypes');
var React = require('React');
var RCTDatePickerIOSConsts = require('NativeModules').UIManager.RCTDatePicker.Constants;
var StyleSheet = require('StyleSheet');
var View = require('View');
var requireNativeComponent = require('requireNativeComponent');
var DATEPICKER = 'datepicker';
/**
* Use `DatePickerIOS` to render a date/time picker (selector) on iOS. This is
* a controlled component, so you must hook in to the `onDateChange` callback
* and update the `date` prop in order for the component to update, otherwise
* the user's change will be reverted immediately to reflect `props.date` as the
* source of truth.
*/
var DatePickerIOS = React.createClass({displayName: "DatePickerIOS",
mixins: [NativeMethodsMixin],
propTypes: {
/**
* The currently selected date.
*/
date: PropTypes.instanceOf(Date).isRequired,
/**
* Date change handler.
*
* This is called when the user changes the date or time in the UI.
* The first and only argument is a Date object representing the new
* date and time.
*/
onDateChange: PropTypes.func.isRequired,
/**
* Maximum date.
*
* Restricts the range of possible date/time values.
*/
maximumDate: PropTypes.instanceOf(Date),
/**
* Minimum date.
*
* Restricts the range of possible date/time values.
*/
minimumDate: PropTypes.instanceOf(Date),
/**
* The date picker mode.
*/
mode: PropTypes.oneOf(['date', 'time', 'datetime']),
/**
* The interval at which minutes can be selected.
*/
minuteInterval: PropTypes.oneOf([1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30]),
/**
* Timezone offset in minutes.
*
* By default, the date picker will use the device's timezone. With this
* parameter, it is possible to force a certain timezone offset. For
* instance, to show times in Pacific Standard Time, pass -7 * 60.
*/
timeZoneOffsetInMinutes: PropTypes.number,
},
getDefaultProps: function() {
return {
mode: 'datetime',
};
},
_onChange: function(event ) {
var nativeTimeStamp = event.nativeEvent.timestamp;
this.props.onDateChange && this.props.onDateChange(
new Date(nativeTimeStamp)
);
this.props.onChange && this.props.onChange(event);
// We expect the onChange* handlers to be in charge of updating our `date`
// prop. That way they can also disallow/undo/mutate the selection of
// certain values. In other words, the embedder of this component should
// be the source of truth, not the native component.
var propsTimeStamp = this.props.date.getTime();
if (nativeTimeStamp !== propsTimeStamp) {
this.refs[DATEPICKER].setNativeProps({
date: propsTimeStamp,
});
}
},
render: function() {
var props = this.props;
return (
React.createElement(View, {style: props.style},
React.createElement(RCTDatePickerIOS, {
ref: DATEPICKER,
style: styles.rkDatePickerIOS,
date: props.date.getTime(),
maximumDate:
props.maximumDate ? props.maximumDate.getTime() : undefined,
minimumDate:
props.minimumDate ? props.minimumDate.getTime() : undefined,
mode: RCTDatePickerIOSConsts.DatePickerModes[props.mode],
minuteInterval: props.minuteInterval,
timeZoneOffsetInMinutes: props.timeZoneOffsetInMinutes,
onChange: this._onChange}
)
)
);
}
});
var styles = StyleSheet.create({
rkDatePickerIOS: {
height: RCTDatePickerIOSConsts.ComponentHeight,
width: RCTDatePickerIOSConsts.ComponentWidth,
},
});
var RCTDatePickerIOS = requireNativeComponent('RCTDatePicker', DatePickerIOS);
module.exports = DatePickerIOS;
});
__d('Image',["EdgeInsetsPropType","ImageResizeMode","ImageStylePropTypes","NativeMethodsMixin","NativeModules","ReactPropTypes","React","ReactIOSViewAttributes","StyleSheet","StyleSheetPropType","flattenStyle","invariant","merge","requireNativeComponent","resolveAssetSource","verifyPropTypes","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 Image
* @flow
*/
'use strict';
var EdgeInsetsPropType = require('EdgeInsetsPropType');
var ImageResizeMode = require('ImageResizeMode');
var ImageStylePropTypes = require('ImageStylePropTypes');
var NativeMethodsMixin = require('NativeMethodsMixin');
var NativeModules = require('NativeModules');
var PropTypes = require('ReactPropTypes');
var React = require('React');
var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
var StyleSheet = require('StyleSheet');
var StyleSheetPropType = require('StyleSheetPropType');
var flattenStyle = require('flattenStyle');
var invariant = require('invariant');
var merge = require('merge');
var requireNativeComponent = require('requireNativeComponent');
var resolveAssetSource = require('resolveAssetSource');
var verifyPropTypes = require('verifyPropTypes');
var warning = require('warning');
/**
* A React component for displaying different types of images,
* including network images, static resources, temporary local images, and
* images from local disk, such as the camera roll.
*
* Example usage:
*
* ```
* renderImages: function() {
* return (
* <View>
* <Image
* style={styles.icon}
* source={require('image!myIcon')}
* />
* <Image
* style={styles.logo}
* source={{uri: 'http://facebook.github.io/react/img/logo_og.png'}}
* />
* </View>
* );
* },
* ```
*/
var Image = React.createClass({displayName: "Image",
propTypes: {
/**
* `uri` is a string representing the resource identifier for the image, which
* could be an http address, a local file path, or the name of a static image
* resource (which should be wrapped in the `required('image!name')` function).
*/
source: PropTypes.shape({
uri: PropTypes.string,
}),
/**
* A static image to display while downloading the final image off the
* network.
*/
defaultSource: PropTypes.shape({
uri: PropTypes.string,
}),
/**
* Whether this element should be revealed as an accessible element.
*/
accessible: PropTypes.bool,
/**
* Custom string to display for accessibility.
*/
accessibilityLabel: PropTypes.string,
/**
* When the image is resized, the corners of the size specified
* by capInsets will stay a fixed size, but the center content and borders
* of the image will be stretched. This is useful for creating resizable
* rounded buttons, shadows, and other resizable assets. More info on
* [Apple documentation](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImage_Class/index.html#//apple_ref/occ/instm/UIImage/resizableImageWithCapInsets)
*/
capInsets: EdgeInsetsPropType,
/**
* Determines how to resize the image when the frame doesn't match the raw
* image dimensions.
*/
resizeMode: PropTypes.oneOf(['cover', 'contain', 'stretch']),
style: StyleSheetPropType(ImageStylePropTypes),
/**
* A unique identifier for this element to be used in UI Automation
* testing scripts.
*/
testID: PropTypes.string,
},
statics: {
resizeMode: ImageResizeMode,
},
mixins: [NativeMethodsMixin],
/**
* `NativeMethodsMixin` will look for this when invoking `setNativeProps`. We
* make `this` look like an actual native component class.
*/
viewConfig: {
uiViewClassName: 'UIView',
validAttributes: ReactIOSViewAttributes.UIView
},
render: function() {
for (var prop in nativeOnlyProps) {
if (this.props[prop] !== undefined) {
console.warn('Prop `' + prop + ' = ' + this.props[prop] + '` should ' +
'not be set directly on Image.');
}
}
var source = resolveAssetSource(this.props.source) || {};
var $__0= source,width=$__0.width,height=$__0.height;
var style = flattenStyle([{width:width, height:height}, styles.base, this.props.style]);
invariant(style, 'style must be initialized');
var isNetwork = source.uri && source.uri.match(/^https?:/);
invariant(
!(isNetwork && source.isStatic),
'static image uris cannot start with "http": "' + source.uri + '"'
);
var isStored = !source.isStatic && !isNetwork;
var RawImage = isNetwork ? RCTNetworkImage : RCTStaticImage;
if (this.props.style && this.props.style.tintColor) {
warning(RawImage === RCTStaticImage, 'tintColor style only supported on static images.');
}
var resizeMode = this.props.resizeMode || style.resizeMode;
var contentModes = NativeModules.UIManager.UIView.ContentMode;
var contentMode;
if (resizeMode === ImageResizeMode.stretch) {
contentMode = contentModes.ScaleToFill;
} else if (resizeMode === ImageResizeMode.contain) {
contentMode = contentModes.ScaleAspectFit;
} else { // ImageResizeMode.cover or undefined
contentMode = contentModes.ScaleAspectFill;
}
var nativeProps = merge(this.props, {
style:style,
contentMode:contentMode,
tintColor: style.tintColor,
});
if (isStored) {
nativeProps.imageTag = source.uri;
} else {
nativeProps.src = source.uri;
}
if (this.props.defaultSource) {
nativeProps.defaultImageSrc = this.props.defaultSource.uri;
}
return React.createElement(RawImage, React.__spread({}, nativeProps));
}
});
var styles = StyleSheet.create({
base: {
overflow: 'hidden',
},
});
var RCTNetworkImage = requireNativeComponent('RCTNetworkImageView', null);
var RCTStaticImage = requireNativeComponent('RCTStaticImage', null);
var nativeOnlyProps = {
src: true,
defaultImageSrc: true,
imageTag: true,
contentMode: true,
};
if (__DEV__) {
verifyPropTypes(Image, RCTStaticImage.viewConfig, nativeOnlyProps);
verifyPropTypes(Image, RCTNetworkImage.viewConfig, nativeOnlyProps);
}
module.exports = Image;
});
__d('EdgeInsetsPropType',["ReactPropTypes","createStrictShapeTypeChecker","insetsDiffer"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 EdgeInsetsPropType
* @flow
*/
'use strict'
var PropTypes = require('ReactPropTypes');
var createStrictShapeTypeChecker = require('createStrictShapeTypeChecker');
var insetsDiffer = require('insetsDiffer');
var EdgeInsetsPropType = createStrictShapeTypeChecker({
top: PropTypes.number,
left: PropTypes.number,
bottom: PropTypes.number,
right: PropTypes.number,
});
module.exports = EdgeInsetsPropType;
});
__d('resolveAssetSource',["AssetRegistry","PixelRatio","NativeModules"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 resolveAssetSource
*/
'use strict';
var AssetRegistry = require('AssetRegistry');
var PixelRatio = require('PixelRatio');
var SourceCode = require('NativeModules').SourceCode;
var _serverURL;
function getServerURL() {
if (_serverURL === undefined) {
var scriptURL = SourceCode.scriptURL;
var match = scriptURL && scriptURL.match(/^https?:\/\/.*?\//);
if (match) {
_serverURL = match[0];
} else {
_serverURL = null;
}
}
return _serverURL;
}
function pickScale(scales, deviceScale) {
// Packager guarantees that `scales` array is sorted
for (var i = 0; i < scales.length; i++) {
if (scales[i] >= deviceScale) {
return scales[i];
}
}
// If nothing matches, device scale is larger than any available
// scales, so we return the biggest one. Unless the array is empty,
// in which case we default to 1
return scales[scales.length - 1] || 1;
}
function resolveAssetSource(source) {
if (typeof source === 'object') {
return source;
}
var asset = AssetRegistry.getAssetByID(source);
if (asset) {
return assetToImageSource(asset);
}
return null;
}
function assetToImageSource(asset) {
// TODO(frantic): currently httpServerLocation is used both as
// path in http URL and path within IPA. Should we have zipArchiveLocation?
var path = asset.httpServerLocation;
if (path[0] === '/') {
path = path.substr(1);
}
var scale = pickScale(asset.scales, PixelRatio.get());
var scaleSuffix = scale === 1 ? '' : '@' + scale + 'x';
var fileName = asset.name + scaleSuffix + '.' + asset.type;
var serverURL = getServerURL();
if (serverURL) {
return {
width: asset.width,
height: asset.height,
uri: serverURL + path + '/' + fileName +
'?hash=' + asset.hash,
isStatic: false,
};
} else {
return {
width: asset.width,
height: asset.height,
uri: path + '/' + fileName,
isStatic: true,
};
}
}
module.exports = resolveAssetSource;
module.exports.pickScale = pickScale;
});
__d('AssetRegistry',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule AssetRegistry
*/
'use strict';
var assets = [];
function registerAsset(asset) {
// `push` returns new array length, so the first asset will
// get id 1 (not 0) to make the value truthy
return assets.push(asset);
}
function getAssetByID(assetId) {
return assets[assetId - 1];
}
module.exports = { registerAsset:registerAsset, getAssetByID:getAssetByID };
});
__d('PixelRatio',["Dimensions"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 PixelRatio
* @flow
*/
'use strict';
var Dimensions = require('Dimensions');
/**
* PixelRatio class gives access to the device pixel density.
*
* There are a few use cases for using PixelRatio:
*
* ### Displaying a line that's as thin as the device permits
*
* A width of 1 is actually pretty thick on an iPhone 4+, we can do one that's
* thinner using a width of `1 / PixelRatio.get()`. It's a technique that works
* on all the devices independent of their pixel density.
*
* ```
* style={{ borderWidth: 1 / PixelRatio.get() }}
* ```
*
* ### Fetching a correctly sized image
*
* You should get a higher resolution image if you are on a high pixel density
* device. A good rule of thumb is to multiply the size of the image you display
* by the pixel ratio.
*
* ```
* var image = getImage({
* width: PixelRatio.getPixelSizeForLayoutSize(200),
* height: PixelRatio.getPixelSizeForLayoutSize(100),
* });
* <Image source={image} style={{width: 200, height: 100}} />
* ```
*/
function PixelRatio(){}
/**
* Returns the device pixel density. Some examples:
*
* - PixelRatio.get() === 2
* - iPhone 4, 4S
* - iPhone 5, 5c, 5s
* - iPhone 6
* - PixelRatio.get() === 3
* - iPhone 6 plus
* - PixelRatio.get() === 3.5
* - Nexus 6
*/
PixelRatio.get=function() {
return Dimensions.get('window').scale;
};
/**
* Converts a layout size (dp) to pixel size (px).
*
* Guaranteed to return an integer number.
*/
PixelRatio.getPixelSizeForLayoutSize=function(layoutSize ) {
return Math.round(layoutSize * PixelRatio.get());
};
// No-op for iOS, but used on the web. Should not be documented.
PixelRatio.startDetecting = function() {};
module.exports = PixelRatio;
});
__d('Dimensions',["NativeModules","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 Dimensions
* @flow
*/
'use strict';
var NativeModules = require('NativeModules');
var invariant = require('invariant');
var dimensions = NativeModules.UIManager.Dimensions;
// We calculate the window dimensions in JS so that we don't encounter loss of
// precision in transferring the dimensions (which could be non-integers) over
// the bridge.
if (dimensions && dimensions.windowPhysicalPixels) {
// parse/stringify => Clone hack
dimensions = JSON.parse(JSON.stringify(dimensions));
var windowPhysicalPixels = dimensions.windowPhysicalPixels;
dimensions.window = {
width: windowPhysicalPixels.width / windowPhysicalPixels.scale,
height: windowPhysicalPixels.height / windowPhysicalPixels.scale,
scale: windowPhysicalPixels.scale,
};
// delete so no callers rely on this existing
delete dimensions.windowPhysicalPixels;
}
function Dimensions(){}
/**
* This should only be called from native code.
*
* @param {object} dims Simple string-keyed object of dimensions to set
*/
Dimensions.set=function(dims ) {
Object.assign(dimensions, dims);
return true;
};
/**
* Initial dimensions are set before `runApplication` is called so they should
* be available before any other require's are run, but may be updated later.
*
* Note: Although dimensions are available immediately, they may change (e.g
* due to device rotation) so any rendering logic or styles that depend on
* these constants should try to call this function on every render, rather
* than caching the value (for example, using inline styles rather than
* setting a value in a `StyleSheet`).
*
* @param {string} dim Name of dimension as defined when calling `set`.
* @returns {Object?} Value for the dimension.
*/
Dimensions.get=function(dim ) {
invariant(dimensions[dim], 'No dimension set for key ' + dim);
return dimensions[dim];
};
module.exports = Dimensions;
});
__d('ListView',["ListViewDataSource","React","NativeModules","ScrollView","ScrollResponder","StaticRenderer","react-timer-mixin/TimerMixin","logError","merge","isEmpty"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015, Facebook, Inc. All rights reserved.
*
* Facebook, Inc. (“Facebook”) owns all right, title and interest, including
* all intellectual property and other proprietary rights, in and to the React
* Native CustomComponents software (the “Software”). Subject to your
* compliance with these terms, you are hereby granted a non-exclusive,
* worldwide, royalty-free copyright license to (1) use and copy the Software;
* and (2) reproduce and distribute the Software as part of your own software
* (“Your Software”). Facebook reserves all rights not expressly granted to
* you in this license agreement.
*
* THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES (INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE) ARE DISCLAIMED.
* IN NO EVENT SHALL FACEBOOK OR ITS AFFILIATES, OFFICERS, DIRECTORS OR
* EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @providesModule ListView
*/
'use strict';
var ListViewDataSource = require('ListViewDataSource');
var React = require('React');
var RCTUIManager = require('NativeModules').UIManager;
var ScrollView = require('ScrollView');
var ScrollResponder = require('ScrollResponder');
var StaticRenderer = require('StaticRenderer');
var TimerMixin = require('react-timer-mixin/TimerMixin');
var logError = require('logError');
var merge = require('merge');
var isEmpty = require('isEmpty');
var PropTypes = React.PropTypes;
var DEFAULT_PAGE_SIZE = 1;
var DEFAULT_INITIAL_ROWS = 10;
var DEFAULT_SCROLL_RENDER_AHEAD = 1000;
var DEFAULT_END_REACHED_THRESHOLD = 1000;
var DEFAULT_SCROLL_CALLBACK_THROTTLE = 50;
var RENDER_INTERVAL = 20;
var SCROLLVIEW_REF = 'listviewscroll';
/**
* ListView - A core component designed for efficient display of vertically
* scrolling lists of changing data. The minimal API is to create a
* `ListView.DataSource`, populate it with a simple array of data blobs, and
* instantiate a `ListView` component with that data source and a `renderRow`
* callback which takes a blob from the data array and returns a renderable
* component.
*
* Minimal example:
*
* ```
* getInitialState: function() {
* var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
* return {
* dataSource: ds.cloneWithRows(['row 1', 'row 2']),
* };
* },
*
* render: function() {
* return (
* <ListView
* dataSource={this.state.dataSource}
* renderRow={(rowData) => <Text>{rowData}</Text>}
* />
* );
* },
* ```
*
* ListView also supports more advanced features, including sections with sticky
* section headers, header and footer support, callbacks on reaching the end of
* the available data (`onEndReached`) and on the set of rows that are visible
* in the device viewport change (`onChangeVisibleRows`), and several
* performance optimizations.
*
* There are a few performance operations designed to make ListView scroll
* smoothly while dynamically loading potentially very large (or conceptually
* infinite) data sets:
*
* * Only re-render changed rows - the hasRowChanged function provided to the
* data source tells the ListView if it needs to re-render a row because the
* source data has changed - see ListViewDataSource for more details.
*
* * Rate-limited row rendering - By default, only one row is rendered per
* event-loop (customizable with the `pageSize` prop). This breaks up the
* work into smaller chunks to reduce the chance of dropping frames while
* rendering rows.
*/
var ListView = React.createClass({displayName: "ListView",
mixins: [ScrollResponder.Mixin, TimerMixin],
statics: {
DataSource: ListViewDataSource,
},
/**
* You must provide a renderRow function. If you omit any of the other render
* functions, ListView will simply skip rendering them.
*
* - renderRow(rowData, sectionID, rowID);
* - renderSectionHeader(sectionData, sectionID);
*/
propTypes: Object.assign({},
ScrollView.propTypes,
{dataSource: PropTypes.instanceOf(ListViewDataSource).isRequired,
/**
* (rowData, sectionID, rowID) => renderable
* Takes a data entry from the data source and its ids and should return
* a renderable component to be rendered as the row. By default the data
* is exactly what was put into the data source, but it's also possible to
* provide custom extractors.
*/
renderRow: PropTypes.func.isRequired,
/**
* How many rows to render on initial component mount. Use this to make
* it so that the first screen worth of data apears at one time instead of
* over the course of multiple frames.
*/
initialListSize: PropTypes.number,
/**
* Called when all rows have been rendered and the list has been scrolled
* to within onEndReachedThreshold of the bottom. The native scroll
* event is provided.
*/
onEndReached: PropTypes.func,
/**
* Threshold in pixels for onEndReached.
*/
onEndReachedThreshold: PropTypes.number,
/**
* Number of rows to render per event loop.
*/
pageSize: PropTypes.number,
/**
* () => renderable
*
* The header and footer are always rendered (if these props are provided)
* on every render pass. If they are expensive to re-render, wrap them
* in StaticContainer or other mechanism as appropriate. Footer is always
* at the bottom of the list, and header at the top, on every render pass.
*/
renderFooter: PropTypes.func,
renderHeader: PropTypes.func,
/**
* (sectionData, sectionID) => renderable
*
* If provided, a sticky header is rendered for this section. The sticky
* behavior means that it will scroll with the content at the top of the
* section until it reaches the top of the screen, at which point it will
* stick to the top until it is pushed off the screen by the next section
* header.
*/
renderSectionHeader: PropTypes.func,
/**
* How early to start rendering rows before they come on screen, in
* pixels.
*/
scrollRenderAheadDistance: React.PropTypes.number,
/**
* (visibleRows, changedRows) => void
*
* Called when the set of visible rows changes. `visibleRows` maps
* { sectionID: { rowID: true }} for all the visible rows, and
* `changedRows` maps { sectionID: { rowID: true | false }} for the rows
* that have changed their visibility, with true indicating visible, and
* false indicating the view has moved out of view.
*/
onChangeVisibleRows: React.PropTypes.func,
/**
* An experimental performance optimization for improving scroll perf of
* large lists, used in conjunction with overflow: 'hidden' on the row
* containers. Use at your own risk.
*/
removeClippedSubviews: React.PropTypes.bool
}),
/**
* Exports some data, e.g. for perf investigations or analytics.
*/
getMetrics: function() {
return {
contentHeight: this.scrollProperties.contentHeight,
totalRows: this.props.dataSource.getRowCount(),
renderedRows: this.state.curRenderedRowsCount,
visibleRows: Object.keys(this._visibleRows).length,
};
},
/**
* Provides a handle to the underlying scroll responder to support operations
* such as scrollTo.
*/
getScrollResponder: function() {
return this.refs[SCROLLVIEW_REF];
},
setNativeProps: function(props) {
this.refs[SCROLLVIEW_REF].setNativeProps(props);
},
/**
* React life cycle hooks.
*/
getDefaultProps: function() {
return {
initialListSize: DEFAULT_INITIAL_ROWS,
pageSize: DEFAULT_PAGE_SIZE,
scrollRenderAheadDistance: DEFAULT_SCROLL_RENDER_AHEAD,
onEndReachedThreshold: DEFAULT_END_REACHED_THRESHOLD,
};
},
getInitialState: function() {
return {
curRenderedRowsCount: this.props.initialListSize,
prevRenderedRowsCount: 0,
};
},
componentWillMount: function() {
// this data should never trigger a render pass, so don't put in state
this.scrollProperties = {
visibleHeight: null,
contentHeight: null,
offsetY: 0
};
this._childFrames = [];
this._visibleRows = {};
},
componentDidMount: function() {
// do this in animation frame until componentDidMount actually runs after
// the component is laid out
this.requestAnimationFrame(function() {
this._measureAndUpdateScrollProps();
this.setInterval(this._renderMoreRowsIfNeeded, RENDER_INTERVAL);
}.bind(this));
},
componentWillReceiveProps: function(nextProps) {
if (this.props.dataSource !== nextProps.dataSource) {
this.setState({prevRenderedRowsCount: 0});
}
},
render: function() {
var bodyComponents = [];
var dataSource = this.props.dataSource;
var allRowIDs = dataSource.rowIdentities;
var rowCount = 0;
var sectionHeaderIndices = [];
var header = this.props.renderHeader && this.props.renderHeader();
var footer = this.props.renderFooter && this.props.renderFooter();
var totalIndex = header ? 1 : 0;
for (var sectionIdx = 0; sectionIdx < allRowIDs.length; sectionIdx++) {
var sectionID = dataSource.sectionIdentities[sectionIdx];
var rowIDs = allRowIDs[sectionIdx];
if (rowIDs.length === 0) {
continue;
}
if (this.props.renderSectionHeader) {
var shouldUpdateHeader = rowCount >= this.state.prevRenderedRowsCount &&
dataSource.sectionHeaderShouldUpdate(sectionIdx);
bodyComponents.push(
React.createElement(StaticRenderer, {
key: 's_' + sectionID,
shouldUpdate: !!shouldUpdateHeader,
render: this.props.renderSectionHeader.bind(
null,
dataSource.getSectionHeaderData(sectionIdx),
sectionID
)}
)
);
sectionHeaderIndices.push(totalIndex++);
}
for (var rowIdx = 0; rowIdx < rowIDs.length; rowIdx++) {
var rowID = rowIDs[rowIdx];
var comboID = sectionID + rowID;
var shouldUpdateRow = rowCount >= this.state.prevRenderedRowsCount &&
dataSource.rowShouldUpdate(sectionIdx, rowIdx);
var row =
React.createElement(StaticRenderer, {
key: 'r_' + comboID,
shouldUpdate: !!shouldUpdateRow,
render: this.props.renderRow.bind(
null,
dataSource.getRowData(sectionIdx, rowIdx),
sectionID,
rowID
)}
);
bodyComponents.push(row);
totalIndex++;
if (++rowCount === this.state.curRenderedRowsCount) {
break;
}
}
if (rowCount >= this.state.curRenderedRowsCount) {
break;
}
}
var props = merge(
this.props, {
onScroll: this._onScroll,
stickyHeaderIndices: sectionHeaderIndices,
}
);
if (!props.scrollEventThrottle) {
props.scrollEventThrottle = DEFAULT_SCROLL_CALLBACK_THROTTLE;
}
return (
React.createElement(ScrollView, React.__spread({}, props,
{ref: SCROLLVIEW_REF}),
header,
bodyComponents,
footer
)
);
},
/**
* Private methods
*/
_measureAndUpdateScrollProps: function() {
RCTUIManager.measureLayout(
this.refs[SCROLLVIEW_REF].getInnerViewNode(),
this.refs[SCROLLVIEW_REF].getNodeHandle(),
logError,
this._setScrollContentHeight
);
RCTUIManager.measureLayoutRelativeToParent(
this.refs[SCROLLVIEW_REF].getNodeHandle(),
logError,
this._setScrollVisibleHeight
);
},
_setScrollContentHeight: function(left, top, width, height) {
this.scrollProperties.contentHeight = height;
},
_setScrollVisibleHeight: function(left, top, width, height) {
this.scrollProperties.visibleHeight = height;
this._updateVisibleRows();
},
_renderMoreRowsIfNeeded: function() {
if (this.scrollProperties.contentHeight === null ||
this.scrollProperties.visibleHeight === null ||
this.state.curRenderedRowsCount === this.props.dataSource.getRowCount()) {
return;
}
var distanceFromEnd = this._getDistanceFromEnd(this.scrollProperties);
if (distanceFromEnd < this.props.scrollRenderAheadDistance) {
this._pageInNewRows();
}
},
_pageInNewRows: function() {
var rowsToRender = Math.min(
this.state.curRenderedRowsCount + this.props.pageSize,
this.props.dataSource.getRowCount()
);
this.setState(
{
prevRenderedRowsCount: this.state.curRenderedRowsCount,
curRenderedRowsCount: rowsToRender
},
function() {
this._measureAndUpdateScrollProps();
this.setState({
prevRenderedRowsCount: this.state.curRenderedRowsCount,
});
}.bind(this)
);
},
_getDistanceFromEnd: function(scrollProperties) {
return scrollProperties.contentHeight -
scrollProperties.visibleHeight -
scrollProperties.offsetY;
},
_updateVisibleRows: function(e) {
if (!this.props.onChangeVisibleRows) {
return; // No need to compute visible rows if there is no callback
}
var updatedFrames = e && e.nativeEvent.updatedChildFrames;
if (updatedFrames) {
updatedFrames.forEach(function(frame) {
this._childFrames[frame.index] = merge(frame);
}.bind(this));
}
var dataSource = this.props.dataSource;
var visibleTop = this.scrollProperties.offsetY;
var visibleBottom = visibleTop + this.scrollProperties.visibleHeight;
var allRowIDs = dataSource.rowIdentities;
var header = this.props.renderHeader && this.props.renderHeader();
var totalIndex = header ? 1 : 0;
var visibilityChanged = false;
var changedRows = {};
for (var sectionIdx = 0; sectionIdx < allRowIDs.length; sectionIdx++) {
var rowIDs = allRowIDs[sectionIdx];
if (rowIDs.length === 0) {
continue;
}
var sectionID = dataSource.sectionIdentities[sectionIdx];
if (this.props.renderSectionHeader) {
totalIndex++;
}
var visibleSection = this._visibleRows[sectionID];
if (!visibleSection) {
visibleSection = {};
}
for (var rowIdx = 0; rowIdx < rowIDs.length; rowIdx++) {
var rowID = rowIDs[rowIdx];
var frame = this._childFrames[totalIndex];
totalIndex++;
if (!frame) {
break;
}
var rowVisible = visibleSection[rowID];
var top = frame.y;
var bottom = top + frame.height;
if (top > visibleBottom || bottom < visibleTop) {
if (rowVisible) {
visibilityChanged = true;
delete visibleSection[rowID];
if (!changedRows[sectionID]) {
changedRows[sectionID] = {};
}
changedRows[sectionID][rowID] = false;
}
} else if (!rowVisible) {
visibilityChanged = true;
visibleSection[rowID] = true;
if (!changedRows[sectionID]) {
changedRows[sectionID] = {};
}
changedRows[sectionID][rowID] = true;
}
}
if (!isEmpty(visibleSection)) {
this._visibleRows[sectionID] = visibleSection;
} else if (this._visibleRows[sectionID]) {
delete this._visibleRows[sectionID];
}
}
visibilityChanged && this.props.onChangeVisibleRows(this._visibleRows, changedRows);
},
_onScroll: function(e) {
this.scrollProperties.visibleHeight = e.nativeEvent.layoutMeasurement.height;
this.scrollProperties.contentHeight = e.nativeEvent.contentSize.height;
this.scrollProperties.offsetY = e.nativeEvent.contentOffset.y;
this._updateVisibleRows(e);
var nearEnd = this._getDistanceFromEnd(this.scrollProperties) < this.props.onEndReachedThreshold;
if (nearEnd &&
this.props.onEndReached &&
this.scrollProperties.contentHeight !== this._sentEndForContentHeight &&
this.state.curRenderedRowsCount === this.props.dataSource.getRowCount()) {
this._sentEndForContentHeight = this.scrollProperties.contentHeight;
this.props.onEndReached(e);
} else {
this._renderMoreRowsIfNeeded();
}
this.props.onScroll && this.props.onScroll(e);
},
});
module.exports = ListView;
});
__d('ListViewDataSource',["invariant","isEmpty","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015, Facebook, Inc. All rights reserved.
*
* Facebook, Inc. (“Facebook”) owns all right, title and interest, including
* all intellectual property and other proprietary rights, in and to the React
* Native CustomComponents software (the “Software”). Subject to your
* compliance with these terms, you are hereby granted a non-exclusive,
* worldwide, royalty-free copyright license to (1) use and copy the Software;
* and (2) reproduce and distribute the Software as part of your own software
* (“Your Software”). Facebook reserves all rights not expressly granted to
* you in this license agreement.
*
* THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES (INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE) ARE DISCLAIMED.
* IN NO EVENT SHALL FACEBOOK OR ITS AFFILIATES, OFFICERS, DIRECTORS OR
* EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @providesModule ListViewDataSource
* @typechecks
* @flow
*/
'use strict';
var invariant = require('invariant');
var isEmpty = require('isEmpty');
var warning = require('warning');
function defaultGetRowData(
dataBlob ,
sectionID ,
rowID
) {
return dataBlob[sectionID][rowID];
}
function defaultGetSectionHeaderData(
dataBlob ,
sectionID
) {
return dataBlob[sectionID];
}
/**
* Provides efficient data processing and access to the
* `ListView` component. A `ListViewDataSource` is created with functions for
* extracting data from the input blob, and comparing elements (with default
* implementations for convenience). The input blob can be as simple as an
* array of strings, or an object with rows nested inside section objects.
*
* To update the data in the datasource, use `cloneWithRows` (or
* `cloneWithRowsAndSections` if you care about sections). The data in the
* data source is immutable, so you can't modify it directly. The clone methods
* suck in the new data and compute a diff for each row so ListView knows
* whether to re-render it or not.
*
* In this example, a component receives data in chunks, handled by
* `_onDataArrived`, which concats the new data onto the old data and updates the
* data source. We use `concat` to create a new array - mutating `this._data`,
* e.g. with `this._data.push(newRowData)`, would be an error. `_rowHasChanged`
* understands the shape of the row data and knows how to efficiently compare
* it.
*
* ```
* getInitialState: function() {
* var ds = new ListViewDataSource({rowHasChanged: this._rowHasChanged});
* return {ds};
* },
* _onDataArrived(newData) {
* this._data = this._data.concat(newData);
* this.setState({
* ds: this.state.ds.cloneWithRows(this._data)
* });
* }
* ```
*/
/**
* You can provide custom extraction and `hasChanged` functions for section
* headers and rows. If absent, data will be extracted with the
* `defaultGetRowData` and `defaultGetSectionHeaderData` functions.
*
* The default extractor expects data of one of the following forms:
*
* { sectionID_1: { rowID_1: <rowData1>, ... }, ... }
*
* or
*
* [ [ <rowData1>, <rowData2>, ... ], ... ]
*
* The constructor takes in a params argument that can contain any of the
* following:
*
* - getRowData(dataBlob, sectionID, rowID);
* - getSectionHeaderData(dataBlob, sectionID);
* - rowHasChanged(prevRowData, nextRowData);
* - sectionHeaderHasChanged(prevSectionData, nextSectionData);
*/
function ListViewDataSource(params ) {
invariant(
params && typeof params.rowHasChanged === 'function',
'Must provide a rowHasChanged function.'
);
this.$ListViewDataSource_rowHasChanged = params.rowHasChanged;
this.$ListViewDataSource_getRowData = params.getRowData || defaultGetRowData;
this.$ListViewDataSource_sectionHeaderHasChanged = params.sectionHeaderHasChanged;
this.$ListViewDataSource_getSectionHeaderData =
params.getSectionHeaderData || defaultGetSectionHeaderData;
this.$ListViewDataSource_dataBlob = null;
this.$ListViewDataSource_dirtyRows = [];
this.$ListViewDataSource_dirtySections = [];
this.$ListViewDataSource_cachedRowCount = 0;
// These two private variables are accessed by outsiders because ListView
// uses them to iterate over the data in this class.
this.rowIdentities = [];
this.sectionIdentities = [];
}
/**
* Clones this `ListViewDataSource` with the specified `dataBlob` and
* `rowIdentities`. The `dataBlob` is just an aribitrary blob of data. At
* construction an extractor to get the interesting informatoin was defined
* (or the default was used).
*
* The `rowIdentities` is is a 2D array of identifiers for rows.
* ie. [['a1', 'a2'], ['b1', 'b2', 'b3'], ...]. If not provided, it's
* assumed that the keys of the section data are the row identities.
*
* Note: This function does NOT clone the data in this data source. It simply
* passes the functions defined at construction to a new data source with
* the data specified. If you wish to maintain the existing data you must
* handle merging of old and new data separately and then pass that into
* this function as the `dataBlob`.
*/
ListViewDataSource.prototype.cloneWithRows=function(
dataBlob ,
rowIdentities
) {
var rowIds = rowIdentities ? [rowIdentities] : null;
if (!this.$ListViewDataSource_sectionHeaderHasChanged) {
this.$ListViewDataSource_sectionHeaderHasChanged = function() {return false;};
}
return this.cloneWithRowsAndSections({s1: dataBlob}, ['s1'], rowIds);
};
/**
* This performs the same function as the `cloneWithRows` function but here
* you also specify what your `sectionIdentities` are. If you don't care
* about sections you should safely be able to use `cloneWithRows`.
*
* `sectionIdentities` is an array of identifiers for sections.
* ie. ['s1', 's2', ...]. If not provided, it's assumed that the
* keys of dataBlob are the section identities.
*
* Note: this returns a new object!
*/
ListViewDataSource.prototype.cloneWithRowsAndSections=function(
dataBlob ,
sectionIdentities ,
rowIdentities
) {
invariant(
typeof this.$ListViewDataSource_sectionHeaderHasChanged === 'function',
'Must provide a sectionHeaderHasChanged function with section data.'
);
var newSource = new ListViewDataSource({
getRowData: this.$ListViewDataSource_getRowData,
getSectionHeaderData: this.$ListViewDataSource_getSectionHeaderData,
rowHasChanged: this.$ListViewDataSource_rowHasChanged,
sectionHeaderHasChanged: this.$ListViewDataSource_sectionHeaderHasChanged,
});
newSource.$ListViewDataSource_dataBlob = dataBlob;
if (sectionIdentities) {
newSource.sectionIdentities = sectionIdentities;
} else {
newSource.sectionIdentities = Object.keys(dataBlob);
}
if (rowIdentities) {
newSource.rowIdentities = rowIdentities;
} else {
newSource.rowIdentities = [];
newSource.sectionIdentities.forEach(function(sectionID) {
newSource.rowIdentities.push(Object.keys(dataBlob[sectionID]));
});
}
newSource.$ListViewDataSource_cachedRowCount = countRows(newSource.rowIdentities);
newSource.$ListViewDataSource_calculateDirtyArrays(
this.$ListViewDataSource_dataBlob,
this.sectionIdentities,
this.rowIdentities
);
return newSource;
};
ListViewDataSource.prototype.getRowCount=function() {
return this.$ListViewDataSource_cachedRowCount;
};
/**
* Returns if the row is dirtied and needs to be rerendered
*/
ListViewDataSource.prototype.rowShouldUpdate=function(sectionIndex , rowIndex ) {
var needsUpdate = this.$ListViewDataSource_dirtyRows[sectionIndex][rowIndex];
warning(needsUpdate !== undefined,
'missing dirtyBit for section, row: ' + sectionIndex + ', ' + rowIndex);
return needsUpdate;
};
/**
* Gets the data required to render the row.
*/
ListViewDataSource.prototype.getRowData=function(sectionIndex , rowIndex ) {
var sectionID = this.sectionIdentities[sectionIndex];
var rowID = this.rowIdentities[sectionIndex][rowIndex];
warning(
sectionID !== undefined && rowID !== undefined,
'rendering invalid section, row: ' + sectionIndex + ', ' + rowIndex
);
return this.$ListViewDataSource_getRowData(this.$ListViewDataSource_dataBlob, sectionID, rowID);
};
/**
* Gets the rowID at index provided if the dataSource arrays were flattened,
* or null of out of range indexes.
*/
ListViewDataSource.prototype.getRowIDForFlatIndex=function(index ) {
var accessIndex = index;
for (var ii = 0; ii < this.sectionIdentities.length; ii++) {
if (accessIndex >= this.rowIdentities[ii].length) {
accessIndex -= this.rowIdentities[ii].length;
} else {
return this.rowIdentities[ii][accessIndex];
}
}
return null;
};
/**
* Gets the sectionID at index provided if the dataSource arrays were flattened,
* or null for out of range indexes.
*/
ListViewDataSource.prototype.getSectionIDForFlatIndex=function(index ) {
var accessIndex = index;
for (var ii = 0; ii < this.sectionIdentities.length; ii++) {
if (accessIndex >= this.rowIdentities[ii].length) {
accessIndex -= this.rowIdentities[ii].length;
} else {
return this.sectionIdentities[ii];
}
}
return null;
};
/**
* Returns an array containing the number of rows in each section
*/
ListViewDataSource.prototype.getSectionLengths=function() {
var results = [];
for (var ii = 0; ii < this.sectionIdentities.length; ii++) {
results.push(this.rowIdentities[ii].length);
}
return results;
};
/**
* Returns if the section header is dirtied and needs to be rerendered
*/
ListViewDataSource.prototype.sectionHeaderShouldUpdate=function(sectionIndex ) {
var needsUpdate = this.$ListViewDataSource_dirtySections[sectionIndex];
warning(needsUpdate !== undefined,
'missing dirtyBit for section: ' + sectionIndex);
return needsUpdate;
};
/**
* Gets the data required to render the section header
*/
ListViewDataSource.prototype.getSectionHeaderData=function(sectionIndex ) {
if (!this.$ListViewDataSource_getSectionHeaderData) {
return null;
}
var sectionID = this.sectionIdentities[sectionIndex];
warning(sectionID !== undefined,
'renderSection called on invalid section: ' + sectionIndex);
return this.$ListViewDataSource_getSectionHeaderData(this.$ListViewDataSource_dataBlob, sectionID);
};
/**
* Private members and methods.
*/
// These two 'protected' variables are accessed by ListView to iterate over
// the data in this class.
ListViewDataSource.prototype.$ListViewDataSource_calculateDirtyArrays=function(
prevDataBlob ,
prevSectionIDs ,
prevRowIDs
) {
// construct a hashmap of the existing (old) id arrays
var prevSectionsHash = keyedDictionaryFromArray(prevSectionIDs);
var prevRowsHash = {};
for (var ii = 0; ii < prevRowIDs.length; ii++) {
var sectionID = prevSectionIDs[ii];
warning(
!prevRowsHash[sectionID],
'SectionID appears more than once: ' + sectionID
);
prevRowsHash[sectionID] = keyedDictionaryFromArray(prevRowIDs[ii]);
}
// compare the 2 identity array and get the dirtied rows
this.$ListViewDataSource_dirtySections = [];
this.$ListViewDataSource_dirtyRows = [];
var dirty;
for (var sIndex = 0; sIndex < this.sectionIdentities.length; sIndex++) {
var sectionID = this.sectionIdentities[sIndex];
// dirty if the sectionHeader is new or _sectionHasChanged is true
dirty = !prevSectionsHash[sectionID];
var sectionHeaderHasChanged = this.$ListViewDataSource_sectionHeaderHasChanged;
if (!dirty && sectionHeaderHasChanged) {
dirty = sectionHeaderHasChanged(
this.$ListViewDataSource_getSectionHeaderData(prevDataBlob, sectionID),
this.$ListViewDataSource_getSectionHeaderData(this.$ListViewDataSource_dataBlob, sectionID)
);
}
this.$ListViewDataSource_dirtySections.push(!!dirty);
this.$ListViewDataSource_dirtyRows[sIndex] = [];
for (var rIndex = 0; rIndex < this.rowIdentities[sIndex].length; rIndex++) {
var rowID = this.rowIdentities[sIndex][rIndex];
// dirty if the section is new, row is new or _rowHasChanged is true
dirty =
!prevSectionsHash[sectionID] ||
!prevRowsHash[sectionID][rowID] ||
this.$ListViewDataSource_rowHasChanged(
this.$ListViewDataSource_getRowData(prevDataBlob, sectionID, rowID),
this.$ListViewDataSource_getRowData(this.$ListViewDataSource_dataBlob, sectionID, rowID)
);
this.$ListViewDataSource_dirtyRows[sIndex].push(!!dirty);
}
}
};
function countRows(allRowIDs) {
var totalRows = 0;
for (var sectionIdx = 0; sectionIdx < allRowIDs.length; sectionIdx++) {
var rowIDs = allRowIDs[sectionIdx];
totalRows += rowIDs.length;
}
return totalRows;
}
function keyedDictionaryFromArray(arr) {
if (isEmpty(arr)) {
return {};
}
var result = {};
for (var ii = 0; ii < arr.length; ii++) {
var key = arr[ii];
warning(!result[key], 'Value appears more than once in array: ' + key);
result[key] = true;
}
return result;
}
module.exports = ListViewDataSource;
});
__d('isEmpty',[],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* @generated SignedSource<<97ffcebc9ae390e734026a4f3964bff6>>
*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* !! This file is a check-in of a static_upstream project! !!
* !! !!
* !! You should not modify this file directly. Instead: !!
* !! 1) Use `fjs use-upstream` to temporarily replace this with !!
* !! the latest version from upstream. !!
* !! 2) Make your changes, test them, etc. !!
* !! 3) Use `fjs push-upstream` to copy your changes back to !!
* !! static_upstream. !!
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
* @providesModule isEmpty
*/
/**
* Mimics empty from PHP.
*/
function isEmpty(obj) {
if (Array.isArray(obj)) {
return obj.length === 0;
} else if (typeof obj === 'object') {
for (var i in obj) {
return false;
}
return true;
} else {
return !obj;
}
}
module.exports = isEmpty;
});
__d('ScrollView',["EdgeInsetsPropType","Platform","PointPropType","NativeModules","React","ReactIOSViewAttributes","NativeModules","ScrollResponder","StyleSheet","StyleSheetPropType","View","ViewStylePropTypes","createReactIOSNativeComponentClass","deepDiffer","flattenStyle","insetsDiffer","invariant","pointsDiffer","requireNativeComponent"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 ScrollView
* @flow
*/
'use strict';
var EdgeInsetsPropType = require('EdgeInsetsPropType');
var Platform = require('Platform');
var PointPropType = require('PointPropType');
var RCTScrollView = require('NativeModules').UIManager.RCTScrollView;
var RCTScrollViewConsts = RCTScrollView.Constants;
var React = require('React');
var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
var RCTUIManager = require('NativeModules').UIManager;
var ScrollResponder = require('ScrollResponder');
var StyleSheet = require('StyleSheet');
var StyleSheetPropType = require('StyleSheetPropType');
var View = require('View');
var ViewStylePropTypes = require('ViewStylePropTypes');
var createReactIOSNativeComponentClass = require('createReactIOSNativeComponentClass');
var deepDiffer = require('deepDiffer');
var flattenStyle = require('flattenStyle');
var insetsDiffer = require('insetsDiffer');
var invariant = require('invariant');
var pointsDiffer = require('pointsDiffer');
var requireNativeComponent = require('requireNativeComponent');
var PropTypes = React.PropTypes;
var SCROLLVIEW = 'ScrollView';
var INNERVIEW = 'InnerScrollView';
var keyboardDismissModeConstants = {
'none': RCTScrollViewConsts.KeyboardDismissMode.None, // default
'interactive': RCTScrollViewConsts.KeyboardDismissMode.Interactive,
'onDrag': RCTScrollViewConsts.KeyboardDismissMode.OnDrag,
};
/**
* Component that wraps platform ScrollView while providing
* integration with touch locking "responder" system.
*
* Doesn't yet support other contained responders from blocking this scroll
* view from becoming the responder.
*/
var ScrollView = React.createClass({displayName: "ScrollView",
propTypes: {
automaticallyAdjustContentInsets: PropTypes.bool, // true
contentInset: EdgeInsetsPropType, // zeros
contentOffset: PointPropType, // zeros
onScroll: PropTypes.func,
onScrollAnimationEnd: PropTypes.func,
scrollEnabled: PropTypes.bool, // true
scrollIndicatorInsets: EdgeInsetsPropType, // zeros
showsHorizontalScrollIndicator: PropTypes.bool,
showsVerticalScrollIndicator: PropTypes.bool,
style: StyleSheetPropType(ViewStylePropTypes),
scrollEventThrottle: PropTypes.number, // null
/**
* When true, the scroll view bounces when it reaches the end of the
* content if the content is larger then the scroll view along the axis of
* the scroll direction. When false, it disables all bouncing even if
* the `alwaysBounce*` props are true. The default value is true.
*/
bounces: PropTypes.bool,
/**
* When true, gestures can drive zoom past min/max and the zoom will animate
* to the min/max value at gesture end, otherwise the zoom will not exceed
* the limits.
*/
bouncesZoom: PropTypes.bool,
/**
* When true, the scroll view bounces horizontally when it reaches the end
* even if the content is smaller than the scroll view itself. The default
* value is true when `horizontal={true}` and false otherwise.
*/
alwaysBounceHorizontal: PropTypes.bool,
/**
* When true, the scroll view bounces vertically when it reaches the end
* even if the content is smaller than the scroll view itself. The default
* value is false when `horizontal={true}` and true otherwise.
*/
alwaysBounceVertical: PropTypes.bool,
/**
* When true, the scroll view automatically centers the content when the
* content is smaller than the scroll view bounds; when the content is
* larger than the scroll view, this property has no effect. The default
* value is false.
*/
centerContent: PropTypes.bool,
/**
* These styles will be applied to the scroll view content container which
* wraps all of the child views. Example:
*
* return (
* <ScrollView contentContainerStyle={styles.contentContainer}>
* </ScrollView>
* );
* ...
* var styles = StyleSheet.create({
* contentContainer: {
* paddingVertical: 20
* }
* });
*/
contentContainerStyle: StyleSheetPropType(ViewStylePropTypes),
/**
* A floating-point number that determines how quickly the scroll view
* decelerates after the user lifts their finger. Reasonable choices include
* - Normal: 0.998 (the default)
* - Fast: 0.9
*/
decelerationRate: PropTypes.number,
/**
* When true, the scroll view's children are arranged horizontally in a row
* instead of vertically in a column. The default value is false.
*/
horizontal: PropTypes.bool,
/**
* When true, the ScrollView will try to lock to only vertical or horizontal
* scrolling while dragging. The default value is false.
*/
directionalLockEnabled: PropTypes.bool,
/**
* When false, once tracking starts, won't try to drag if the touch moves.
* The default value is true.
*/
canCancelContentTouches: PropTypes.bool,
/**
* Determines whether the keyboard gets dismissed in response to a drag.
* - 'none' (the default), drags do not dismiss the keyboard.
* - 'onDrag', the keyboard is dismissed when a drag begins.
* - 'interactive', the keyboard is dismissed interactively with the drag
* and moves in synchrony with the touch; dragging upwards cancels the
* dismissal.
*/
keyboardDismissMode: PropTypes.oneOf([
'none', // default
'interactive',
'onDrag',
]),
/**
* When false, tapping outside of the focused text input when the keyboard
* is up dismisses the keyboard. When true, the scroll view will not catch
* taps, and the keyboard will not dismiss automatically. The default value
* is false.
*/
keyboardShouldPersistTaps: PropTypes.bool,
/**
* The maximum allowed zoom scale. The default value is 1.0.
*/
maximumZoomScale: PropTypes.number,
/**
* The minimum allowed zoom scale. The default value is 1.0.
*/
minimumZoomScale: PropTypes.number,
/**
* When true, the scroll view stops on multiples of the scroll view's size
* when scrolling. This can be used for horizontal pagination. The default
* value is false.
*/
pagingEnabled: PropTypes.bool,
/**
* When true, the scroll view scrolls to top when the status bar is tapped.
* The default value is true.
*/
scrollsToTop: PropTypes.bool,
/**
* An array of child indices determining which children get docked to the
* top of the screen when scrolling. For example, passing
* `stickyHeaderIndices={[0]}` will cause the first child to be fixed to the
* top of the scroll view. This property is not supported in conjunction
* with `horizontal={true}`.
*/
stickyHeaderIndices: PropTypes.arrayOf(PropTypes.number),
/**
* Experimental: When true, offscreen child views (whose `overflow` value is
* `hidden`) are removed from their native backing superview when offscreen.
* This can improve scrolling performance on long lists. The default value is
* false.
*/
removeClippedSubviews: PropTypes.bool,
/**
* The current scale of the scroll view content. The default value is 1.0.
*/
zoomScale: PropTypes.number,
},
mixins: [ScrollResponder.Mixin],
getInitialState: function() {
return this.scrollResponderMixinGetInitialState();
},
setNativeProps: function(props ) {
this.refs[SCROLLVIEW].setNativeProps(props);
},
getInnerViewNode: function() {
return this.refs[INNERVIEW].getNodeHandle();
},
scrollTo: function(destY , destX ) {
if (Platform.OS === 'android') {
RCTUIManager.dispatchViewManagerCommand(
this.getNodeHandle(),
RCTUIManager.RCTScrollView.Commands.scrollTo,
[destX || 0, destY || 0]
);
} else {
RCTUIManager.scrollTo(
this.getNodeHandle(),
destX || 0,
destY || 0
);
}
},
scrollWithoutAnimationTo: function(destY , destX ) {
RCTUIManager.scrollWithoutAnimationTo(
this.getNodeHandle(),
destX || 0,
destY || 0
);
},
render: function() {
var contentContainerStyle = [
this.props.horizontal && styles.contentContainerHorizontal,
this.props.contentContainerStyle,
];
if (__DEV__ && this.props.style) {
var style = flattenStyle(this.props.style);
var childLayoutProps = ['alignItems', 'justifyContent']
.filter(function(prop) {return style && style[prop] !== undefined;});
invariant(
childLayoutProps.length === 0,
'ScrollView child layout (' + JSON.stringify(childLayoutProps) +
') must by applied through the contentContainerStyle prop.'
);
}
if (__DEV__) {
if (this.props.onScroll && !this.props.scrollEventThrottle) {
var onScroll = this.props.onScroll;
this.props.onScroll = function() {
console.log(
'You specified `onScroll` on a <ScrollView> but not ' +
'`scrollEventThrottle`. You will only receive one event. ' +
'Using `16` you get all the events but be aware that it may ' +
'cause frame drops, use a bigger number if you don\'t need as ' +
'much precision.'
);
onScroll.apply(this, arguments);
};
}
}
var contentContainer =
React.createElement(View, {
ref: INNERVIEW,
style: contentContainerStyle,
removeClippedSubviews: this.props.removeClippedSubviews},
this.props.children
);
var alwaysBounceHorizontal =
this.props.alwaysBounceHorizontal !== undefined ?
this.props.alwaysBounceHorizontal :
this.props.horizontal;
var alwaysBounceVertical =
this.props.alwaysBounceVertical !== undefined ?
this.props.alwaysBounceVertical :
!this.props.horizontal;
var props = Object.assign({},
this.props,
{alwaysBounceHorizontal:alwaysBounceHorizontal,
alwaysBounceVertical:alwaysBounceVertical,
keyboardDismissMode: this.props.keyboardDismissMode ?
keyboardDismissModeConstants[this.props.keyboardDismissMode] :
undefined,
style: ([styles.base, this.props.style] ),
onTouchStart: this.scrollResponderHandleTouchStart,
onTouchMove: this.scrollResponderHandleTouchMove,
onTouchEnd: this.scrollResponderHandleTouchEnd,
onScrollBeginDrag: this.scrollResponderHandleScrollBeginDrag,
onScrollEndDrag: this.scrollResponderHandleScrollEndDrag,
onMomentumScrollBegin: this.scrollResponderHandleMomentumScrollBegin,
onMomentumScrollEnd: this.scrollResponderHandleMomentumScrollEnd,
onStartShouldSetResponder: this.scrollResponderHandleStartShouldSetResponder,
onStartShouldSetResponderCapture: this.scrollResponderHandleStartShouldSetResponderCapture,
onScrollShouldSetResponder: this.scrollResponderHandleScrollShouldSetResponder,
onScroll: this.scrollResponderHandleScroll,
onResponderGrant: this.scrollResponderHandleResponderGrant,
onResponderTerminationRequest: this.scrollResponderHandleTerminationRequest,
onResponderTerminate: this.scrollResponderHandleTerminate,
onResponderRelease: this.scrollResponderHandleResponderRelease,
onResponderReject: this.scrollResponderHandleResponderReject
});
var ScrollViewClass;
if (Platform.OS === 'ios') {
ScrollViewClass = RCTScrollView;
} else if (Platform.OS === 'android') {
if (this.props.horizontal) {
ScrollViewClass = AndroidHorizontalScrollView;
} else {
ScrollViewClass = AndroidScrollView;
}
}
invariant(
ScrollViewClass !== undefined,
'ScrollViewClass must not be undefined'
);
return (
React.createElement(ScrollViewClass, React.__spread({}, props, {ref: SCROLLVIEW}),
contentContainer
)
);
}
});
var styles = StyleSheet.create({
base: {
flex: 1,
},
contentContainerHorizontal: {
alignSelf: 'flex-start',
flexDirection: 'row',
},
});
var validAttributes = Object.assign({},
ReactIOSViewAttributes.UIView,
{alwaysBounceHorizontal: true,
alwaysBounceVertical: true,
automaticallyAdjustContentInsets: true,
bounces: true,
centerContent: true,
contentInset: {diff: insetsDiffer},
contentOffset: {diff: pointsDiffer},
decelerationRate: true,
horizontal: true,
keyboardDismissMode: true,
keyboardShouldPersistTaps: true,
maximumZoomScale: true,
minimumZoomScale: true,
pagingEnabled: true,
removeClippedSubviews: true,
scrollEnabled: true,
scrollIndicatorInsets: {diff: insetsDiffer},
scrollsToTop: true,
showsHorizontalScrollIndicator: true,
showsVerticalScrollIndicator: true,
stickyHeaderIndices: {diff: deepDiffer},
scrollEventThrottle: true,
zoomScale: true
});
if (Platform.OS === 'android') {
var AndroidScrollView = createReactIOSNativeComponentClass({
validAttributes: validAttributes,
uiViewClassName: 'RCTScrollView',
});
var AndroidHorizontalScrollView = createReactIOSNativeComponentClass({
validAttributes: validAttributes,
uiViewClassName: 'AndroidHorizontalScrollView',
});
} else if (Platform.OS === 'ios') {
var RCTScrollView = requireNativeComponent('RCTScrollView', ScrollView);
}
module.exports = ScrollView;
});
__d('PointPropType',["ReactPropTypes","createStrictShapeTypeChecker","pointsDiffer"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 PointPropType
* @flow
*/
'use strict'
var PropTypes = require('ReactPropTypes');
var createStrictShapeTypeChecker = require('createStrictShapeTypeChecker');
var pointsDiffer = require('pointsDiffer');
var PointPropType = createStrictShapeTypeChecker({
x: PropTypes.number,
y: PropTypes.number,
});
module.exports = PointPropType;
});
__d('ScrollResponder',["NativeModules","RCTDeviceEventEmitter","Subscribable","TextInputState","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 ScrollResponder
* @flow
*/
'use strict';
var NativeModules = require('NativeModules');
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
var Subscribable = require('Subscribable');
var TextInputState = require('TextInputState');
var RCTUIManager = NativeModules.UIManager;
var RCTUIManagerDeprecated = NativeModules.UIManager;
var RCTScrollViewConsts = RCTUIManager.RCTScrollView.Constants;
var warning = require('warning');
/**
* Mixin that can be integrated in order to handle scrolling that plays well
* with `ResponderEventPlugin`. Integrate with your platform specific scroll
* views, or even your custom built (every-frame animating) scroll views so that
* all of these systems play well with the `ResponderEventPlugin`.
*
* iOS scroll event timing nuances:
* ===============================
*
*
* Scrolling without bouncing, if you touch down:
* -------------------------------
*
* 1. `onMomentumScrollBegin` (when animation begins after letting up)
* ... physical touch starts ...
* 2. `onTouchStartCapture` (when you press down to stop the scroll)
* 3. `onTouchStart` (same, but bubble phase)
* 4. `onResponderRelease` (when lifting up - you could pause forever before * lifting)
* 5. `onMomentumScrollEnd`
*
*
* Scrolling with bouncing, if you touch down:
* -------------------------------
*
* 1. `onMomentumScrollBegin` (when animation begins after letting up)
* ... bounce begins ...
* ... some time elapses ...
* ... physical touch during bounce ...
* 2. `onMomentumScrollEnd` (Makes no sense why this occurs first during bounce)
* 3. `onTouchStartCapture` (immediately after `onMomentumScrollEnd`)
* 4. `onTouchStart` (same, but bubble phase)
* 5. `onTouchEnd` (You could hold the touch start for a long time)
* 6. `onMomentumScrollBegin` (When releasing the view starts bouncing back)
*
* So when we receive an `onTouchStart`, how can we tell if we are touching
* *during* an animation (which then causes the animation to stop)? The only way
* to tell is if the `touchStart` occurred immediately after the
* `onMomentumScrollEnd`.
*
* This is abstracted out for you, so you can just call this.scrollResponderIsAnimating() if
* necessary
*
* `ScrollResponder` also includes logic for blurring a currently focused input
* if one is focused while scrolling. The `ScrollResponder` is a natural place
* to put this logic since it can support not dismissing the keyboard while
* scrolling, unless a recognized "tap"-like gesture has occurred.
*
* The public lifecycle API includes events for keyboard interaction, responder
* interaction, and scrolling (among others). The keyboard callbacks
* `onKeyboardWill/Did/*` are *global* events, but are invoked on scroll
* responder's props so that you can guarantee that the scroll responder's
* internal state has been updated accordingly (and deterministically) by
* the time the props callbacks are invoke. Otherwise, you would always wonder
* if the scroll responder is currently in a state where it recognizes new
* keyboard positions etc. If coordinating scrolling with keyboard movement,
* *always* use these hooks instead of listening to your own global keyboard
* events.
*
* Public keyboard lifecycle API: (props callbacks)
*
* Standard Keyboard Appearance Sequence:
*
* this.props.onKeyboardWillShow
* this.props.onKeyboardDidShow
*
* `onScrollResponderKeyboardDismissed` will be invoked if an appropriate
* tap inside the scroll responder's scrollable region was responsible
* for the dismissal of the keyboard. There are other reasons why the
* keyboard could be dismissed.
*
* this.props.onScrollResponderKeyboardDismissed
*
* Standard Keyboard Hide Sequence:
*
* this.props.onKeyboardWillHide
* this.props.onKeyboardDidHide
*/
var IS_ANIMATING_TOUCH_START_THRESHOLD_MS = 16;
var ScrollResponderMixin = {
mixins: [Subscribable.Mixin],
statics: RCTScrollViewConsts,
scrollResponderMixinGetInitialState: function() {
return {
isTouching: false,
lastMomentumScrollBeginTime: 0,
lastMomentumScrollEndTime: 0,
// Reset to false every time becomes responder. This is used to:
// - Determine if the scroll view has been scrolled and therefore should
// refuse to give up its responder lock.
// - Determine if releasing should dismiss the keyboard when we are in
// tap-to-dismiss mode (!this.props.keyboardShouldPersistTaps).
observedScrollSinceBecomingResponder: false,
becameResponderWhileAnimating: false,
};
},
/**
* Invoke this from an `onScroll` event.
*/
scrollResponderHandleScrollShouldSetResponder: function() {
return this.state.isTouching;
},
/**
* Merely touch starting is not sufficient for a scroll view to become the
* responder. Being the "responder" means that the very next touch move/end
* event will result in an action/movement.
*
* Invoke this from an `onStartShouldSetResponder` event.
*
* `onStartShouldSetResponder` is used when the next move/end will trigger
* some UI movement/action, but when you want to yield priority to views
* nested inside of the view.
*
* There may be some cases where scroll views actually should return `true`
* from `onStartShouldSetResponder`: Any time we are detecting a standard tap
* that gives priority to nested views.
*
* - If a single tap on the scroll view triggers an action such as
* recentering a map style view yet wants to give priority to interaction
* views inside (such as dropped pins or labels), then we would return true
* from this method when there is a single touch.
*
* - Similar to the previous case, if a two finger "tap" should trigger a
* zoom, we would check the `touches` count, and if `>= 2`, we would return
* true.
*
*/
scrollResponderHandleStartShouldSetResponder: function() {
return false;
},
/**
* There are times when the scroll view wants to become the responder
* (meaning respond to the next immediate `touchStart/touchEnd`), in a way
* that *doesn't* give priority to nested views (hence the capture phase):
*
* - Currently animating.
* - Tapping anywhere that is not the focused input, while the keyboard is
* up (which should dismiss the keyboard).
*
* Invoke this from an `onStartShouldSetResponderCapture` event.
*/
scrollResponderHandleStartShouldSetResponderCapture: function(e ) {
// First see if we want to eat taps while the keyboard is up
var currentlyFocusedTextInput = TextInputState.currentlyFocusedField();
if (!this.props.keyboardShouldPersistTaps &&
currentlyFocusedTextInput != null &&
e.target != currentlyFocusedTextInput) {
return true;
}
return this.scrollResponderIsAnimating();
},
/**
* Invoke this from an `onResponderReject` event.
*
* Some other element is not yielding its role as responder. Normally, we'd
* just disable the `UIScrollView`, but a touch has already began on it, the
* `UIScrollView` will not accept being disabled after that. The easiest
* solution for now is to accept the limitation of disallowing this
* altogether. To improve this, find a way to disable the `UIScrollView` after
* a touch has already started.
*/
scrollResponderHandleResponderReject: function() {
warning(false, "ScrollView doesn't take rejection well - scrolls anyway");
},
/**
* We will allow the scroll view to give up its lock iff it acquired the lock
* during an animation. This is a very useful default that happens to satisfy
* many common user experiences.
*
* - Stop a scroll on the left edge, then turn that into an outer view's
* backswipe.
* - Stop a scroll mid-bounce at the top, continue pulling to have the outer
* view dismiss.
* - However, without catching the scroll view mid-bounce (while it is
* motionless), if you drag far enough for the scroll view to become
* responder (and therefore drag the scroll view a bit), any backswipe
* navigation of a swipe gesture higher in the view hierarchy, should be
* rejected.
*/
scrollResponderHandleTerminationRequest: function() {
return !this.state.observedScrollSinceBecomingResponder;
},
/**
* Invoke this from an `onTouchEnd` event.
*
* @param {SyntheticEvent} e Event.
*/
scrollResponderHandleTouchEnd: function(e ) {
var nativeEvent = e.nativeEvent;
this.state.isTouching = nativeEvent.touches.length !== 0;
this.props.onTouchEnd && this.props.onTouchEnd(e);
},
/**
* Invoke this from an `onResponderRelease` event.
*/
scrollResponderHandleResponderRelease: function(e ) {
this.props.onResponderRelease && this.props.onResponderRelease(e);
// By default scroll views will unfocus a textField
// if another touch occurs outside of it
var currentlyFocusedTextInput = TextInputState.currentlyFocusedField();
if (!this.props.keyboardShouldPersistTaps &&
currentlyFocusedTextInput != null &&
e.target != currentlyFocusedTextInput &&
!this.state.observedScrollSinceBecomingResponder &&
!this.state.becameResponderWhileAnimating) {
this.props.onScrollResponderKeyboardDismissed &&
this.props.onScrollResponderKeyboardDismissed(e);
TextInputState.blurTextInput(currentlyFocusedTextInput);
}
},
scrollResponderHandleScroll: function(e ) {
this.state.observedScrollSinceBecomingResponder = true;
this.props.onScroll && this.props.onScroll(e);
},
/**
* Invoke this from an `onResponderGrant` event.
*/
scrollResponderHandleResponderGrant: function(e ) {
this.state.observedScrollSinceBecomingResponder = false;
this.props.onResponderGrant && this.props.onResponderGrant(e);
this.state.becameResponderWhileAnimating = this.scrollResponderIsAnimating();
},
/**
* Unfortunately, `onScrollBeginDrag` also fires when *stopping* the scroll
* animation, and there's not an easy way to distinguish a drag vs. stopping
* momentum.
*
* Invoke this from an `onScrollBeginDrag` event.
*/
scrollResponderHandleScrollBeginDrag: function(e ) {
this.props.onScrollBeginDrag && this.props.onScrollBeginDrag(e);
},
/**
* Invoke this from an `onScrollEndDrag` event.
*/
scrollResponderHandleScrollEndDrag: function(e ) {
this.props.onScrollEndDrag && this.props.onScrollEndDrag(e);
},
/**
* Invoke this from an `onMomentumScrollBegin` event.
*/
scrollResponderHandleMomentumScrollBegin: function(e ) {
this.state.lastMomentumScrollBeginTime = Date.now();
this.props.onMomentumScrollBegin && this.props.onMomentumScrollBegin(e);
},
/**
* Invoke this from an `onMomentumScrollEnd` event.
*/
scrollResponderHandleMomentumScrollEnd: function(e ) {
this.state.lastMomentumScrollEndTime = Date.now();
this.props.onMomentumScrollEnd && this.props.onMomentumScrollEnd(e);
},
/**
* Invoke this from an `onTouchStart` event.
*
* Since we know that the `SimpleEventPlugin` occurs later in the plugin
* order, after `ResponderEventPlugin`, we can detect that we were *not*
* permitted to be the responder (presumably because a contained view became
* responder). The `onResponderReject` won't fire in that case - it only
* fires when a *current* responder rejects our request.
*
* @param {SyntheticEvent} e Touch Start event.
*/
scrollResponderHandleTouchStart: function(e ) {
this.state.isTouching = true;
this.props.onTouchStart && this.props.onTouchStart(e);
},
/**
* Invoke this from an `onTouchMove` event.
*
* Since we know that the `SimpleEventPlugin` occurs later in the plugin
* order, after `ResponderEventPlugin`, we can detect that we were *not*
* permitted to be the responder (presumably because a contained view became
* responder). The `onResponderReject` won't fire in that case - it only
* fires when a *current* responder rejects our request.
*
* @param {SyntheticEvent} e Touch Start event.
*/
scrollResponderHandleTouchMove: function(e ) {
this.props.onTouchMove && this.props.onTouchMove(e);
},
/**
* A helper function for this class that lets us quickly determine if the
* view is currently animating. This is particularly useful to know when
* a touch has just started or ended.
*/
scrollResponderIsAnimating: function() {
var now = Date.now();
var timeSinceLastMomentumScrollEnd = now - this.state.lastMomentumScrollEndTime;
var isAnimating = timeSinceLastMomentumScrollEnd < IS_ANIMATING_TOUCH_START_THRESHOLD_MS ||
this.state.lastMomentumScrollEndTime < this.state.lastMomentumScrollBeginTime;
return isAnimating;
},
/**
* A helper function to scroll to a specific point in the scrollview.
* This is currently used to help focus on child textview's, but this
* can also be used to quickly scroll to any element we want to focus
*/
scrollResponderScrollTo: function(offsetX , offsetY ) {
RCTUIManagerDeprecated.scrollTo(this.getNodeHandle(), offsetX, offsetY);
},
/**
* A helper function to zoom to a specific rect in the scrollview.
* @param {object} rect Should have shape {x, y, width, height}
*/
scrollResponderZoomTo: function(rect ) {
RCTUIManagerDeprecated.zoomToRect(this.getNodeHandle(), rect);
},
/**
* This method should be used as the callback to onFocus in a TextInputs'
* parent view. Note that any module using this mixin needs to return
* the parent view's ref in getScrollViewRef() in order to use this method.
* @param {any} nodeHandle The TextInput node handle
* @param {number} additionalOffset The scroll view's top "contentInset".
* Default is 0.
* @param {bool} preventNegativeScrolling Whether to allow pulling the content
* down to make it meet the keyboard's top. Default is false.
*/
scrollResponderScrollNativeHandleToKeyboard: function(nodeHandle , additionalOffset , preventNegativeScrollOffset ) {
this.additionalScrollOffset = additionalOffset || 0;
this.preventNegativeScrollOffset = !!preventNegativeScrollOffset;
RCTUIManager.measureLayout(
nodeHandle,
this.getNodeHandle(),
this.scrollResponderTextInputFocusError,
this.scrollResponderInputMeasureAndScrollToKeyboard
);
},
/**
* The calculations performed here assume the scroll view takes up the entire
* screen - even if has some content inset. We then measure the offsets of the
* keyboard, and compensate both for the scroll view's "contentInset".
*
* @param {number} left Position of input w.r.t. table view.
* @param {number} top Position of input w.r.t. table view.
* @param {number} width Width of the text input.
* @param {number} height Height of the text input.
*/
scrollResponderInputMeasureAndScrollToKeyboard: function(left , top , width , height ) {
if (this.keyboardWillOpenTo) {
var scrollOffsetY =
top - this.keyboardWillOpenTo.endCoordinates.screenY + height +
this.additionalScrollOffset;
// By default, this can scroll with negative offset, pulling the content
// down so that the target component's bottom meets the keyboard's top.
// If requested otherwise, cap the offset at 0 minimum to avoid content
// shifting down.
if (this.preventNegativeScrollOffset) {
scrollOffsetY = Math.max(0, scrollOffsetY);
}
this.scrollResponderScrollTo(0, scrollOffsetY);
}
this.additionalOffset = 0;
this.preventNegativeScrollOffset = false;
},
scrollResponderTextInputFocusError: function(e ) {
console.error('Error measuring text field: ', e);
},
/**
* `componentWillMount` is the closest thing to a standard "constructor" for
* React components.
*
* The `keyboardWillShow` is called before input focus.
*/
componentWillMount: function() {
this.keyboardWillOpenTo = null;
this.additionalScrollOffset = 0;
this.addListenerOn(RCTDeviceEventEmitter, 'keyboardWillShow', this.scrollResponderKeyboardWillShow);
this.addListenerOn(RCTDeviceEventEmitter, 'keyboardWillHide', this.scrollResponderKeyboardWillHide);
this.addListenerOn(RCTDeviceEventEmitter, 'keyboardDidShow', this.scrollResponderKeyboardDidShow);
this.addListenerOn(RCTDeviceEventEmitter, 'keyboardDidHide', this.scrollResponderKeyboardDidHide);
},
/**
* Warning, this may be called several times for a single keyboard opening.
* It's best to store the information in this method and then take any action
* at a later point (either in `keyboardDidShow` or other).
*
* Here's the order that events occur in:
* - focus
* - willShow {startCoordinates, endCoordinates} several times
* - didShow several times
* - blur
* - willHide {startCoordinates, endCoordinates} several times
* - didHide several times
*
* The `ScrollResponder` providesModule callbacks for each of these events.
* Even though any user could have easily listened to keyboard events
* themselves, using these `props` callbacks ensures that ordering of events
* is consistent - and not dependent on the order that the keyboard events are
* subscribed to. This matters when telling the scroll view to scroll to where
* the keyboard is headed - the scroll responder better have been notified of
* the keyboard destination before being instructed to scroll to where the
* keyboard will be. Stick to the `ScrollResponder` callbacks, and everything
* will work.
*
* WARNING: These callbacks will fire even if a keyboard is displayed in a
* different navigation pane. Filter out the events to determine if they are
* relevant to you. (For example, only if you receive these callbacks after
* you had explicitly focused a node etc).
*/
scrollResponderKeyboardWillShow: function(e ) {
this.keyboardWillOpenTo = e;
this.props.onKeyboardWillShow && this.props.onKeyboardWillShow(e);
},
scrollResponderKeyboardWillHide: function(e ) {
this.keyboardWillOpenTo = null;
this.props.onKeyboardWillHide && this.props.onKeyboardWillHide(e);
},
scrollResponderKeyboardDidShow: function() {
this.keyboardWillOpenTo = null;
this.props.onKeyboardDidShow && this.props.onKeyboardDidShow();
},
scrollResponderKeyboardDidHide: function() {
this.keyboardWillOpenTo = null;
this.props.onKeyboardDidHide && this.props.onKeyboardDidHide();
}
};
var ScrollResponder = {
Mixin: ScrollResponderMixin,
};
module.exports = ScrollResponder;
});
__d('Subscribable',["EventEmitter"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 Subscribable
* @flow
*/
'use strict';
var EventEmitter = require('EventEmitter');
/**
* Subscribable provides a mixin for safely subscribing a component to an
* eventEmitter
*
* This will be replaced with the observe interface that will be coming soon to
* React Core
*/
var Subscribable = {};
Subscribable.Mixin = {
componentWillMount: function() {
this._subscribableSubscriptions = [];
},
componentWillUnmount: function() {
this._subscribableSubscriptions.forEach(
function(subscription) {return subscription.remove();}
);
this._subscribableSubscriptions = null;
},
/**
* Special form of calling `addListener` that *guarantees* that a
* subscription *must* be tied to a component instance, and therefore will
* be cleaned up when the component is unmounted. It is impossible to create
* the subscription and pass it in - this method must be the one to create
* the subscription and therefore can guarantee it is retained in a way that
* will be cleaned up.
*
* @param {EventEmitter} eventEmitter emitter to subscribe to.
* @param {string} eventType Type of event to listen to.
* @param {function} listener Function to invoke when event occurs.
* @param {object} context Object to use as listener context.
*/
addListenerOn: function(
eventEmitter ,
eventType ,
listener ,
context
) {
this._subscribableSubscriptions.push(
eventEmitter.addListener(eventType, listener, context)
);
}
};
module.exports = Subscribable;
});
__d('StaticRenderer',["React"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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.
*
* @provides StaticRenderer
* @flow
*/
'use strict';
var React = require('React');
var StaticRenderer = React.createClass({displayName: "StaticRenderer",
propTypes: {
shouldUpdate: React.PropTypes.bool.isRequired,
render: React.PropTypes.func.isRequired,
},
shouldComponentUpdate: function(nextProps ) {
return nextProps.shouldUpdate;
},
render: function() {
return this.props.render();
},
});
module.exports = StaticRenderer;
});
__d('react-timer-mixin/TimerMixin',[],function(global, require, requireDynamic, requireLazy, module, exports) { /*
* Copyright (c) 2015-present, 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.
*
*/
'use strict';
var setter = function(_setter, _clearer, array) {
return function(callback, delta) {
var id = _setter(function() {
_clearer.call(this, id);
callback.apply(this, arguments);
}.bind(this), delta);
if (!this[array]) {
this[array] = [id];
} else {
this[array].push(id);
}
return id;
};
};
var clearer = function(_clearer, array) {
return function(id) {
if (this[array]) {
var index = this[array].indexOf(id);
if (index !== -1) {
this[array].splice(index, 1);
}
}
_clearer(id);
};
};
var _timeouts = 'TimerMixin_timeouts';
var _clearTimeout = clearer(clearTimeout, _timeouts);
var _setTimeout = setter(setTimeout, _clearTimeout, _timeouts);
var _intervals = 'TimerMixin_intervals';
var _clearInterval = clearer(clearInterval, _intervals);
var _setInterval = setter(setInterval, function() {/* noop */}, _intervals);
var _immediates = 'TimerMixin_immediates';
var _clearImmediate = clearer(clearImmediate, _immediates);
var _setImmediate = setter(setImmediate, _clearImmediate, _immediates);
var _rafs = 'TimerMixin_rafs';
var _cancelAnimationFrame = clearer(cancelAnimationFrame, _rafs);
var _requestAnimationFrame = setter(requestAnimationFrame, _cancelAnimationFrame, _rafs);
var TimerMixin = {
componentWillUnmount: function() {
this[_timeouts] && this[_timeouts].forEach(this.clearTimeout);
this[_intervals] && this[_intervals].forEach(this.clearInterval);
this[_immediates] && this[_immediates].forEach(this.clearImmediate);
this[_rafs] && this[_rafs].forEach(this.cancelAnimationFrame);
},
setTimeout: _setTimeout,
clearTimeout: _clearTimeout,
setInterval: _setInterval,
clearInterval: _clearInterval,
setImmediate: _setImmediate,
clearImmediate: _clearImmediate,
requestAnimationFrame: _requestAnimationFrame,
cancelAnimationFrame: _cancelAnimationFrame,
};
module.exports = TimerMixin;
});
__d('MapView',["EdgeInsetsPropType","NativeMethodsMixin","Platform","React","ReactIOSViewAttributes","View","createReactIOSNativeComponentClass","deepDiffer","insetsDiffer","merge","requireNativeComponent"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 MapView
* @flow
*/
'use strict';
var EdgeInsetsPropType = require('EdgeInsetsPropType');
var NativeMethodsMixin = require('NativeMethodsMixin');
var Platform = require('Platform');
var React = require('React');
var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
var View = require('View');
var createReactIOSNativeComponentClass = require('createReactIOSNativeComponentClass');
var deepDiffer = require('deepDiffer');
var insetsDiffer = require('insetsDiffer');
var merge = require('merge');
var requireNativeComponent = require('requireNativeComponent');
var MapView = React.createClass({displayName: "MapView",
mixins: [NativeMethodsMixin],
propTypes: {
/**
* Used to style and layout the `MapView`. See `StyleSheet.js` and
* `ViewStylePropTypes.js` for more info.
*/
style: View.propTypes.style,
/**
* If `true` the app will ask for the user's location and focus on it.
* Default value is `false`.
*
* **NOTE**: You need to add NSLocationWhenInUseUsageDescription key in
* Info.plist to enable geolocation, otherwise it is going
* to *fail silently*!
*/
showsUserLocation: React.PropTypes.bool,
/**
* If `false` the user won't be able to pinch/zoom the map.
* Default `value` is true.
*/
zoomEnabled: React.PropTypes.bool,
/**
* When this property is set to `true` and a valid camera is associated with
* the map, the camera’s heading angle is used to rotate the plane of the
* map around its center point. When this property is set to `false`, the
* camera’s heading angle is ignored and the map is always oriented so
* that true north is situated at the top of the map view
*/
rotateEnabled: React.PropTypes.bool,
/**
* When this property is set to `true` and a valid camera is associated
* with the map, the camera’s pitch angle is used to tilt the plane
* of the map. When this property is set to `false`, the camera’s pitch
* angle is ignored and the map is always displayed as if the user
* is looking straight down onto it.
*/
pitchEnabled: React.PropTypes.bool,
/**
* If `false` the user won't be able to change the map region being displayed.
* Default value is `true`.
*/
scrollEnabled: React.PropTypes.bool,
/**
* The region to be displayed by the map.
*
* The region is defined by the center coordinates and the span of
* coordinates to display.
*/
region: React.PropTypes.shape({
/**
* Coordinates for the center of the map.
*/
latitude: React.PropTypes.number.isRequired,
longitude: React.PropTypes.number.isRequired,
/**
* Distance between the minimun and the maximum latitude/longitude
* to be displayed.
*/
latitudeDelta: React.PropTypes.number.isRequired,
longitudeDelta: React.PropTypes.number.isRequired,
}),
/**
* Map annotations with title/subtitle.
*/
annotations: React.PropTypes.arrayOf(React.PropTypes.shape({
/**
* The location of the annotation.
*/
latitude: React.PropTypes.number.isRequired,
longitude: React.PropTypes.number.isRequired,
/**
* Annotation title/subtile.
*/
title: React.PropTypes.string,
subtitle: React.PropTypes.string,
})),
/**
* Maximum size of area that can be displayed.
*/
maxDelta: React.PropTypes.number,
/**
* Minimum size of area that can be displayed.
*/
minDelta: React.PropTypes.number,
/**
* Insets for the map's legal label, originally at bottom left of the map.
* See `EdgeInsetsPropType.js` for more information.
*/
legalLabelInsets: EdgeInsetsPropType,
/**
* Callback that is called continuously when the user is dragging the map.
*/
onRegionChange: React.PropTypes.func,
/**
* Callback that is called once, when the user is done moving the map.
*/
onRegionChangeComplete: React.PropTypes.func,
},
_onChange: function(event ) {
if (event.nativeEvent.continuous) {
this.props.onRegionChange &&
this.props.onRegionChange(event.nativeEvent.region);
} else {
this.props.onRegionChangeComplete &&
this.props.onRegionChangeComplete(event.nativeEvent.region);
}
},
render: function() {
return React.createElement(RCTMap, React.__spread({}, this.props, {onChange: this._onChange}));
},
});
if (Platform.OS === 'android') {
var RCTMap = createReactIOSNativeComponentClass({
validAttributes: merge(
ReactIOSViewAttributes.UIView, {
showsUserLocation: true,
zoomEnabled: true,
rotateEnabled: true,
pitchEnabled: true,
scrollEnabled: true,
region: {diff: deepDiffer},
annotations: {diff: deepDiffer},
maxDelta: true,
minDelta: true,
legalLabelInsets: {diff: insetsDiffer},
}
),
uiViewClassName: 'RCTMap',
});
} else {
var RCTMap = requireNativeComponent('RCTMap', MapView);
}
module.exports = MapView;
});
__d('NavigatorIOS',["EventEmitter","Image","React","ReactIOSViewAttributes","NativeModules","StyleSheet","StaticContainer.react","View","createReactIOSNativeComponentClass","invariant","logError","merge"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 NavigatorIOS
* @flow
*/
'use strict';
var EventEmitter = require('EventEmitter');
var Image = require('Image');
var React = require('React');
var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
var RCTNavigatorManager = require('NativeModules').NavigatorManager;
var StyleSheet = require('StyleSheet');
var StaticContainer = require('StaticContainer.react');
var View = require('View');
var createReactIOSNativeComponentClass =
require('createReactIOSNativeComponentClass');
var invariant = require('invariant');
var logError = require('logError');
var merge = require('merge');
var TRANSITIONER_REF = 'transitionerRef';
var PropTypes = React.PropTypes;
var __uid = 0;
function getuid() {
return __uid++;
}
var RCTNavigator = createReactIOSNativeComponentClass({
validAttributes: merge(ReactIOSViewAttributes.UIView, {
requestedTopOfStack: true
}),
uiViewClassName: 'RCTNavigator',
});
var RCTNavigatorItem = createReactIOSNativeComponentClass({
validAttributes: {
// TODO: Remove or fix the attributes that are not fully functional.
// NavigatorIOS does not use them all, because some are problematic
title: true,
barTintColor: true,
leftButtonIcon: true,
leftButtonTitle: true,
onNavLeftButtonTap: true,
rightButtonIcon: true,
rightButtonTitle: true,
onNavRightButtonTap: true,
backButtonIcon: true,
backButtonTitle: true,
tintColor: true,
navigationBarHidden: true,
titleTextColor: true,
style: true,
},
uiViewClassName: 'RCTNavItem',
});
var NavigatorTransitionerIOS = React.createClass({displayName: "NavigatorTransitionerIOS",
requestSchedulingNavigation: function(cb) {
RCTNavigatorManager.requestSchedulingJavaScriptNavigation(
(this ).getNodeHandle(),
logError,
cb
);
},
render: function() {
return (
React.createElement(RCTNavigator, React.__spread({}, this.props))
);
},
});
/**
* Think of `<NavigatorIOS>` as simply a component that renders an
* `RCTNavigator`, and moves the `RCTNavigator`'s `requestedTopOfStack` pointer
* forward and backward. The `RCTNavigator` interprets changes in
* `requestedTopOfStack` to be pushes and pops of children that are rendered.
* `<NavigatorIOS>` always ensures that whenever the `requestedTopOfStack`
* pointer is moved, that we've also rendered enough children so that the
* `RCTNavigator` can carry out the push/pop with those children.
* `<NavigatorIOS>` also removes children that will no longer be needed
* (after the pop of a child has been fully completed/animated out).
*/
/**
* NavigatorIOS wraps UIKit navigation and allows you to add back-swipe
* functionality across your app.
*
* #### Routes
* A route is an object used to describe each page in the navigator. The first
* route is provided to NavigatorIOS as `initialRoute`:
*
* ```
* render: function() {
* return (
* <NavigatorIOS
* initialRoute={{
* component: MyView,
* title: 'My View Title',
* passProps: { myProp: 'foo' },
* }}
* />
* );
* },
* ```
*
* Now MyView will be rendered by the navigator. It will recieve the route
* object in the `route` prop, a navigator, and all of the props specified in
* `passProps`.
*
* See the initialRoute propType for a complete definition of a route.
*
* #### Navigator
*
* A `navigator` is an object of navigation functions that a view can call. It
* is passed as a prop to any component rendered by NavigatorIOS.
*
* ```
* var MyView = React.createClass({
* _handleBackButtonPress: function() {
* this.props.navigator.pop();
* },
* _handleNextButtonPress: function() {
* this.props.navigator.push(nextRoute);
* },
* ...
* });
* ```
*
* A navigation object contains the following functions:
*
* - `push(route)` - Navigate forward to a new route
* - `pop()` - Go back one page
* - `popN(n)` - Go back N pages at once. When N=1, behavior matches `pop()`
* - `replace(route)` - Replace the route for the current page and immediately
* load the view for the new route
* - `replacePrevious(route)` - Replace the route/view for the previous page
* - `replacePreviousAndPop(route)` - Replaces the previous route/view and
* transitions back to it
* - `resetTo(route)` - Replaces the top item and popToTop
* - `popToRoute(route)` - Go back to the item for a particular route object
* - `popToTop()` - Go back to the top item
*
* Navigator functions are also available on the NavigatorIOS component:
*
* ```
* var MyView = React.createClass({
* _handleNavigationRequest: function() {
* this.refs.nav.push(otherRoute);
* },
* render: () => (
* <NavigatorIOS
* ref="nav"
* initialRoute={...}
* />
* ),
* });
* ```
*
*/
var NavigatorIOS = React.createClass({displayName: "NavigatorIOS",
propTypes: {
/**
* NavigatorIOS uses "route" objects to identify child views, their props,
* and navigation bar configuration. "push" and all the other navigation
* operations expect routes to be like this:
*/
initialRoute: PropTypes.shape({
/**
* The React Class to render for this route
*/
component: PropTypes.func.isRequired,
/**
* The title displayed in the nav bar and back button for this route
*/
title: PropTypes.string.isRequired,
/**
* Specify additional props passed to the component. NavigatorIOS will
* automatically provide "route" and "navigator" components
*/
passProps: PropTypes.object,
/**
* If set, the left header button image will appear with this source. Note
* that this doesn't apply for the header of the current view, but the
* ones of the views that are pushed afterward.
*/
backButtonIcon: Image.propTypes.source,
/**
* If set, the left header button will appear with this name. Note that
* this doesn't apply for the header of the current view, but the ones
* of the views that are pushed afterward.
*/
backButtonTitle: PropTypes.string,
/**
* If set, the left header button image will appear with this source
*/
leftButtonIcon: Image.propTypes.source,
/**
* If set, the left header button will appear with this name
*/
leftButtonTitle: PropTypes.string,
/**
* Called when the left header button is pressed
*/
onLeftButtonPress: PropTypes.func,
/**
* If set, the right header button image will appear with this source
*/
rightButtonIcon: Image.propTypes.source,
/**
* If set, the right header button will appear with this name
*/
rightButtonTitle: PropTypes.string,
/**
* Called when the right header button is pressed
*/
onRightButtonPress: PropTypes.func,
/**
* Styles for the navigation item containing the component
*/
wrapperStyle: View.propTypes.style,
}).isRequired,
/**
* A Boolean value that indicates whether the navigation bar is hidden
*/
navigationBarHidden: PropTypes.bool,
/**
* The default wrapper style for components in the navigator.
* A common use case is to set the backgroundColor for every page
*/
itemWrapperStyle: View.propTypes.style,
/**
* The color used for buttons in the navigation bar
*/
tintColor: PropTypes.string,
/**
* The background color of the navigation bar
*/
barTintColor: PropTypes.string,
/**
* The text color of the navigation bar title
*/
titleTextColor: PropTypes.string,
},
navigator: (undefined ),
componentWillMount: function() {
// Precompute a pack of callbacks that's frequently generated and passed to
// instances.
this.navigator = {
push: this.push,
pop: this.pop,
popN: this.popN,
replace: this.replace,
replacePrevious: this.replacePrevious,
replacePreviousAndPop: this.replacePreviousAndPop,
resetTo: this.resetTo,
popToRoute: this.popToRoute,
popToTop: this.popToTop,
};
},
getInitialState: function() {
return {
idStack: [getuid()],
routeStack: [this.props.initialRoute],
// The navigation index that we wish to push/pop to.
requestedTopOfStack: 0,
// The last index that native has sent confirmation of completed push/pop
// for. At this point, we can discard any views that are beyond the
// `requestedTopOfStack`. A value of `null` means we have not received
// any confirmation, ever. We may receive an `observedTopOfStack` without
// ever requesting it - native can instigate pops of its own with the
// backswipe gesture.
observedTopOfStack: 0,
progress: 1,
fromIndex: 0,
toIndex: 0,
// Whether or not we are making a navigator request to push/pop. (Used
// for performance optimization).
makingNavigatorRequest: false,
// Whether or not we are updating children of navigator and if so (not
// `null`) which index marks the beginning of all updates. Used for
// performance optimization.
updatingAllIndicesAtOrBeyond: 0,
};
},
_toFocusOnNavigationComplete: (undefined ),
_handleFocusRequest: function(item ) {
if (this.state.makingNavigatorRequest) {
this._toFocusOnNavigationComplete = item;
} else {
this._getFocusEmitter().emit('focus', item);
}
},
_focusEmitter: (undefined ),
_getFocusEmitter: function() {
// Flow not yet tracking assignments to instance fields.
var focusEmitter = this._focusEmitter;
if (!focusEmitter) {
focusEmitter = new EventEmitter();
this._focusEmitter = focusEmitter;
}
return focusEmitter;
},
getChildContext: function()
{
return {
onFocusRequested: this._handleFocusRequest,
focusEmitter: this._getFocusEmitter(),
};
},
childContextTypes: {
onFocusRequested: React.PropTypes.func,
focusEmitter: React.PropTypes.instanceOf(EventEmitter),
},
_tryLockNavigator: function(cb ) {
this.refs[TRANSITIONER_REF].requestSchedulingNavigation(
function(acquiredLock) {return acquiredLock && cb();}
);
},
_handleNavigatorStackChanged: function(e ) {
var newObservedTopOfStack = e.nativeEvent.stackLength - 1;
invariant(
newObservedTopOfStack <= this.state.requestedTopOfStack,
'No navigator item should be pushed without JS knowing about it %s %s', newObservedTopOfStack, this.state.requestedTopOfStack
);
var wasWaitingForConfirmation =
this.state.requestedTopOfStack !== this.state.observedTopOfStack;
if (wasWaitingForConfirmation) {
invariant(
newObservedTopOfStack === this.state.requestedTopOfStack,
'If waiting for observedTopOfStack to reach requestedTopOfStack, ' +
'the only valid observedTopOfStack should be requestedTopOfStack.'
);
}
// Mark the most recent observation regardless of if we can lock the
// navigator. `observedTopOfStack` merely represents what we've observed
// and this first `setState` is only executed to update debugging
// overlays/navigation bar.
// Also reset progress, toIndex, and fromIndex as they might not end
// in the correct states for a two possible reasons:
// Progress isn't always 0 or 1 at the end, the system rounds
// If the Navigator is offscreen these values won't be updated
// TOOD: Revisit this decision when no longer relying on native navigator.
var nextState = {
observedTopOfStack: newObservedTopOfStack,
makingNavigatorRequest: false,
updatingAllIndicesAtOrBeyond: null,
progress: 1,
toIndex: newObservedTopOfStack,
fromIndex: newObservedTopOfStack,
};
this.setState(nextState, this._eliminateUnneededChildren);
},
_eliminateUnneededChildren: function() {
// Updating the indices that we're deleting and that's all. (Truth: Nothing
// even uses the indices in this case, but let's make this describe the
// truth anyways).
var updatingAllIndicesAtOrBeyond =
this.state.routeStack.length > this.state.observedTopOfStack + 1 ?
this.state.observedTopOfStack + 1 :
null;
this.setState({
idStack: this.state.idStack.slice(0, this.state.observedTopOfStack + 1),
routeStack: this.state.routeStack.slice(0, this.state.observedTopOfStack + 1),
// Now we rerequest the top of stack that we observed.
requestedTopOfStack: this.state.observedTopOfStack,
makingNavigatorRequest: true,
updatingAllIndicesAtOrBeyond: updatingAllIndicesAtOrBeyond,
});
},
push: function(route ) {
invariant(!!route, 'Must supply route to push');
// Make sure all previous requests are caught up first. Otherwise reject.
if (this.state.requestedTopOfStack === this.state.observedTopOfStack) {
this._tryLockNavigator(function() {
var nextStack = this.state.routeStack.concat([route]);
var nextIDStack = this.state.idStack.concat([getuid()]);
this.setState({
// We have to make sure that we've also supplied enough views to
// satisfy our request to adjust the `requestedTopOfStack`.
idStack: nextIDStack,
routeStack: nextStack,
requestedTopOfStack: nextStack.length - 1,
makingNavigatorRequest: true,
updatingAllIndicesAtOrBeyond: nextStack.length - 1,
});
}.bind(this));
}
},
popN: function(n ) {
if (n === 0) {
return;
}
// Make sure all previous requests are caught up first. Otherwise reject.
if (this.state.requestedTopOfStack === this.state.observedTopOfStack) {
if (this.state.requestedTopOfStack > 0) {
this._tryLockNavigator(function() {
invariant(
this.state.requestedTopOfStack - n >= 0,
'Cannot pop below 0'
);
this.setState({
requestedTopOfStack: this.state.requestedTopOfStack - n,
makingNavigatorRequest: true,
// Not actually updating the indices yet until we get the native
// `onNavigationComplete`.
updatingAllIndicesAtOrBeyond: null,
});
}.bind(this));
}
}
},
pop: function() {
this.popN(1);
},
/**
* Replace a route in the navigation stack.
*
* `index` specifies the route in the stack that should be replaced.
* If it's negative, it counts from the back.
*/
replaceAtIndex: function(route , index ) {
invariant(!!route, 'Must supply route to replace');
if (index < 0) {
index += this.state.routeStack.length;
}
if (this.state.routeStack.length <= index) {
return;
}
// I don't believe we need to lock for a replace since there's no
// navigation actually happening
var nextIDStack = this.state.idStack.slice();
var nextRouteStack = this.state.routeStack.slice();
nextIDStack[index] = getuid();
nextRouteStack[index] = route;
this.setState({
idStack: nextIDStack,
routeStack: nextRouteStack,
makingNavigatorRequest: false,
updatingAllIndicesAtOrBeyond: index,
});
},
/**
* Replaces the top of the navigation stack.
*/
replace: function(route ) {
this.replaceAtIndex(route, -1);
},
/**
* Replace the current route's parent.
*/
replacePrevious: function(route ) {
this.replaceAtIndex(route, -2);
},
popToTop: function() {
this.popToRoute(this.state.routeStack[0]);
},
popToRoute: function(route ) {
var indexOfRoute = this.state.routeStack.indexOf(route);
invariant(
indexOfRoute !== -1,
'Calling pop to route for a route that doesn\'t exist!'
);
var numToPop = this.state.routeStack.length - indexOfRoute - 1;
this.popN(numToPop);
},
replacePreviousAndPop: function(route ) {
// Make sure all previous requests are caught up first. Otherwise reject.
if (this.state.requestedTopOfStack !== this.state.observedTopOfStack) {
return;
}
if (this.state.routeStack.length < 2) {
return;
}
this._tryLockNavigator(function() {
this.replacePrevious(route);
this.setState({
requestedTopOfStack: this.state.requestedTopOfStack - 1,
makingNavigatorRequest: true,
});
}.bind(this));
},
resetTo: function(route ) {
invariant(!!route, 'Must supply route to push');
// Make sure all previous requests are caught up first. Otherwise reject.
if (this.state.requestedTopOfStack !== this.state.observedTopOfStack) {
return;
}
this.replaceAtIndex(route, 0);
this.popToRoute(route);
},
handleNavigationComplete: function(e ) {
if (this._toFocusOnNavigationComplete) {
this._getFocusEmitter().emit('focus', this._toFocusOnNavigationComplete);
this._toFocusOnNavigationComplete = null;
}
this._handleNavigatorStackChanged(e);
},
_routeToStackItem: function(route , i ) {
var Component = route.component;
var shouldUpdateChild = this.state.updatingAllIndicesAtOrBeyond !== null &&
this.state.updatingAllIndicesAtOrBeyond >= i;
return (
React.createElement(StaticContainer, {key: 'nav' + i, shouldUpdate: shouldUpdateChild},
React.createElement(RCTNavigatorItem, {
title: route.title,
style: [
styles.stackItem,
this.props.itemWrapperStyle,
route.wrapperStyle
],
backButtonIcon: this._imageNameFromSource(route.backButtonIcon),
backButtonTitle: route.backButtonTitle,
leftButtonIcon: this._imageNameFromSource(route.leftButtonIcon),
leftButtonTitle: route.leftButtonTitle,
onNavLeftButtonTap: route.onLeftButtonPress,
rightButtonIcon: this._imageNameFromSource(route.rightButtonIcon),
rightButtonTitle: route.rightButtonTitle,
onNavRightButtonTap: route.onRightButtonPress,
navigationBarHidden: this.props.navigationBarHidden,
tintColor: this.props.tintColor,
barTintColor: this.props.barTintColor,
titleTextColor: this.props.titleTextColor},
React.createElement(Component, React.__spread({
navigator: this.navigator,
route: route},
route.passProps)
)
)
)
);
},
_imageNameFromSource: function(source ) {
return source ? source.uri : undefined;
},
renderNavigationStackItems: function() {
var shouldRecurseToNavigator =
this.state.makingNavigatorRequest ||
this.state.updatingAllIndicesAtOrBeyond !== null;
// If not recursing update to navigator at all, may as well avoid
// computation of navigator children.
var items = shouldRecurseToNavigator ?
this.state.routeStack.map(this._routeToStackItem) : null;
return (
React.createElement(StaticContainer, {shouldUpdate: shouldRecurseToNavigator},
React.createElement(NavigatorTransitionerIOS, {
ref: TRANSITIONER_REF,
style: styles.transitioner,
vertical: this.props.vertical,
requestedTopOfStack: this.state.requestedTopOfStack,
onNavigationComplete: this.handleNavigationComplete},
items
)
)
);
},
render: function() {
return (
React.createElement(View, {style: this.props.style},
this.renderNavigationStackItems()
)
);
}
});
var styles = StyleSheet.create({
stackItem: {
backgroundColor: 'white',
overflow: 'hidden',
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
},
transitioner: {
flex: 1,
},
});
module.exports = NavigatorIOS;
});
__d('StaticContainer.react',["React","onlyChild"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* @generated SignedSource<<e158ef03956b8fface1e9d3f8d611322>>
*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* !! This file is a check-in of a static_upstream project! !!
* !! !!
* !! You should not modify this file directly. Instead: !!
* !! 1) Use `fjs use-upstream` to temporarily replace this with !!
* !! the latest version from upstream. !!
* !! 2) Make your changes, test them, etc. !!
* !! 3) Use `fjs push-upstream` to copy your changes back to !!
* !! static_upstream. !!
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
* @providesModule StaticContainer.react
* @jsx React.DOM
*/
var React = require('React');
var onlyChild = require('onlyChild');
/**
* Renders static content efficiently by allowing React to short-circuit the
* reconciliation process. This component should be used when you know that a
* subtree of components will never need to be updated.
*
* var someValue = ...; // We know for certain this value will never change.
* return (
* <StaticContainer>
* <MyComponent value={someValue} />
* </StaticContainer>
* );
*
* Typically, you will not need to use this component and should opt for normal
* React reconciliation.
*/
var StaticContainer = React.createClass({displayName: "StaticContainer",
shouldComponentUpdate: function(nextProps) {
return nextProps.shouldUpdate;
},
render: function() {
return onlyChild(this.props.children);
}
});
module.exports = StaticContainer;
});
__d('PickerIOS',["NativeMethodsMixin","React","ReactChildren","ReactIOSViewAttributes","NativeModules","StyleSheet","View","createReactIOSNativeComponentClass","merge"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015-present, 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 PickerIOS
*
* This is a controlled component version of RCTPickerIOS
*/
'use strict';
var NativeMethodsMixin = require('NativeMethodsMixin');
var React = require('React');
var ReactChildren = require('ReactChildren');
var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
var RCTPickerIOSConsts = require('NativeModules').UIManager.RCTPicker.Constants;
var StyleSheet = require('StyleSheet');
var View = require('View');
var createReactIOSNativeComponentClass =
require('createReactIOSNativeComponentClass');
var merge = require('merge');
var PICKER = 'picker';
var PickerIOS = React.createClass({displayName: "PickerIOS",
mixins: [NativeMethodsMixin],
propTypes: {
onValueChange: React.PropTypes.func,
selectedValue: React.PropTypes.any, // string or integer basically
},
getInitialState: function() {
return this._stateFromProps(this.props);
},
componentWillReceiveProps: function(nextProps) {
this.setState(this._stateFromProps(nextProps));
},
// Translate PickerIOS prop and children into stuff that RCTPickerIOS understands.
_stateFromProps: function(props) {
var selectedIndex = 0;
var items = [];
ReactChildren.forEach(props.children, function (child, index) {
if (child.props.value === props.selectedValue) {
selectedIndex = index;
}
items.push({value: child.props.value, label: child.props.label});
});
return {selectedIndex:selectedIndex, items:items};
},
render: function() {
return (
React.createElement(View, {style: this.props.style},
React.createElement(RCTPickerIOS, {
ref: PICKER,
style: styles.rkPickerIOS,
items: this.state.items,
selectedIndex: this.state.selectedIndex,
onChange: this._onChange}
)
)
);
},
_onChange: function(event) {
if (this.props.onChange) {
this.props.onChange(event);
}
if (this.props.onValueChange) {
this.props.onValueChange(event.nativeEvent.newValue);
}
// The picker is a controlled component. This means we expect the
// on*Change handlers to be in charge of updating our
// `selectedValue` prop. That way they can also
// disallow/undo/mutate the selection of certain values. In other
// words, the embedder of this component should be the source of
// truth, not the native component.
if (this.state.selectedIndex !== event.nativeEvent.newIndex) {
this.refs[PICKER].setNativeProps({
selectedIndex: this.state.selectedIndex
});
}
},
});
PickerIOS.Item = React.createClass({displayName: "Item",
propTypes: {
value: React.PropTypes.any, // string or integer basically
label: React.PropTypes.string,
},
render: function() {
// These items don't get rendered directly.
return null;
},
});
var styles = StyleSheet.create({
rkPickerIOS: {
// The picker will conform to whatever width is given, but we do
// have to set the component's height explicitly on the
// surrounding view to ensure it gets rendered.
height: RCTPickerIOSConsts.ComponentHeight,
},
});
var rkPickerIOSAttributes = merge(ReactIOSViewAttributes.UIView, {
items: true,
selectedIndex: true,
});
var RCTPickerIOS = createReactIOSNativeComponentClass({
validAttributes: rkPickerIOSAttributes,
uiViewClassName: 'RCTPicker',
});
module.exports = PickerIOS;
});
__d('Navigator',["NativeModules","BackAndroid","Dimensions","InteractionMixin","NavigatorBreadcrumbNavigationBar","NavigatorInterceptor","NavigatorNavigationBar","NavigatorSceneConfigs","NavigatorStaticContextContainer","PanResponder","Platform","React","StaticContainer.react","StyleSheet","Subscribable","react-timer-mixin/TimerMixin","View","clamp","flattenStyle","getNavigatorContext","invariant","keyMirror","merge","rebound/rebound"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015, Facebook, Inc. All rights reserved.
*
* Facebook, Inc. (“Facebook”) owns all right, title and interest, including
* all intellectual property and other proprietary rights, in and to the React
* Native CustomComponents software (the “Software”). Subject to your
* compliance with these terms, you are hereby granted a non-exclusive,
* worldwide, royalty-free copyright license to (1) use and copy the Software;
* and (2) reproduce and distribute the Software as part of your own software
* (“Your Software”). Facebook reserves all rights not expressly granted to
* you in this license agreement.
*
* THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES (INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE) ARE DISCLAIMED.
* IN NO EVENT SHALL FACEBOOK OR ITS AFFILIATES, OFFICERS, DIRECTORS OR
* EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @providesModule Navigator
*/
'use strict';
var AnimationsDebugModule = require('NativeModules').AnimationsDebugModule;
var BackAndroid = require('BackAndroid');
var Dimensions = require('Dimensions');
var InteractionMixin = require('InteractionMixin');
var NavigatorBreadcrumbNavigationBar = require('NavigatorBreadcrumbNavigationBar');
var NavigatorInterceptor = require('NavigatorInterceptor');
var NavigatorNavigationBar = require('NavigatorNavigationBar');
var NavigatorSceneConfigs = require('NavigatorSceneConfigs');
var NavigatorStaticContextContainer = require('NavigatorStaticContextContainer');
var PanResponder = require('PanResponder');
var Platform = require('Platform');
var React = require('React');
var StaticContainer = require('StaticContainer.react');
var StyleSheet = require('StyleSheet');
var Subscribable = require('Subscribable');
var TimerMixin = require('react-timer-mixin/TimerMixin');
var View = require('View');
var clamp = require('clamp');
var flattenStyle = require('flattenStyle');
var getNavigatorContext = require('getNavigatorContext');
var invariant = require('invariant');
var keyMirror = require('keyMirror');
var merge = require('merge');
var rebound = require('rebound/rebound');
var PropTypes = React.PropTypes;
// TODO: this is not ideal because there is no guarantee that the navigator
// is full screen, hwoever we don't have a good way to measure the actual
// size of the navigator right now, so this is the next best thing.
var SCREEN_WIDTH = Dimensions.get('window').width;
var SCREEN_HEIGHT = Dimensions.get('window').height;
var SCENE_DISABLED_NATIVE_PROPS = {
style: {
left: SCREEN_WIDTH,
opacity: 0,
},
};
var __uid = 0;
function getuid() {
return __uid++;
}
// styles moved to the top of the file so getDefaultProps can refer to it
var styles = StyleSheet.create({
container: {
flex: 1,
overflow: 'hidden',
},
defaultSceneStyle: {
position: 'absolute',
left: 0,
right: 0,
bottom: 0,
top: 0,
},
baseScene: {
position: 'absolute',
overflow: 'hidden',
left: 0,
right: 0,
bottom: 0,
top: 0,
},
disabledScene: {
left: SCREEN_WIDTH,
},
transitioner: {
flex: 1,
backgroundColor: 'transparent',
overflow: 'hidden',
}
});
var GESTURE_ACTIONS = [
'pop',
'jumpBack',
'jumpForward',
];
/**
* Use `Navigator` to transition between different scenes in your app. To
* accomplish this, provide route objects to the navigator to identify each
* scene, and also a `renderScene` function that the navigator can use to
* render the scene for a given route.
*
* To change the animation or gesture properties of the scene, provide a
* `configureScene` prop to get the config object for a given route. See
* `Navigator.SceneConfigs` for default animations and more info on
* scene config options.
*
* ### Basic Usage
*
* ```
* <Navigator
* initialRoute={{name: 'My First Scene', index: 0}}
* renderScene={(route, navigator) =>
* <MySceneComponent
* name={route.name}
* onForward={() => {
* var nextIndex = route.index + 1;
* navigator.push({
* name: 'Scene ' + nextIndex,
* index: nextIndex,
* });
* }}
* onBack={() => {
* if (route.index > 0) {
* navigator.pop();
* }
* }}
* />
* }
* />
* ```
*
* ### Navigator Methods
*
* If you have a ref to the Navigator element, you can invoke several methods
* on it to trigger navigation:
*
* - `getCurrentRoutes()` - returns the current list of routes
* - `jumpBack()` - Jump backward without unmounting the current scene
* - `jumpForward()` - Jump forward to the next scene in the route stack
* - `jumpTo(route)` - Transition to an existing scene without unmounting
* - `push(route)` - Navigate forward to a new scene, squashing any scenes
* that you could `jumpForward` to
* - `pop()` - Transition back and unmount the current scene
* - `replace(route)` - Replace the current scene with a new route
* - `replaceAtIndex(route, index)` - Replace a scene as specified by an index
* - `replacePrevious(route)` - Replace the previous scene
* - `immediatelyResetRouteStack(routeStack)` - Reset every scene with an
* array of routes
* - `popToRoute(route)` - Pop to a particular scene, as specified by it's
* route. All scenes after it will be unmounted
* - `popToTop()` - Pop to the first scene in the stack, unmounting every
* other scene
*
* ### Navigation Context
*
* The navigator context object is made available to scenes through the
* `renderScene` function. Alternatively, any scene or component inside a
* Navigator can get the navigation context by calling
* `Navigator.getContext(this)`.
*
* Unlike the Navigator methods, the functions in navigation context do not
* directly control a specific navigator. Instead, the navigator context allows
* a scene to request navigation from its parents. Navigation requests will
* travel up through the hierarchy of Navigators, and will be resolved by the
* deepest active navigator.
*
* Navigation context objects contain the following:
*
* - `getCurrentRoutes()` - returns the routes for the closest navigator
* - `jumpBack()` - Jump backward without unmounting the current scene
* - `jumpForward()` - Jump forward to the next scene in the route stack
* - `jumpTo(route)` - Transition to an existing scene without unmounting
* - `parentNavigator` - a refrence to the parent navigation context
* - `push(route)` - Navigate forward to a new scene, squashing any scenes
* that you could `jumpForward` to
* - `pop()` - Transition back and unmount the current scene
* - `replace(route)` - Replace the current scene with a new route
* - `replaceAtIndex(route, index)` - Replace a scene as specified by an index
* - `replacePrevious(route)` - Replace the previous scene
* - `route` - The route that was used to render the scene with this context
* - `immediatelyResetRouteStack(routeStack)` - Reset every scene with an
* array of routes
* - `popToRoute(route)` - Pop to a particular scene, as specified by it's
* route. All scenes after it will be unmounted
* - `popToTop()` - Pop to the first scene in the stack, unmounting every
* other scene
*
*/
var Navigator = React.createClass({displayName: "Navigator",
propTypes: {
/**
* Optional function that allows configuration about scene animations and
* gestures. Will be invoked with the route and should return a scene
* configuration object
*
* ```
* (route) => Navigator.SceneConfigs.FloatFromRight
* ```
*/
configureScene: PropTypes.func,
/**
* Required function which renders the scene for a given route. Will be
* invoked with the route and the navigator object
*
* ```
* (route, navigator) =>
* <MySceneComponent title={route.title} />
* ```
*/
renderScene: PropTypes.func.isRequired,
/**
* Specify a route to start on. A route is an object that the navigator
* will use to identify each scene to render. `initialRoute` must be
* a route in the `initialRouteStack` if both props are provided. The
* `initialRoute` will default to the last item in the `initialRouteStack`.
*/
initialRoute: PropTypes.object,
/**
* Provide a set of routes to initially mount. Required if no initialRoute
* is provided. Otherwise, it will default to an array containing only the
* `initialRoute`
*/
initialRouteStack: PropTypes.arrayOf(PropTypes.object),
/**
* Will emit the target route upon mounting and before each nav transition
*/
onWillFocus: PropTypes.func,
/**
* Will be called with the new route of each scene after the transition is
* complete or after the initial mounting
*/
onDidFocus: PropTypes.func,
/**
* Will be called with (ref, indexInStack) when the scene ref changes
*/
onItemRef: PropTypes.func,
/**
* Optionally provide a navigation bar that persists across scene
* transitions
*/
navigationBar: PropTypes.node,
/**
* Optionally provide the navigator object from a parent Navigator
*/
navigator: PropTypes.object,
/**
* Styles to apply to the container of each scene
*/
sceneStyle: View.propTypes.style,
},
contextTypes: {
// TODO (t6707746) Re-enable this when owner context switches to parent context
// navigator: PropTypes.object,
},
statics: {
BreadcrumbNavigationBar: NavigatorBreadcrumbNavigationBar,
NavigationBar: NavigatorNavigationBar,
SceneConfigs: NavigatorSceneConfigs,
Interceptor: NavigatorInterceptor,
getContext: getNavigatorContext,
},
mixins: [TimerMixin, InteractionMixin, Subscribable.Mixin],
getDefaultProps: function() {
return {
configureScene: function() {return NavigatorSceneConfigs.PushFromRight;},
sceneStyle: styles.defaultSceneStyle,
};
},
getInitialState: function() {
var routeStack = this.props.initialRouteStack || [this.props.initialRoute];
invariant(
routeStack.length >= 1,
'Navigator requires props.initialRoute or props.initialRouteStack.'
);
var initialRouteIndex = routeStack.length - 1;
if (this.props.initialRoute) {
initialRouteIndex = routeStack.indexOf(this.props.initialRoute);
invariant(
initialRouteIndex !== -1,
'initialRoute is not in initialRouteStack.'
);
}
return {
sceneConfigStack: routeStack.map(
function(route) {return this.props.configureScene(route);}.bind(this)
),
idStack: routeStack.map(function() {return getuid();}),
routeStack:routeStack,
// `updatingRange*` allows us to only render the visible or staged scenes
// On first render, we will render every scene in the initialRouteStack
updatingRangeStart: 0,
updatingRangeLength: routeStack.length,
presentedIndex: initialRouteIndex,
transitionFromIndex: null,
activeGesture: null,
pendingGestureProgress: null,
transitionQueue: [],
};
},
componentWillMount: function() {
this.parentNavigator = getNavigatorContext(this) || this.props.navigator;
this._subRouteFocus = [];
this.navigatorContext = {
// Actions for child navigators or interceptors:
setHandlerForRoute: this.setHandlerForRoute,
request: this.request,
// Contextual utilities
parentNavigator: this.parentNavigator,
getCurrentRoutes: this.getCurrentRoutes,
// `route` is injected by NavigatorStaticContextContainer
// Contextual nav actions
pop: this.requestPop,
popToRoute: this.requestPopTo,
// Legacy, imperitive nav actions. Will transition these to contextual actions
jumpBack: this.jumpBack,
jumpForward: this.jumpForward,
jumpTo: this.jumpTo,
push: this.push,
replace: this.replace,
replaceAtIndex: this.replaceAtIndex,
replacePrevious: this.replacePrevious,
replacePreviousAndPop: this.replacePreviousAndPop,
immediatelyResetRouteStack: this.immediatelyResetRouteStack,
resetTo: this.resetTo,
popToTop: this.popToTop,
};
this._handlers = {};
this.springSystem = new rebound.SpringSystem();
this.spring = this.springSystem.createSpring();
this.spring.setRestSpeedThreshold(0.05);
this.spring.setCurrentValue(0).setAtRest();
this.spring.addListener({
onSpringEndStateChange: function() {
if (!this._interactionHandle) {
this._interactionHandle = this.createInteractionHandle();
}
}.bind(this),
onSpringUpdate: function() {
this._handleSpringUpdate();
}.bind(this),
onSpringAtRest: function() {
this._completeTransition();
}.bind(this),
});
this.panGesture = PanResponder.create({
onMoveShouldSetPanResponder: this._handleMoveShouldSetPanResponder,
onPanResponderGrant: this._handlePanResponderGrant,
onPanResponderRelease: this._handlePanResponderRelease,
onPanResponderMove: this._handlePanResponderMove,
onPanResponderTerminate: this._handlePanResponderTerminate,
});
this._itemRefs = {};
this._interactionHandle = null;
this._emitWillFocus(this.state.routeStack[this.state.presentedIndex]);
},
request: function(action, arg1, arg2) {
if (this.parentNavigator) {
return this.parentNavigator.request.apply(null, arguments);
}
return this._handleRequest.apply(null, arguments);
},
requestPop: function(popToBeforeRoute) {
return this.request('pop', popToBeforeRoute);
},
requestPopTo: function(route) {
return this.request('popTo', route);
},
_handleRequest: function(action, arg1, arg2) {
var childHandler = this._handlers[this.state.presentedIndex];
if (childHandler && childHandler(action, arg1, arg2)) {
return true;
}
switch (action) {
case 'pop':
return this._handlePop(arg1);
case 'popTo':
return this._handlePopTo(arg1);
case 'push':
return this._handlePush(arg1);
default:
invariant(false, 'Unsupported request type ' + action);
return false;
}
},
_handlePop: function(popToBeforeRoute) {
if (popToBeforeRoute) {
var popToBeforeRouteIndex = this.state.routeStack.indexOf(popToBeforeRoute);
if (popToBeforeRouteIndex === -1) {
return false;
}
invariant(
popToBeforeRouteIndex <= this.state.presentedIndex,
'Cannot pop past a route that is forward in the navigator'
);
this._popN(this.state.presentedIndex - popToBeforeRouteIndex + 1);
return true;
}
if (this.state.presentedIndex === 0) {
return false;
}
this.pop();
return true;
},
_handlePopTo: function(destRoute) {
if (destRoute) {
var hasRoute = this.state.routeStack.indexOf(destRoute) !== -1;
if (hasRoute) {
this.popToRoute(destRoute);
return true;
} else {
return false;
}
}
if (this.state.presentedIndex === 0) {
return false;
}
this.pop();
return true;
},
_handlePush: function(route) {
this.push(route);
return true;
},
setHandlerForRoute: function(route, handler) {
this._handlers[this.state.routeStack.indexOf(route)] = handler;
},
componentDidMount: function() {
this._handleSpringUpdate();
this._emitDidFocus(this.state.routeStack[this.state.presentedIndex]);
if (this.parentNavigator) {
this.parentNavigator.setHandler(this._handleRequest);
} else if (Platform.OS === 'android') {
// There is no navigator in our props or context, so this is the
// top-level navigator. We will handle back button presses here
BackAndroid.addEventListener('hardwareBackPress', this._handleAndroidBackPress);
}
},
componentWillUnmount: function() {
if (this.parentNavigator) {
this.parentNavigator.setHandler(null);
} else if (Platform.OS === 'android') {
BackAndroid.removeEventListener('hardwareBackPress', this._handleAndroidBackPress);
}
},
_handleAndroidBackPress: function() {
var didPop = this.requestPop();
if (!didPop) {
BackAndroid.exitApp();
}
},
/**
* @param {RouteStack} nextRouteStack Next route stack to reinitialize. This
* doesn't accept stack item `id`s, which implies that all existing items are
* destroyed, and then potentially recreated according to `routeStack`. Does
* not animate, immediately replaces and rerenders navigation bar and stack
* items.
*/
immediatelyResetRouteStack: function(nextRouteStack) {
var destIndex = nextRouteStack.length - 1;
this.setState({
idStack: nextRouteStack.map(getuid),
routeStack: nextRouteStack,
sceneConfigStack: nextRouteStack.map(
this.props.configureScene
),
updatingRangeStart: 0,
updatingRangeLength: nextRouteStack.length,
presentedIndex: destIndex,
activeGesture: null,
transitionFromIndex: null,
transitionQueue: [],
}, function() {
this._handleSpringUpdate();
}.bind(this));
},
_transitionTo: function(destIndex, velocity, jumpSpringTo, cb) {
if (destIndex === this.state.presentedIndex) {
return;
}
if (this.state.transitionFromIndex !== null) {
this.state.transitionQueue.push({
destIndex:destIndex,
velocity:velocity,
cb:cb,
});
return;
}
this.state.transitionFromIndex = this.state.presentedIndex;
this.state.presentedIndex = destIndex;
this.state.transitionCb = cb;
this._onAnimationStart();
if (AnimationsDebugModule) {
AnimationsDebugModule.startRecordingFps();
}
var sceneConfig = this.state.sceneConfigStack[this.state.transitionFromIndex] ||
this.state.sceneConfigStack[this.state.presentedIndex];
invariant(
sceneConfig,
'Cannot configure scene at index ' + this.state.transitionFromIndex
);
if (jumpSpringTo != null) {
this.spring.setCurrentValue(jumpSpringTo);
}
this.spring.setOvershootClampingEnabled(true);
this.spring.getSpringConfig().friction = sceneConfig.springFriction;
this.spring.getSpringConfig().tension = sceneConfig.springTension;
this.spring.setVelocity(velocity || sceneConfig.defaultTransitionVelocity);
this.spring.setEndValue(1);
var willFocusRoute = this._subRouteFocus[this.state.presentedIndex] || this.state.routeStack[this.state.presentedIndex];
this._emitWillFocus(willFocusRoute);
},
/**
* This happens for each frame of either a gesture or a transition. If both are
* happening, we only set values for the transition and the gesture will catch up later
*/
_handleSpringUpdate: function() {
// Prioritize handling transition in progress over a gesture:
if (this.state.transitionFromIndex != null) {
this._transitionBetween(
this.state.transitionFromIndex,
this.state.presentedIndex,
this.spring.getCurrentValue()
);
} else if (this.state.activeGesture != null) {
this._transitionBetween(
this.state.presentedIndex,
this.state.presentedIndex + this._deltaForGestureAction(this.state.activeGesture),
this.spring.getCurrentValue()
);
}
},
/**
* This happens at the end of a transition started by transitionTo, and when the spring catches up to a pending gesture
*/
_completeTransition: function() {
if (this.spring.getCurrentValue() !== 1) {
// The spring has finished catching up to a gesture in progress. Remove the pending progress
// and we will be in a normal activeGesture state
if (this.state.pendingGestureProgress) {
this.state.pendingGestureProgress = null;
}
return;
}
this._onAnimationEnd();
var presentedIndex = this.state.presentedIndex;
var didFocusRoute = this._subRouteFocus[presentedIndex] || this.state.routeStack[presentedIndex];
this._emitDidFocus(didFocusRoute);
if (AnimationsDebugModule) {
AnimationsDebugModule.stopRecordingFps(Date.now());
}
this.state.transitionFromIndex = null;
this.spring.setCurrentValue(0).setAtRest();
this._hideScenes();
if (this.state.transitionCb) {
this.state.transitionCb();
this.state.transitionCb = null;
}
if (this._interactionHandle) {
this.clearInteractionHandle(this._interactionHandle);
this._interactionHandle = null;
}
if (this.state.pendingGestureProgress) {
// A transition completed, but there is already another gesture happening.
// Enable the scene and set the spring to catch up with the new gesture
var gestureToIndex = this.state.presentedIndex + this._deltaForGestureAction(this.state.activeGesture);
this._enableScene(gestureToIndex);
this.spring.setEndValue(this.state.pendingGestureProgress);
return;
}
if (this.state.transitionQueue.length) {
var queuedTransition = this.state.transitionQueue.shift();
this._enableScene(queuedTransition.destIndex);
this._transitionTo(
queuedTransition.destIndex,
queuedTransition.velocity,
null,
queuedTransition.cb
);
}
},
_emitDidFocus: function(route) {
if (this._lastDidFocus === route) {
return;
}
this._lastDidFocus = route;
if (this.props.onDidFocus) {
this.props.onDidFocus(route);
}
if (this.parentNavigator && this.parentNavigator.onDidFocus) {
this.parentNavigator.onDidFocus(route);
}
},
_emitWillFocus: function(route) {
if (this._lastWillFocus === route) {
return;
}
this._lastWillFocus = route;
var navBar = this._navBar;
if (navBar && navBar.handleWillFocus) {
navBar.handleWillFocus(route);
}
if (this.props.onWillFocus) {
this.props.onWillFocus(route);
}
if (this.parentNavigator && this.parentNavigator.onWillFocus) {
this.parentNavigator.onWillFocus(route);
}
},
/**
* Hides scenes that we are not currently on or transitioning from
*/
_hideScenes: function() {
for (var i = 0; i < this.state.routeStack.length; i++) {
if (i === this.state.presentedIndex || i === this.state.transitionFromIndex) {
continue;
}
this._disableScene(i);
}
},
/**
* Push a scene off the screen, so that opacity:0 scenes will not block touches sent to the presented scenes
*/
_disableScene: function(sceneIndex) {
this.refs['scene_' + sceneIndex] &&
this.refs['scene_' + sceneIndex].setNativeProps(SCENE_DISABLED_NATIVE_PROPS);
},
/**
* Put the scene back into the state as defined by props.sceneStyle, so transitions can happen normally
*/
_enableScene: function(sceneIndex) {
// First, determine what the defined styles are for scenes in this navigator
var sceneStyle = flattenStyle(this.props.sceneStyle);
// Then restore the left value for this scene
var enabledSceneNativeProps = {
left: sceneStyle.left,
};
if (sceneIndex !== this.state.transitionFromIndex &&
sceneIndex !== this.state.presentedIndex) {
// If we are not in a transition from this index, make sure opacity is 0
// to prevent the enabled scene from flashing over the presented scene
enabledSceneNativeProps.opacity = 0;
}
this.refs['scene_' + sceneIndex] &&
this.refs['scene_' + sceneIndex].setNativeProps(enabledSceneNativeProps);
},
_onAnimationStart: function() {
var fromIndex = this.state.presentedIndex;
var toIndex = this.state.presentedIndex;
if (this.state.transitionFromIndex != null) {
fromIndex = this.state.transitionFromIndex;
} else if (this.state.activeGesture) {
toIndex = this.state.presentedIndex + this._deltaForGestureAction(this.state.activeGesture);
}
this._setRenderSceneToHarwareTextureAndroid(fromIndex, true);
this._setRenderSceneToHarwareTextureAndroid(toIndex, true);
var navBar = this._navBar;
if (navBar && navBar.onAnimationStart) {
navBar.onAnimationStart(fromIndex, toIndex);
}
},
_onAnimationEnd: function() {
var max = this.state.routeStack.length - 1;
for (var index = 0; index <= max; index++) {
this._setRenderSceneToHarwareTextureAndroid(index, false);
}
var navBar = this._navBar;
if (navBar && navBar.onAnimationEnd) {
navBar.onAnimationEnd();
}
},
_setRenderSceneToHarwareTextureAndroid: function(sceneIndex, shouldRenderToHardwareTexture) {
var viewAtIndex = this.refs['scene_' + sceneIndex];
if (viewAtIndex === null || viewAtIndex === undefined) {
return;
}
viewAtIndex.setNativeProps({renderToHardwareTextureAndroid: shouldRenderToHardwareTexture});
},
_handleMoveShouldSetPanResponder: function(e, gestureState) {
var currentRoute = this.state.routeStack[this.state.presentedIndex];
var sceneConfig = this.state.sceneConfigStack[this.state.presentedIndex];
this._expectingGestureGrant = this._matchGestureAction(sceneConfig.gestures, gestureState);
return !! this._expectingGestureGrant;
},
_doesGestureOverswipe: function(gestureName) {
var wouldOverswipeBack = this.state.presentedIndex <= 0 &&
(gestureName === 'pop' || gestureName === 'jumpBack');
var wouldOverswipeForward = this.state.presentedIndex >= this.state.routeStack.length - 1 &&
gestureName === 'jumpForward';
return wouldOverswipeForward || wouldOverswipeBack;
},
_handlePanResponderGrant: function(e, gestureState) {
invariant(
this._expectingGestureGrant,
'Responder granted unexpectedly.'
);
this._attachGesture(this._expectingGestureGrant);
this._onAnimationStart();
this._expectingGestureGrant = null;
},
_deltaForGestureAction: function(gestureAction) {
switch (gestureAction) {
case 'pop':
case 'jumpBack':
return -1;
case 'jumpForward':
return 1;
default:
invariant(false, 'Unsupported gesture action ' + gestureAction);
return;
}
},
_handlePanResponderRelease: function(e, gestureState) {
var sceneConfig = this.state.sceneConfigStack[this.state.presentedIndex];
var releaseGestureAction = this.state.activeGesture;
if (!releaseGestureAction) {
// The gesture may have been detached while responder, so there is no action here
return;
}
var releaseGesture = sceneConfig.gestures[releaseGestureAction];
var destIndex = this.state.presentedIndex + this._deltaForGestureAction(this.state.activeGesture);
if (this.spring.getCurrentValue() === 0) {
// The spring is at zero, so the gesture is already complete
this.spring.setCurrentValue(0).setAtRest();
this._completeTransition();
return;
}
var isTravelVertical = releaseGesture.direction === 'top-to-bottom' || releaseGesture.direction === 'bottom-to-top';
var isTravelInverted = releaseGesture.direction === 'right-to-left' || releaseGesture.direction === 'bottom-to-top';
var velocity, gestureDistance;
if (isTravelVertical) {
velocity = isTravelInverted ? -gestureState.vy : gestureState.vy;
gestureDistance = isTravelInverted ? -gestureState.dy : gestureState.dy;
} else {
velocity = isTravelInverted ? -gestureState.vx : gestureState.vx;
gestureDistance = isTravelInverted ? -gestureState.dx : gestureState.dx;
}
var transitionVelocity = clamp(-10, velocity, 10);
if (Math.abs(velocity) < releaseGesture.notMoving) {
// The gesture velocity is so slow, is "not moving"
var hasGesturedEnoughToComplete = gestureDistance > releaseGesture.fullDistance * releaseGesture.stillCompletionRatio;
transitionVelocity = hasGesturedEnoughToComplete ? releaseGesture.snapVelocity : -releaseGesture.snapVelocity;
}
if (transitionVelocity < 0 || this._doesGestureOverswipe(releaseGestureAction)) {
// This gesture is to an overswiped region or does not have enough velocity to complete
// If we are currently mid-transition, then this gesture was a pending gesture. Because this gesture takes no action, we can stop here
if (this.state.transitionFromIndex == null) {
// There is no current transition, so we need to transition back to the presented index
var transitionBackToPresentedIndex = this.state.presentedIndex;
// slight hack: change the presented index for a moment in order to transitionTo correctly
this.state.presentedIndex = destIndex;
this._transitionTo(
transitionBackToPresentedIndex,
- transitionVelocity,
1 - this.spring.getCurrentValue()
);
}
} else {
// The gesture has enough velocity to complete, so we transition to the gesture's destination
this._transitionTo(destIndex, transitionVelocity);
}
this._detachGesture();
},
_handlePanResponderTerminate: function(e, gestureState) {
var destIndex = this.state.presentedIndex + this._deltaForGestureAction(this.state.activeGesture);
this._detachGesture();
var transitionBackToPresentedIndex = this.state.presentedIndex;
// slight hack: change the presented index for a moment in order to transitionTo correctly
this.state.presentedIndex = destIndex;
this._transitionTo(
transitionBackToPresentedIndex,
null,
1 - this.spring.getCurrentValue()
);
},
_attachGesture: function(gestureId) {
this.state.activeGesture = gestureId;
var gesturingToIndex = this.state.presentedIndex + this._deltaForGestureAction(this.state.activeGesture);
this._enableScene(gesturingToIndex);
},
_detachGesture: function() {
this.state.activeGesture = null;
this.state.pendingGestureProgress = null;
this._hideScenes();
},
_handlePanResponderMove: function(e, gestureState) {
var sceneConfig = this.state.sceneConfigStack[this.state.presentedIndex];
if (this.state.activeGesture) {
var gesture = sceneConfig.gestures[this.state.activeGesture];
return this._moveAttachedGesture(gesture, gestureState);
}
var matchedGesture = this._matchGestureAction(sceneConfig.gestures, gestureState);
if (matchedGesture) {
this._attachGesture(matchedGesture);
}
},
_moveAttachedGesture: function(gesture, gestureState) {
var isTravelVertical = gesture.direction === 'top-to-bottom' || gesture.direction === 'bottom-to-top';
var isTravelInverted = gesture.direction === 'right-to-left' || gesture.direction === 'bottom-to-top';
var distance = isTravelVertical ? gestureState.dy : gestureState.dx;
distance = isTravelInverted ? - distance : distance;
var gestureDetectMovement = gesture.gestureDetectMovement;
var nextProgress = (distance - gestureDetectMovement) /
(gesture.fullDistance - gestureDetectMovement);
if (nextProgress < 0 && gesture.isDetachable) {
this._detachGesture();
this.spring.setCurrentValue(0);
}
if (this._doesGestureOverswipe(this.state.activeGesture)) {
var frictionConstant = gesture.overswipe.frictionConstant;
var frictionByDistance = gesture.overswipe.frictionByDistance;
var frictionRatio = 1 / ((frictionConstant) + (Math.abs(nextProgress) * frictionByDistance));
nextProgress *= frictionRatio;
}
nextProgress = clamp(0, nextProgress, 1);
if (this.state.transitionFromIndex != null) {
this.state.pendingGestureProgress = nextProgress;
} else if (this.state.pendingGestureProgress) {
this.spring.setEndValue(nextProgress);
} else {
this.spring.setCurrentValue(nextProgress);
}
},
_matchGestureAction: function(gestures, gestureState) {
if (!gestures) {
return null;
}
var matchedGesture = null;
GESTURE_ACTIONS.some(function(gestureName) {
var gesture = gestures[gestureName];
if (!gesture) {
return;
}
if (gesture.overswipe == null && this._doesGestureOverswipe(gestureName)) {
// cannot swipe past first or last scene without overswiping
return false;
}
var isTravelVertical = gesture.direction === 'top-to-bottom' || gesture.direction === 'bottom-to-top';
var isTravelInverted = gesture.direction === 'right-to-left' || gesture.direction === 'bottom-to-top';
var currentLoc = isTravelVertical ? gestureState.moveY : gestureState.moveX;
var travelDist = isTravelVertical ? gestureState.dy : gestureState.dx;
var oppositeAxisTravelDist =
isTravelVertical ? gestureState.dx : gestureState.dy;
var edgeHitWidth = gesture.edgeHitWidth;
if (isTravelInverted) {
currentLoc = -currentLoc;
travelDist = -travelDist;
oppositeAxisTravelDist = -oppositeAxisTravelDist;
edgeHitWidth = isTravelVertical ?
-(SCREEN_HEIGHT - edgeHitWidth) :
-(SCREEN_WIDTH - edgeHitWidth);
}
var moveStartedInRegion = gesture.edgeHitWidth == null ||
currentLoc < edgeHitWidth;
var moveTravelledFarEnough =
travelDist >= gesture.gestureDetectMovement &&
travelDist > oppositeAxisTravelDist * gesture.directionRatio;
if (moveStartedInRegion && moveTravelledFarEnough) {
matchedGesture = gestureName;
return true;
}
}.bind(this));
return matchedGesture;
},
_transitionSceneStyle: function(fromIndex, toIndex, progress, index) {
var viewAtIndex = this.refs['scene_' + index];
if (viewAtIndex === null || viewAtIndex === undefined) {
return;
}
// Use toIndex animation when we move forwards. Use fromIndex when we move back
var sceneConfigIndex = fromIndex < toIndex ? toIndex : fromIndex;
var sceneConfig = this.state.sceneConfigStack[sceneConfigIndex];
// this happens for overswiping when there is no scene at toIndex
if (!sceneConfig) {
sceneConfig = this.state.sceneConfigStack[sceneConfigIndex - 1];
}
var styleToUse = {};
var useFn = index < fromIndex || index < toIndex ?
sceneConfig.animationInterpolators.out :
sceneConfig.animationInterpolators.into;
var directionAdjustedProgress = fromIndex < toIndex ? progress : 1 - progress;
var didChange = useFn(styleToUse, directionAdjustedProgress);
if (didChange) {
viewAtIndex.setNativeProps({style: styleToUse});
}
},
_transitionBetween: function(fromIndex, toIndex, progress) {
this._transitionSceneStyle(fromIndex, toIndex, progress, fromIndex);
this._transitionSceneStyle(fromIndex, toIndex, progress, toIndex);
var navBar = this._navBar;
if (navBar && navBar.updateProgress) {
navBar.updateProgress(progress, fromIndex, toIndex);
}
},
_handleResponderTerminationRequest: function() {
return false;
},
_resetUpdatingRange: function() {
this.state.updatingRangeStart = 0;
this.state.updatingRangeLength = this.state.routeStack.length;
},
_getDestIndexWithinBounds: function(n) {
var currentIndex = this.state.presentedIndex;
var destIndex = currentIndex + n;
invariant(
destIndex >= 0,
'Cannot jump before the first route.'
);
var maxIndex = this.state.routeStack.length - 1;
invariant(
maxIndex >= destIndex,
'Cannot jump past the last route.'
);
return destIndex;
},
_jumpN: function(n) {
var destIndex = this._getDestIndexWithinBounds(n);
var requestTransitionAndResetUpdatingRange = function() {
this._enableScene(destIndex);
this._transitionTo(destIndex);
this._resetUpdatingRange();
}.bind(this);
this.setState({
updatingRangeStart: destIndex,
updatingRangeLength: 1,
}, requestTransitionAndResetUpdatingRange);
},
jumpTo: function(route) {
var destIndex = this.state.routeStack.indexOf(route);
invariant(
destIndex !== -1,
'Cannot jump to route that is not in the route stack'
);
this._jumpN(destIndex - this.state.presentedIndex);
},
jumpForward: function() {
this._jumpN(1);
},
jumpBack: function() {
this._jumpN(-1);
},
push: function(route) {
invariant(!!route, 'Must supply route to push');
var activeLength = this.state.presentedIndex + 1;
var activeStack = this.state.routeStack.slice(0, activeLength);
var activeIDStack = this.state.idStack.slice(0, activeLength);
var activeAnimationConfigStack = this.state.sceneConfigStack.slice(0, activeLength);
var nextStack = activeStack.concat([route]);
var destIndex = nextStack.length - 1;
var nextIDStack = activeIDStack.concat([getuid()]);
var nextAnimationConfigStack = activeAnimationConfigStack.concat([
this.props.configureScene(route),
]);
var requestTransitionAndResetUpdatingRange = function() {
this._enableScene(destIndex);
this._transitionTo(destIndex);
this._resetUpdatingRange();
}.bind(this);
this.setState({
idStack: nextIDStack,
routeStack: nextStack,
sceneConfigStack: nextAnimationConfigStack,
updatingRangeStart: nextStack.length - 1,
updatingRangeLength: 1,
}, requestTransitionAndResetUpdatingRange);
},
_popN: function(n) {
if (n === 0) {
return;
}
invariant(
this.state.presentedIndex - n >= 0,
'Cannot pop below zero'
);
var popIndex = this.state.presentedIndex - n;
this._enableScene(popIndex);
this._transitionTo(
popIndex,
null, // default velocity
null, // no spring jumping
function() {
this._cleanScenesPastIndex(popIndex);
}.bind(this)
);
},
pop: function() {
this._popN(1);
},
/**
* Replace a route in the navigation stack.
*
* `index` specifies the route in the stack that should be replaced.
* If it's negative, it counts from the back.
*/
replaceAtIndex: function(route, index, cb) {
invariant(!!route, 'Must supply route to replace');
if (index < 0) {
index += this.state.routeStack.length;
}
if (this.state.routeStack.length <= index) {
return;
}
// I don't believe we need to lock for a replace since there's no
// navigation actually happening
var nextIDStack = this.state.idStack.slice();
var nextRouteStack = this.state.routeStack.slice();
var nextAnimationModeStack = this.state.sceneConfigStack.slice();
nextIDStack[index] = getuid();
nextRouteStack[index] = route;
nextAnimationModeStack[index] = this.props.configureScene(route);
this.setState({
idStack: nextIDStack,
routeStack: nextRouteStack,
sceneConfigStack: nextAnimationModeStack,
updatingRangeStart: index,
updatingRangeLength: 1,
}, function() {
this._resetUpdatingRange();
if (index === this.state.presentedIndex) {
this._emitWillFocus(route);
this._emitDidFocus(route);
}
cb && cb();
}.bind(this));
},
/**
* Replaces the current scene in the stack.
*/
replace: function(route) {
this.replaceAtIndex(route, this.state.presentedIndex);
},
/**
* Replace the current route's parent.
*/
replacePrevious: function(route) {
this.replaceAtIndex(route, this.state.presentedIndex - 1);
},
popToTop: function() {
this.popToRoute(this.state.routeStack[0]);
},
_getNumToPopForRoute: function(route) {
var indexOfRoute = this.state.routeStack.indexOf(route);
invariant(
indexOfRoute !== -1,
'Calling pop to route for a route that doesn\'t exist!'
);
return this.state.presentedIndex - indexOfRoute;
},
popToRoute: function(route) {
var numToPop = this._getNumToPopForRoute(route);
this._popN(numToPop);
},
replacePreviousAndPop: function(route) {
if (this.state.routeStack.length < 2) {
return;
}
this.replacePrevious(route);
this.pop();
},
resetTo: function(route) {
invariant(!!route, 'Must supply route to push');
this.replaceAtIndex(route, 0, function() {
this.popToRoute(route);
}.bind(this));
},
getCurrentRoutes: function() {
return this.state.routeStack;
},
_handleItemRef: function(itemId, ref) {
this._itemRefs[itemId] = ref;
var itemIndex = this.state.idStack.indexOf(itemId);
if (itemIndex === -1) {
return;
}
this.props.onItemRef && this.props.onItemRef(ref, itemIndex);
},
_cleanScenesPastIndex: function(index) {
var newStackLength = index + 1;
// Remove any unneeded rendered routes.
if (newStackLength < this.state.routeStack.length) {
var updatingRangeStart = newStackLength; // One past the top
var updatingRangeLength = this.state.routeStack.length - newStackLength + 1;
this.state.idStack.slice(newStackLength).map(function(removingId) {
this._itemRefs[removingId] = null;
}.bind(this));
this.setState({
updatingRangeStart: updatingRangeStart,
updatingRangeLength: updatingRangeLength,
sceneConfigStack: this.state.sceneConfigStack.slice(0, newStackLength),
idStack: this.state.idStack.slice(0, newStackLength),
routeStack: this.state.routeStack.slice(0, newStackLength),
}, this._resetUpdatingRange);
}
},
_renderOptimizedScenes: function() {
// To avoid rendering scenes that are not visible, we use
// updatingRangeStart and updatingRangeLength to track the scenes that need
// to be updated.
// To avoid visual glitches, we never re-render scenes during a transition.
// We assume that `state.updatingRangeLength` will have a length during the
// initial render of any scene
var shouldRenderScenes = this.state.updatingRangeLength !== 0;
if (shouldRenderScenes) {
return (
React.createElement(StaticContainer, {shouldUpdate: true},
React.createElement(View, React.__spread({
style: styles.transitioner},
this.panGesture.panHandlers,
{onResponderTerminationRequest:
this._handleResponderTerminationRequest
}),
this.state.routeStack.map(this._renderOptimizedScene)
)
)
);
}
// If no scenes are changing, we can save render time. React will notice
// that we are rendering a StaticContainer in the same place, so the
// existing element will be updated. When React asks the element
// shouldComponentUpdate, the StaticContainer will return false, and the
// children from the previous reconciliation will remain.
return (
React.createElement(StaticContainer, {shouldUpdate: false})
);
},
_renderOptimizedScene: function(route, i) {
var shouldRenderScene =
i >= this.state.updatingRangeStart &&
i <= this.state.updatingRangeStart + this.state.updatingRangeLength;
var sceneNavigatorContext = Object.assign({},
this.navigatorContext,
{route:route,
setHandler: function(handler) {
this.navigatorContext.setHandlerForRoute(route, handler);
}.bind(this),
onWillFocus: function(childRoute) {
this._subRouteFocus[i] = childRoute;
if (this.state.presentedIndex === i) {
this._emitWillFocus(childRoute);
}
}.bind(this),
onDidFocus: function(childRoute) {
this._subRouteFocus[i] = childRoute;
if (this.state.presentedIndex === i) {
this._emitDidFocus(childRoute);
}
}.bind(this)
});
var scene = shouldRenderScene ?
this._renderScene(route, i, sceneNavigatorContext) : null;
return (
React.createElement(NavigatorStaticContextContainer, {
navigatorContext: sceneNavigatorContext,
key: 'nav' + i,
shouldUpdate: shouldRenderScene},
scene
)
);
},
_renderScene: function(route, i, sceneNavigatorContext) {
var child = this.props.renderScene(
route,
sceneNavigatorContext
);
var disabledSceneStyle = null;
if (i !== this.state.presentedIndex) {
disabledSceneStyle = styles.disabledScene;
}
return (
React.createElement(View, {
key: this.state.idStack[i],
ref: 'scene_' + i,
onStartShouldSetResponderCapture: function() {
return i !== this.state.presentedIndex;
}.bind(this),
style: [styles.baseScene, this.props.sceneStyle, disabledSceneStyle]},
React.cloneElement(child, {
ref: this._handleItemRef.bind(null, this.state.idStack[i]),
})
)
);
},
_renderNavigationBar: function() {
if (!this.props.navigationBar) {
return null;
}
return React.cloneElement(this.props.navigationBar, {
ref: function(navBar) { this._navBar = navBar; }.bind(this),
navigator: this.navigatorContext,
navState: this.state,
});
},
render: function() {
return (
React.createElement(View, {style: [styles.container, this.props.style]},
this._renderOptimizedScenes(),
this._renderNavigationBar()
)
);
},
});
module.exports = Navigator;
});
__d('BackAndroid',["warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* iOS stub for BackAndroid.android.js
*
* @providesModule BackAndroid
*/
'use strict';
var warning = require('warning');
function platformWarn() {
warning(false, 'BackAndroid is not supported on this platform.');
}
var BackAndroid = {
exitApp: platformWarn,
addEventListener: platformWarn,
removeEventListener: platformWarn,
};
module.exports = BackAndroid;
});
__d('InteractionMixin',["InteractionManager"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule InteractionMixin
* @flow
*/
'use strict';
var InteractionManager = require('InteractionManager');
/**
* This mixin provides safe versions of InteractionManager start/end methods
* that ensures `clearInteractionHandle` is always called
* once per start, even if the component is unmounted.
*/
var InteractionMixin = {
componentWillUnmount: function() {
while (this._interactionMixinHandles.length) {
InteractionManager.clearInteractionHandle(
this._interactionMixinHandles.pop()
);
}
},
_interactionMixinHandles: ([] ),
createInteractionHandle: function() {
var handle = InteractionManager.createInteractionHandle();
this._interactionMixinHandles.push(handle);
return handle;
},
clearInteractionHandle: function(clearHandle ) {
InteractionManager.clearInteractionHandle(clearHandle);
this._interactionMixinHandles = this._interactionMixinHandles.filter(
function(handle) {return handle !== clearHandle;}
);
},
/**
* Schedule work for after all interactions have completed.
*
* @param {function} callback
*/
runAfterInteractions: function(callback ) {
InteractionManager.runAfterInteractions(callback);
},
};
module.exports = InteractionMixin;
});
__d('NavigatorBreadcrumbNavigationBar',["NavigatorBreadcrumbNavigationBarStyles","NavigatorNavigationBarStyles","React","StaticContainer.react","StyleSheet","View","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015, Facebook, Inc. All rights reserved.
*
* Facebook, Inc. (“Facebook”) owns all right, title and interest, including
* all intellectual property and other proprietary rights, in and to the React
* Native CustomComponents software (the “Software”). Subject to your
* compliance with these terms, you are hereby granted a non-exclusive,
* worldwide, royalty-free copyright license to (1) use and copy the Software;
* and (2) reproduce and distribute the Software as part of your own software
* (“Your Software”). Facebook reserves all rights not expressly granted to
* you in this license agreement.
*
* THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES (INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE) ARE DISCLAIMED.
* IN NO EVENT SHALL FACEBOOK OR ITS AFFILIATES, OFFICERS, DIRECTORS OR
* EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @providesModule NavigatorBreadcrumbNavigationBar
*/
'use strict';
var NavigatorBreadcrumbNavigationBarStyles = require('NavigatorBreadcrumbNavigationBarStyles');
var NavigatorNavigationBarStyles = require('NavigatorNavigationBarStyles');
var React = require('React');
var StaticContainer = require('StaticContainer.react');
var StyleSheet = require('StyleSheet');
var View = require('View');
var invariant = require('invariant');
var Interpolators = NavigatorBreadcrumbNavigationBarStyles.Interpolators;
var PropTypes = React.PropTypes;
/**
* Reusable props objects.
*/
var CRUMB_PROPS = Interpolators.map(function() {return {style: {}};});
var ICON_PROPS = Interpolators.map(function() {return {style: {}};});
var SEPARATOR_PROPS = Interpolators.map(function() {return {style: {}};});
var TITLE_PROPS = Interpolators.map(function() {return {style: {}};});
var RIGHT_BUTTON_PROPS = Interpolators.map(function() {return {style: {}};});
var navStatePresentedIndex = function(navState) {
if (navState.presentedIndex !== undefined) {
return navState.presentedIndex;
}
// TODO: rename `observedTopOfStack` to `presentedIndex` in `NavigatorIOS`
return navState.observedTopOfStack;
};
/**
* The first route is initially rendered using a different style than all
* future routes.
*
* @param {number} index Index of breadcrumb.
* @return {object} Style config for initial rendering of index.
*/
var initStyle = function(index, presentedIndex) {
return index === presentedIndex ? NavigatorBreadcrumbNavigationBarStyles.Center[index] :
index < presentedIndex ? NavigatorBreadcrumbNavigationBarStyles.Left[index] :
NavigatorBreadcrumbNavigationBarStyles.Right[index];
};
var NavigatorBreadcrumbNavigationBar = React.createClass({displayName: "NavigatorBreadcrumbNavigationBar",
propTypes: {
navigator: PropTypes.shape({
push: PropTypes.func,
pop: PropTypes.func,
replace: PropTypes.func,
popToRoute: PropTypes.func,
popToTop: PropTypes.func,
}),
routeMapper: PropTypes.shape({
rightContentForRoute: PropTypes.func,
titleContentForRoute: PropTypes.func,
iconForRoute: PropTypes.func,
}),
navState: React.PropTypes.shape({
routeStack: React.PropTypes.arrayOf(React.PropTypes.object),
idStack: React.PropTypes.arrayOf(React.PropTypes.number),
presentedIndex: React.PropTypes.number,
}),
style: View.propTypes.style,
},
statics: {
Styles: NavigatorBreadcrumbNavigationBarStyles,
},
_updateIndexProgress: function(progress, index, fromIndex, toIndex) {
var amount = toIndex > fromIndex ? progress : (1 - progress);
var oldDistToCenter = index - fromIndex;
var newDistToCenter = index - toIndex;
var interpolate;
invariant(
Interpolators[index],
'Cannot find breadcrumb interpolators for ' + index
);
if (oldDistToCenter > 0 && newDistToCenter === 0 ||
newDistToCenter > 0 && oldDistToCenter === 0) {
interpolate = Interpolators[index].RightToCenter;
} else if (oldDistToCenter < 0 && newDistToCenter === 0 ||
newDistToCenter < 0 && oldDistToCenter === 0) {
interpolate = Interpolators[index].CenterToLeft;
} else if (oldDistToCenter === newDistToCenter) {
interpolate = Interpolators[index].RightToCenter;
} else {
interpolate = Interpolators[index].RightToLeft;
}
if (interpolate.Crumb(CRUMB_PROPS[index].style, amount)) {
this.refs['crumb_' + index].setNativeProps(CRUMB_PROPS[index]);
}
if (interpolate.Icon(ICON_PROPS[index].style, amount)) {
this.refs['icon_' + index].setNativeProps(ICON_PROPS[index]);
}
if (interpolate.Separator(SEPARATOR_PROPS[index].style, amount)) {
this.refs['separator_' + index].setNativeProps(SEPARATOR_PROPS[index]);
}
if (interpolate.Title(TITLE_PROPS[index].style, amount)) {
this.refs['title_' + index].setNativeProps(TITLE_PROPS[index]);
}
var right = this.refs['right_' + index];
if (right &&
interpolate.RightItem(RIGHT_BUTTON_PROPS[index].style, amount)) {
right.setNativeProps(RIGHT_BUTTON_PROPS[index]);
}
},
updateProgress: function(progress, fromIndex, toIndex) {
var max = Math.max(fromIndex, toIndex);
var min = Math.min(fromIndex, toIndex);
for (var index = min; index <= max; index++) {
this._updateIndexProgress(progress, index, fromIndex, toIndex);
}
},
onAnimationStart: function(fromIndex, toIndex) {
var max = Math.max(fromIndex, toIndex);
var min = Math.min(fromIndex, toIndex);
for (var index = min; index <= max; index++) {
this._setRenderViewsToHardwareTextureAndroid(index, true);
}
},
onAnimationEnd: function() {
var max = this.props.navState.routeStack.length - 1;
for (var index = 0; index <= max; index++) {
this._setRenderViewsToHardwareTextureAndroid(index, false);
}
},
_setRenderViewsToHardwareTextureAndroid: function(index, renderToHardwareTexture) {
var props = {
renderToHardwareTextureAndroid: renderToHardwareTexture,
};
this.refs['crumb_' + index].setNativeProps(props);
this.refs['icon_' + index].setNativeProps(props);
this.refs['separator_' + index].setNativeProps(props);
this.refs['title_' + index].setNativeProps(props);
var right = this.refs['right_' + index];
if (right) {
right.setNativeProps(props);
}
},
render: function() {
var navState = this.props.navState;
var icons = navState && navState.routeStack.map(this._renderOrReturnBreadcrumb);
var titles = navState.routeStack.map(this._renderOrReturnTitle);
var buttons = navState.routeStack.map(this._renderOrReturnRightButton);
return (
React.createElement(View, {style: [styles.breadCrumbContainer, this.props.style]},
titles,
icons,
buttons
)
);
},
_renderOrReturnBreadcrumb: function(route, index) {
var uid = this.props.navState.idStack[index];
var navBarRouteMapper = this.props.routeMapper;
var navOps = this.props.navigator;
var alreadyRendered = this.refs['crumbContainer' + uid];
if (alreadyRendered) {
// Don't bother re-calculating the children
return (
React.createElement(StaticContainer, {
ref: 'crumbContainer' + uid,
key: 'crumbContainer' + uid,
shouldUpdate: false}
)
);
}
var firstStyles = initStyle(index, navStatePresentedIndex(this.props.navState));
return (
React.createElement(StaticContainer, {
ref: 'crumbContainer' + uid,
key: 'crumbContainer' + uid,
shouldUpdate: false},
React.createElement(View, {ref: 'crumb_' + index, style: firstStyles.Crumb},
React.createElement(View, {ref: 'icon_' + index, style: firstStyles.Icon},
navBarRouteMapper.iconForRoute(route, navOps)
),
React.createElement(View, {ref: 'separator_' + index, style: firstStyles.Separator},
navBarRouteMapper.separatorForRoute(route, navOps)
)
)
)
);
},
_renderOrReturnTitle: function(route, index) {
var navState = this.props.navState;
var uid = navState.idStack[index];
var alreadyRendered = this.refs['titleContainer' + uid];
if (alreadyRendered) {
// Don't bother re-calculating the children
return (
React.createElement(StaticContainer, {
ref: 'titleContainer' + uid,
key: 'titleContainer' + uid,
shouldUpdate: false}
)
);
}
var navBarRouteMapper = this.props.routeMapper;
var titleContent = navBarRouteMapper.titleContentForRoute(
navState.routeStack[index],
this.props.navigator
);
var firstStyles = initStyle(index, navStatePresentedIndex(this.props.navState));
return (
React.createElement(StaticContainer, {
ref: 'titleContainer' + uid,
key: 'titleContainer' + uid,
shouldUpdate: false},
React.createElement(View, {ref: 'title_' + index, style: firstStyles.Title},
titleContent
)
)
);
},
_renderOrReturnRightButton: function(route, index) {
var navState = this.props.navState;
var navBarRouteMapper = this.props.routeMapper;
var uid = navState.idStack[index];
var alreadyRendered = this.refs['rightContainer' + uid];
if (alreadyRendered) {
// Don't bother re-calculating the children
return (
React.createElement(StaticContainer, {
ref: 'rightContainer' + uid,
key: 'rightContainer' + uid,
shouldUpdate: false}
)
);
}
var rightContent = navBarRouteMapper.rightContentForRoute(
navState.routeStack[index],
this.props.navigator
);
if (!rightContent) {
return null;
}
var firstStyles = initStyle(index, navStatePresentedIndex(this.props.navState));
return (
React.createElement(StaticContainer, {
ref: 'rightContainer' + uid,
key: 'rightContainer' + uid,
shouldUpdate: false},
React.createElement(View, {ref: 'right_' + index, style: firstStyles.RightItem},
rightContent
)
)
);
},
});
var styles = StyleSheet.create({
breadCrumbContainer: {
overflow: 'hidden',
position: 'absolute',
height: NavigatorNavigationBarStyles.General.TotalNavHeight,
top: 0,
left: 0,
right: 0,
},
});
module.exports = NavigatorBreadcrumbNavigationBar;
});
__d('NavigatorBreadcrumbNavigationBarStyles',["Dimensions","NavigatorNavigationBarStyles","buildStyleInterpolator","merge"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015, Facebook, Inc. All rights reserved.
*
* Facebook, Inc. (“Facebook”) owns all right, title and interest, including
* all intellectual property and other proprietary rights, in and to the React
* Native CustomComponents software (the “Software”). Subject to your
* compliance with these terms, you are hereby granted a non-exclusive,
* worldwide, royalty-free copyright license to (1) use and copy the Software;
* and (2) reproduce and distribute the Software as part of your own software
* (“Your Software”). Facebook reserves all rights not expressly granted to
* you in this license agreement.
*
* THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES (INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE) ARE DISCLAIMED.
* IN NO EVENT SHALL FACEBOOK OR ITS AFFILIATES, OFFICERS, DIRECTORS OR
* EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @providesModule NavigatorBreadcrumbNavigationBarStyles
*/
'use strict';
var Dimensions = require('Dimensions');
var NavigatorNavigationBarStyles = require('NavigatorNavigationBarStyles');
var buildStyleInterpolator = require('buildStyleInterpolator');
var merge = require('merge');
var SCREEN_WIDTH = Dimensions.get('window').width;
var STATUS_BAR_HEIGHT = NavigatorNavigationBarStyles.General.StatusBarHeight;
var NAV_BAR_HEIGHT = NavigatorNavigationBarStyles.General.NavBarHeight;
var SPACING = 4;
var ICON_WIDTH = 40;
var SEPARATOR_WIDTH = 9;
var CRUMB_WIDTH = ICON_WIDTH + SEPARATOR_WIDTH;
var OPACITY_RATIO = 100;
var ICON_INACTIVE_OPACITY = 0.6;
var MAX_BREADCRUMBS = 10;
var CRUMB_BASE = {
position: 'absolute',
flexDirection: 'row',
top: STATUS_BAR_HEIGHT,
width: CRUMB_WIDTH,
height: NAV_BAR_HEIGHT,
backgroundColor: 'transparent',
};
var ICON_BASE = {
width: ICON_WIDTH,
height: NAV_BAR_HEIGHT,
};
var SEPARATOR_BASE = {
width: SEPARATOR_WIDTH,
height: NAV_BAR_HEIGHT,
};
var TITLE_BASE = {
position: 'absolute',
top: STATUS_BAR_HEIGHT,
height: NAV_BAR_HEIGHT,
backgroundColor: 'transparent',
};
// For first title styles, make sure first title is centered
var FIRST_TITLE_BASE = merge(TITLE_BASE, {
left: 0,
right: 0,
alignItems: 'center',
height: NAV_BAR_HEIGHT,
});
var RIGHT_BUTTON_BASE = {
position: 'absolute',
top: STATUS_BAR_HEIGHT,
right: SPACING,
overflow: 'hidden',
opacity: 1,
height: NAV_BAR_HEIGHT,
backgroundColor: 'transparent',
};
/**
* Precompute crumb styles so that they don't need to be recomputed on every
* interaction.
*/
var LEFT = [];
var CENTER = [];
var RIGHT = [];
for (var i = 0; i < MAX_BREADCRUMBS; i++) {
var crumbLeft = CRUMB_WIDTH * i + SPACING;
LEFT[i] = {
Crumb: merge(CRUMB_BASE, { left: crumbLeft }),
Icon: merge(ICON_BASE, { opacity: ICON_INACTIVE_OPACITY }),
Separator: merge(SEPARATOR_BASE, { opacity: 1 }),
Title: merge(TITLE_BASE, { left: crumbLeft, opacity: 0 }),
RightItem: merge(RIGHT_BUTTON_BASE, { opacity: 0 }),
};
CENTER[i] = {
Crumb: merge(CRUMB_BASE, { left: crumbLeft }),
Icon: merge(ICON_BASE, { opacity: 1 }),
Separator: merge(SEPARATOR_BASE, { opacity: 0 }),
Title: merge(TITLE_BASE, {
left: crumbLeft + ICON_WIDTH,
opacity: 1,
}),
RightItem: merge(RIGHT_BUTTON_BASE, { opacity: 1 }),
};
var crumbRight = SCREEN_WIDTH - 100;
RIGHT[i] = {
Crumb: merge(CRUMB_BASE, { left: crumbRight}),
Icon: merge(ICON_BASE, { opacity: 0 }),
Separator: merge(SEPARATOR_BASE, { opacity: 0 }),
Title: merge(TITLE_BASE, {
left: crumbRight + ICON_WIDTH,
opacity: 0,
}),
RightItem: merge(RIGHT_BUTTON_BASE, { opacity: 0 }),
};
}
// Special case the CENTER state of the first scene.
CENTER[0] = {
Crumb: merge(CRUMB_BASE, {left: SCREEN_WIDTH / 4}),
Icon: merge(ICON_BASE, {opacity: 0}),
Separator: merge(SEPARATOR_BASE, {opacity: 0}),
Title: merge(FIRST_TITLE_BASE, {opacity: 1}),
RightItem: CENTER[0].RightItem,
};
LEFT[0].Title = merge(FIRST_TITLE_BASE, {left: - SCREEN_WIDTH / 4, opacity: 0});
RIGHT[0].Title = merge(FIRST_TITLE_BASE, {opacity: 0});
var buildIndexSceneInterpolator = function(startStyles, endStyles) {
return {
Crumb: buildStyleInterpolator({
left: {
type: 'linear',
from: startStyles.Crumb.left,
to: endStyles.Crumb.left,
min: 0,
max: 1,
extrapolate: true,
},
}),
Icon: buildStyleInterpolator({
opacity: {
type: 'linear',
from: startStyles.Icon.opacity,
to: endStyles.Icon.opacity,
min: 0,
max: 1,
},
}),
Separator: buildStyleInterpolator({
opacity: {
type: 'linear',
from: startStyles.Separator.opacity,
to: endStyles.Separator.opacity,
min: 0,
max: 1,
},
}),
Title: buildStyleInterpolator({
opacity: {
type: 'linear',
from: startStyles.Title.opacity,
to: endStyles.Title.opacity,
min: 0,
max: 1,
},
left: {
type: 'linear',
from: startStyles.Title.left,
to: endStyles.Title.left,
min: 0,
max: 1,
extrapolate: true,
},
}),
RightItem: buildStyleInterpolator({
opacity: {
type: 'linear',
from: startStyles.RightItem.opacity,
to: endStyles.RightItem.opacity,
min: 0,
max: 1,
round: OPACITY_RATIO,
},
}),
};
};
var Interpolators = CENTER.map(function(_, ii) {
return {
// Animating *into* the center stage from the right
RightToCenter: buildIndexSceneInterpolator(RIGHT[ii], CENTER[ii]),
// Animating out of the center stage, to the left
CenterToLeft: buildIndexSceneInterpolator(CENTER[ii], LEFT[ii]),
// Both stages (animating *past* the center stage)
RightToLeft: buildIndexSceneInterpolator(RIGHT[ii], LEFT[ii]),
};
});
/**
* Contains constants that are used in constructing both `StyleSheet`s and
* inline styles during transitions.
*/
module.exports = {
Interpolators:Interpolators,
Left: LEFT,
Center: CENTER,
Right: RIGHT,
IconWidth: ICON_WIDTH,
IconHeight: NAV_BAR_HEIGHT,
SeparatorWidth: SEPARATOR_WIDTH,
SeparatorHeight: NAV_BAR_HEIGHT,
};
});
__d('NavigatorNavigationBarStyles',["Dimensions","buildStyleInterpolator","merge"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright (c) 2015, Facebook, Inc. All rights reserved.
*
* Facebook, Inc. (“Facebook”) owns all right, title and interest, including
* all intellectual property and other proprietary rights, in and to the React
* Native CustomComponents software (the “Software”). Subject to your
* compliance with these terms, you are hereby granted a non-exclusive,
* worldwide, royalty-free copyright license to (1) use and copy the Software;
* and (2) reproduce and distribute the Software as part of your own software
* (“Your Software”). Facebook reserves all rights not expressly granted to
* you in this license agreement.
*
* THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES (INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE) ARE DISCLAIMED.
* IN NO EVENT SHALL FACEBOOK OR ITS AFFILIATES, OFFICERS, DIRECTORS OR
* EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @providesModule NavigatorNavigationBarStyles
*/
'use strict';
var Dimensions = require('Dimensions');
var buildStyleInterpolator = require('buildStyleInterpolator');
var merge = require('merge');
var SCREEN_WIDTH = Dimensions.get('window').width;
var NAV_BAR_HEIGHT = 44;
var STATUS_BAR_HEIGHT = 20;
var NAV_HEIGHT = NAV_BAR_HEIGHT + STATUS_BAR_HEIGHT;
var BASE_STYLES = {
Title: {
position: 'absolute',
top: STATUS_BAR_HEIGHT,
left: 0,
alignItems: 'center',
width: SCREEN_WIDTH,
height: NAV_BAR_HEIGHT,
backgroundColor: 'transparent',
},
LeftButton: {
position: 'absolute',
top: STATUS_BAR_HEIGHT,
left: 0,
overflow: 'hidden',
opacity: 1,
width: SCREEN_WIDTH / 3,
height: NAV_BAR_HEIGHT,
backgroundColor: 'transparent',
},
RightButton: {
position: 'absolute',
top: STATUS_BAR_HEIGHT,
left: 2 * SCREEN_WIDTH / 3,
overflow: 'hidden',
opacity: 1,
alignItems: 'flex-end',
width: SCREEN_WIDTH / 3,
height: NAV_BAR_HEIGHT,
backgroundColor: 'transparent',
},
};
// There are 3 stages: left, center, right. All previous navigation
// items are in the left stage. The current navigation item is in the
// center stage. All upcoming navigation items are in the right stage.
// Another way to think of the stages is in terms of transitions. When
// we move forward in the navigation stack, we perform a
// right-to-center transition on the new navigation item and a
// center-to-left transition on the current navigation item.
var Stages = {
Left: {
Title: merge(BASE_STYLES.Title, { left: - SCREEN_WIDTH / 2, opacity: 0 }),
LeftButton: merge(BASE_STYLES.LeftButton, { left: - SCREEN_WIDTH / 3, opacity: 1 }),
RightButton: merge(BASE_STYLES.RightButton, { left: SCREEN_WIDTH / 3, opacity: 0 }),
},
Center: {
Title: merge(BASE_STYLES.Title, { left: 0, opacity: 1 }),
LeftButton: merge(BASE_STYLES.LeftButton, { left: 0, opacity: 1 }),
RightButton: merge(BASE_STYLES.RightButton, { left: 2 * SCREEN_WIDTH / 3 - 0, opacity: 1 }),
},
Right: {
Title: merge(BASE_STYLES.Title, { left: SCREEN_WIDTH / 2, opacity: 0 }),
LeftButton: merge(BASE_STYLES.LeftButton, { left: 0, opacity: 0 }),
RightButton: merge(BASE_STYLES.RightButton, { left: SCREEN_WIDTH, opacity: 0 }),
},
};
var opacityRatio = 100;
function buildSceneInterpolators(startStyles, endStyles) {
return {
Title: buildStyleInterpolator({
opacity: {
type: 'linear',
from: startStyles.Title.opacity,
to: endStyles.Title.opacity,
min: 0,
max: 1,
},
left: {
type: 'linear',
from: startStyles.Title.left,
to: endStyles.Title.left,
min: 0,
max: 1,
extrapolate: true,
},
}),
LeftButton: buildStyleInterpolator({
opacity: {
type: 'linear',
from: startStyles.LeftButton.opacity,
to: endStyles.LeftButton.opacity,
min: 0,
max: 1,
round: opacityRatio,
},
left: {
type: 'linear',
from: startStyles.LeftButton.left,
to: endStyles.LeftButton.left,
min: 0,
max: 1,
},
}),
RightButton: buildStyleInterpolator({
opacity: {
type: 'linear',
from: startStyles.RightButton.opacity,
to: endStyles.RightButton.opacity,
min: 0,
max: 1,
round: opacityRatio,
},
left: {
type: 'linear',
from: startStyles.RightButton.left,
to: endStyles.RightButton.left,
min: 0,
max: 1,
extrapolate: true,
},
}),
};
}
var Interpolators = {
// Animating *into* the center stage from the right
RightToCenter: buildSceneInterpolators(Stages.Right, Stages.Center),
// Animating out of the center stage, to the left
CenterToLeft: buildSceneInterpolators(Stages.Center, Stages.Left),
// Both stages (animating *past* the center stage)
RightToLeft: buildSceneInterpolators(Stages.Right, Stages.Left),
};
module.exports = {
General: {
NavBarHeight: NAV_BAR_HEIGHT,
StatusBarHeight: STATUS_BAR_HEIGHT,
TotalNavHeight: NAV_HEIGHT,
},
Interpolators:Interpolators,
Stages:Stages,
};
});
__d('buildStyleInterpolator',["keyOf"],function(global, require, requireDynamic, requireLazy, module, exports) { /**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule buildStyleInterpolator
*/
/**
* Cannot "use strict" because we must use eval in this file.
*/
var keyOf = require('keyOf');
var X_DIM = keyOf({x: null});
var Y_DIM = keyOf({y: null});
var Z_DIM = keyOf({z: null});
var W_DIM = keyOf({w: null});
var TRANSFORM_ROTATE_NAME = keyOf({transformRotateRadians: null});
var ShouldAllocateReusableOperationVars = {
transformRotateRadians: true,
transformScale: true,
transformTranslate: true,
};
var InitialOperationField = {
transformRotateRadians: [0, 0, 0, 1],
transformTranslate: [0, 0, 0],
transformScale: [1, 1, 1],
};
/**
* Creates a highly specialized animation function that may be evaluated every
* frame. For example:
*
* var ToTheLeft = {
* opacity: {
* from: 1,
* to: 0.7,
* min: 0,
* max: 1,
* type: 'linear',
* extrapolate: false,
* round: 100,
* },
* left: {
* from: 0,
* to: -SCREEN_WIDTH * 0.3,
* min: 0,
* max: 1,
* type: 'linear',
* extrapolate: true,
* round: PixelRatio.get(),
* },
* };
*
* var toTheLeft = buildStyleInterpolator(ToTheLeft);
*
* Would returns a specialized function of the form:
*
* function(result, value) {
* var didChange = false;
* var nextScalarVal;
* var ratio;
* ratio = (value - 0) / 1;
* ratio = ratio > 1 ? 1 : (ratio < 0 ? 0 : ratio);
* nextScalarVal = Math.round(100 * (1 * (1 - ratio) + 0.7 * ratio)) / 100;
* if (!didChange) {
* var prevVal = result.opacity;
* result.opacity = nextScalarVal;
* didChange = didChange || (nextScalarVal !== prevVal);
* } else {
* result.opacity = nextScalarVal;
* }
* ratio = (value - 0) / 1;
* nextScalarVal = Math.round(2 * (0 * (1 - ratio) + -30 * ratio)) / 2;
* if (!didChange) {
* var prevVal = result.left;
* result.left = nextScalarVal;
* didChange = didChange || (nextScalarVal !== prevVal);
* } else {
* result.left = nextScalarVal;
* }
* return didChange;
* }
*/
var ARGUMENT_NAMES_RE = /([^\s,]+)/g;
/**
* This is obviously a huge hack. Proper tooling would allow actual inlining.
* This only works in a few limited cases (where there is no function return
* value, and the function operates mutatively on parameters).
*
* Example:
*
*
* var inlineMe(a, b) {
* a = b + b;
* };
*
* inline(inlineMe, ['hi', 'bye']); // "hi = bye + bye;"
*
* @param {function} func Any simple function whos arguments can be replaced via a regex.
* @param {array<string>} replaceWithArgs Corresponding names of variables
* within an environment, to replace `func` args with.
* @return {string} Resulting function body string.
*/
var inline = function(func, replaceWithArgs) {
var fnStr = func.toString();
var parameterNames = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')'))
.match(ARGUMENT_NAMES_RE) ||
[];
var replaceRegexStr = parameterNames.map(function(paramName) {
return '\\b' + paramName + '\\b';
}).join('|');
var replaceRegex = new RegExp(replaceRegexStr, 'g');
var fnBody = fnStr.substring(fnStr.indexOf('{') + 1, fnStr.lastIndexOf('}') - 1);
var newFnBody = fnBody.replace(replaceRegex, function(parameterName) {
var indexInParameterNames = parameterNames.indexOf(parameterName);
var replacementName = replaceWithArgs[indexInParameterNames];
return replacementName;
});
return newFnBody.split('\n');
};
/**
* Simply a convenient way to inline functions using the function's toString
* method.
*/
var MatrixOps = {
unroll: function(matVar, m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15) {
m0 = matVar[0];
m1 = matVar[1];
m2 = matVar[2];
m3 = matVar[3];
m4 = matVar[4];
m5 = matVar[5];
m6 = matVar[6];
m7 = matVar[7];
m8 = matVar[8];
m9 = matVar[9];
m10 = matVar[10];
m11 = matVar[11];
m12 = matVar[12];
m13 = matVar[13];
m14 = matVar[14];
m15 = matVar[15];
},
matrixDiffers: function(retVar, matVar, m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15) {
retVar = retVar ||
m0 !== matVar[0] ||
m1 !== matVar[1] ||
m2 !== matVar[2] ||
m3 !== matVar[3] ||
m4 !== matVar[4] ||
m5 !== matVar[5] ||
m6 !== matVar[6] ||
m7 !== matVar[7] ||
m8 !== matVar[8] ||
m9 !== matVar[9] ||
m10 !== matVar[10] ||
m11 !== matVar[11] ||
m12 !== matVar[12] ||
m13 !== matVar[13] ||
m14 !== matVar[14] ||
m15 !== matVar[15];
},
transformScale: function(matVar, opVar) {
// Scaling matVar by opVar
var x = opVar[0];
var y = opVar[1];
var z = opVar[2];
matVar[0] = matVar[0] * x;
matVar[1] = matVar[1] * x;
matVar[2] = matVar[2] * x;
matVar[3] = matVar[3] * x;
matVar[4] = matVar[4] * y;
matVar[5] = matVar[5] * y;
matVar[6] = matVar[6] * y;
matVar[7] = matVar[7] * y;
matVar[8] = matVar[8] * z;
matVar[9] = matVar[9] * z;
matVar[10] = matVar[10] * z;
matVar[11] = matVar[11] * z;
matVar[12] = matVar[12];
matVar[13] = matVar[13];
matVar[14] = matVar[14];
matVar[15] = matVar[15];
},
/**
* All of these matrix transforms are not general purpose utilities, and are
* only suitable for being inlined for the use of building up interpolators.
*/
transformTranslate: function(matVar, opVar) {
// Translating matVar by opVar
var x = opVar[0];
var y = opVar[1];
var z = opVar[2];
matVar[12] = matVar[0] * x + matVar[4] * y + matVar[8] * z + matVar[12];
matVar[13] = matVar[1] * x + matVar[5] * y + matVar[9] * z + matVar[13];
matVar[14] = matVar[2] * x + matVar[6] * y + matVar[10] * z + matVar[14];
matVar[15] = matVar[3] * x + matVar[7] * y + matVar[11] * z + matVar[15];
},
/**
* @param {array} matVar Both the input, and the output matrix.
* @param {quaternion specification} q Four element array describing rotation.
*/
transformRotateRadians: function(matVar, q) {
// Rotating matVar by q
var xQuat = q[0], yQuat = q[1], zQuat = q[2], wQuat = q[3];
var x2Quat = xQuat + xQuat;
var y2Quat = yQuat + yQuat;
var z2Quat = zQuat + zQuat;
var xxQuat = xQuat * x2Quat;
var xyQuat = xQuat * y2Quat;
var xzQuat = xQuat * z2Quat;
var yyQuat = yQuat * y2Quat;
var yzQuat = yQuat * z2Quat;
var zzQuat = zQuat * z2Quat;
var wxQuat = wQuat * x2Quat;
var wyQuat = wQuat * y2Quat;
var wzQuat = wQuat * z2Quat;
// Step 1: Inlines the construction of a quaternion matrix (`quatMat`)
var quatMat0 = 1 - (yyQuat + zzQuat);
var quatMat1 = xyQuat + wzQuat;
var quatMat2 = xzQuat - wyQuat;
var quatMat4 = xyQuat - wzQuat;
var quatMat5 = 1 - (xxQuat + zzQuat);
var quatMat6 = yzQuat + wxQuat;
var quatMat8 = xzQuat + wyQuat;
var quatMat9 = yzQuat - wxQuat;
var quatMat10 = 1 - (xxQuat + yyQuat);
// quatMat3/7/11/12/13/14 = 0, quatMat15 = 1
// Step 2: Inlines multiplication, takes advantage of constant quatMat cells
var a00 = matVar[0];
var a01 = matVar[1];
var a02 = matVar[2];
var a03 = matVar[3];
var a10 = matVar[4];
var a11 = matVar[5];
var a12 = matVar[6];
var a13 = matVar[7];
var a20 = matVar[8];
var a21 = matVar[9];
var a22 = matVar[10];
var a23 = matVar[11];
var b0 = quatMat0, b1 = quatMat1, b2 = quatMat2;
matVar[0] = b0 * a00 + b1 * a10 + b2 * a20;
matVar[1] = b0 * a01 + b1 * a11 + b2 * a21;
matVar[2] = b0 * a02 + b1 * a12 + b2 * a22;
matVar[3] = b0 * a03 + b1 * a13 + b2 * a23;
b0 = quatMat4; b1 = quatMat5; b2 = quatMat6;
matVar[4] = b0 * a00 + b1 * a10 + b2 * a20;
matVar[5] = b0 * a01 + b1 * a11 + b2 * a21;
matVar[6] = b0 * a02 + b1 * a12 + b2 * a22;
matVar[7] = b0 * a03 + b1 * a13 + b2 * a23;
b0 = quatMat8; b1 = quatMat9; b2 = quatMat10;
matVar[8] = b0 * a00 + b1 * a10 + b2 * a20;
matVar[9] = b0 * a01 + b1 * a11 + b2 * a21;
matVar[10] = b0 * a02 + b1 * a12 + b2 * a22;
matVar[11] = b0 * a03 + b1 * a13 + b2 * a23;
}
};
// Optimized version of general operation applications that can be used when
// the target matrix is known to be the identity matrix.
var MatrixOpsInitial = {
transformScale: function(matVar, opVar) {
// Scaling matVar known to be identity by opVar
matVar[0] = opVar[0];
matVar[1] = 0;
matVar[2] = 0;
matVar[3] = 0;
matVar[4] = 0;
matVar[5] = opVar[1];
matVar[6] = 0;
matVar[7] = 0;
matVar[8] = 0;
matVar[9] = 0;
matVar[10] = opVar[2];
matVar[11] = 0;
matVar[12] = 0;
matVar[13] = 0;
matVar[14] = 0;
matVar[15] = 1;
},
transformTranslate: function(matVar, opVar) {
// Translating matVar known to be identity by opVar';
matVar[0] = 1;
matVar[1] = 0;
matVar[2] = 0;
matVar[3] = 0;
matVar[4] = 0;
matVar[5] = 1;
matVar[6] = 0;
matVar[7] = 0;
matVar[8] = 0;
matVar[9] = 0;
matVar[10] = 1;
matVar[11] = 0;
matVar[12] = opVar[0];
matVar[13] = opVar[1];
matVar[14] = opVar[2];
matVar[15] = 1;
},
/**
* @param {array} matVar Both the input, and the output matrix - assumed to be
* identity.
* @param {quaternion specification} q Four element array describing rotation.
*/
transformRotateRadians: function(matVar, q) {
// Rotating matVar which is known to be identity by q
var xQuat = q[0], yQuat = q[1], zQuat = q[2], wQuat = q[3];
var x2Quat = xQuat + xQuat;
var y2Quat = yQuat + yQuat;
var z2Quat = zQuat + zQuat;
var xxQuat = xQuat * x2Quat;
var xyQuat = xQuat * y2Quat;
var xzQuat = xQuat * z2Quat;
var yyQuat = yQuat * y2Quat;
var yzQuat = yQuat * z2Quat;
var zzQuat = zQuat * z2Quat;
var wxQuat = wQuat * x2Quat;
var wyQuat = wQuat * y2Quat;
var wzQuat = wQuat * z2Quat;
// Step 1: Inlines the construction of a quaternion matrix (`quatMat`)
var quatMat0 = 1 - (yyQuat + zzQuat);
var quatMat1 = xyQuat + wzQuat;
var quatMat2 = xzQuat - wyQuat;
var quatMat4 = xyQuat - wzQuat;
var quatMat5 = 1 - (xxQuat + zzQuat);
var quatMat6 = yzQuat + wxQuat;
var quatMat8 = xzQuat + wyQuat;
var quatMat9 = yzQuat - wxQuat;
var quatMat10 = 1 - (xxQuat + yyQuat);
// quatMat3/7/11/12/13/14 = 0, quatMat15 = 1
// Step 2: Inlines the multiplication with identity matrix.
var b0 = quatMat0, b1 = quatMat1, b2 = quatMat2;
matVar[0] = b0;
matVar[1] = b1;
matVar[2] = b2;
matVar[3] = 0;
b0 = quatMat4; b1 = quatMat5; b2 = quatMat6;
matVar[4] = b0;
matVar[5] = b1;
matVar[6] = b2;
matVar[7] = 0;
b0 = quatMat8; b1 = quatMat9; b2 = quatMat10;
matVar[8] = b0;
matVar[9] = b1;
matVar[10] = b2;
matVar[11] = 0;
matVar[12] = 0;
matVar[13] = 0;
matVar[14] = 0;
matVar[15] = 1;
}
};
var setNextValAndDetectChange = function(name, tmpVarName) {
return (
' if (!didChange) {\n' +
' var prevVal = result.' + name +';\n' +
' result.' + name + ' = ' + tmpVarName + ';\n' +
' didChange = didChange || (' + tmpVarName + ' !== prevVal);\n' +
' } else {\n' +
' result.' + name + ' = ' + tmpVarName + ';\n' +
' }\n'
);
};
var computeNextValLinear = function(anim, from, to, tmpVarName) {
var hasRoundRatio = 'round' in anim;
var roundRatio = anim.round;
var fn = ' ratio = (value - ' + anim.min + ') / ' + (anim.max - anim.min) + ';\n';
if (!anim.extrapolate) {
fn += ' ratio = ratio > 1 ? 1 : (ratio < 0 ? 0 : ratio);\n';
}
var roundOpen = (hasRoundRatio ? 'Math.round(' + roundRatio + ' * ' : '' );
var roundClose = (hasRoundRatio ? ') / ' + roundRatio : '' );
fn +=
' ' + tmpVarName + ' = ' +
roundOpen +
'(' + from + ' * (1 - ratio) + ' + to + ' * ratio)' +
roundClose + ';\n';
return fn;
};
var computeNextValLinearScalar = function(anim) {
return computeNextValLinear(anim, anim.from, anim.to, 'nextScalarVal');
};
var computeNextValConstant = function(anim) {
var constantExpression = JSON.stringify(anim.value);
return ' nextScalarVal = ' + constantExpression + ';\n';
};
var computeNextValStep = function(anim) {
return (
' nextScalarVal = value >= ' +
(anim.threshold + ' ? ' + anim.to + ' : ' + anim.from) + ';\n'
);
};
var computeNextValIdentity = function(anim) {
return ' nextScalarVal = value;\n';
};
var operationVar = function(name) {
return name + 'ReuseOp';
};
var createReusableOperationVars = function(anims) {
var ret = '';
for (var name in anims) {
if (ShouldAllocateReusableOperationVars[name]) {
ret += 'var ' + operationVar(name) + ' = [];\n';
}
}
return ret;
};
var newlines = function(statements) {
return '\n' + statements.join('\n') + '\n';
};
/**
* @param {Animation} anim Configuration entry.
* @param {key} dimension Key to examine in `from`/`to`.
* @param {number} index Field in operationVar to set.
* @return {string} Code that sets the operation variable's field.
*/
var computeNextMatrixOperationField = function(anim, name, dimension, index) {
var fieldAccess = operationVar(name) + '[' + index + ']';
if (anim.from[dimension] !== undefined && anim.to[dimension] !== undefined) {
return ' ' + anim.from[dimension] !== anim.to[dimension] ?
computeNextValL
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment