mk-react-images
Version:
A simple, responsive lightbox component for displaying an array of images with React.js
1,427 lines (1,257 loc) • 966 kB
JavaScript
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _inlineStylePrefixerStatic = require('inline-style-prefixer/static');
var _inlineStylePrefixerStatic2 = _interopRequireDefault(_inlineStylePrefixerStatic);
var _util = require('./util');
/**
* Generate CSS for a selector and some styles.
*
* This function handles the media queries, pseudo selectors, and descendant
* styles that can be used in aphrodite styles.
*
* @param {string} selector: A base CSS selector for the styles to be generated
* with.
* @param {Object} styleTypes: A list of properties of the return type of
* StyleSheet.create, e.g. [styles.red, styles.blue].
* @param stringHandlers: See `generateCSSRuleset`
* @param useImportant: See `generateCSSRuleset`
*
* To actually generate the CSS special-construct-less styles are passed to
* `generateCSSRuleset`.
*
* For instance, a call to
*
* generateCSSInner(".foo", {
* color: "red",
* "@media screen": {
* height: 20,
* ":hover": {
* backgroundColor: "black"
* }
* },
* ":active": {
* fontWeight: "bold",
* ">>bar": {
* _names: { "foo_bar": true },
* height: 10,
* }
* }
* });
*
* will make 5 calls to `generateCSSRuleset`:
*
* generateCSSRuleset(".foo", { color: "red" }, ...)
* generateCSSRuleset(".foo:active", { fontWeight: "bold" }, ...)
* generateCSSRuleset(".foo:active .foo_bar", { height: 10 }, ...)
* // These 2 will be wrapped in @media screen {}
* generateCSSRuleset(".foo", { height: 20 }, ...)
* generateCSSRuleset(".foo:hover", { backgroundColor: "black" }, ...)
*/
var generateCSS = function generateCSS(selector, styleTypes, stringHandlers, useImportant) {
var merged = styleTypes.reduce(_util.recursiveMerge);
var declarations = {};
var mediaQueries = {};
var pseudoStyles = {};
Object.keys(merged).forEach(function (key) {
if (key[0] === ':') {
pseudoStyles[key] = merged[key];
} else if (key[0] === '@') {
mediaQueries[key] = merged[key];
} else {
declarations[key] = merged[key];
}
});
return generateCSSRuleset(selector, declarations, stringHandlers, useImportant) + Object.keys(pseudoStyles).map(function (pseudoSelector) {
return generateCSSRuleset(selector + pseudoSelector, pseudoStyles[pseudoSelector], stringHandlers, useImportant);
}).join("") + Object.keys(mediaQueries).map(function (mediaQuery) {
var ruleset = generateCSS(selector, [mediaQueries[mediaQuery]], stringHandlers, useImportant);
return mediaQuery + '{' + ruleset + '}';
}).join("");
};
exports.generateCSS = generateCSS;
/**
* Helper method of generateCSSRuleset to facilitate custom handling of certain
* CSS properties. Used for e.g. font families.
*
* See generateCSSRuleset for usage and documentation of paramater types.
*/
var runStringHandlers = function runStringHandlers(declarations, stringHandlers) {
var result = {};
Object.keys(declarations).forEach(function (key) {
// If a handler exists for this particular key, let it interpret
// that value first before continuing
if (stringHandlers && stringHandlers.hasOwnProperty(key)) {
result[key] = stringHandlers[key](declarations[key]);
} else {
result[key] = declarations[key];
}
});
return result;
};
/**
* Generate a CSS ruleset with the selector and containing the declarations.
*
* This function assumes that the given declarations don't contain any special
* children (such as media queries, pseudo-selectors, or descendant styles).
*
* Note that this method does not deal with nesting used for e.g.
* psuedo-selectors or media queries. That responsibility is left to the
* `generateCSS` function.
*
* @param {string} selector: the selector associated with the ruleset
* @param {Object} declarations: a map from camelCased CSS property name to CSS
* property value.
* @param {Object.<string, function>} stringHandlers: a map from camelCased CSS
* property name to a function which will map the given value to the value
* that is output.
* @param {bool} useImportant: A boolean saying whether to append "!important"
* to each of the CSS declarations.
* @returns {string} A string of raw CSS.
*
* Examples:
*
* generateCSSRuleset(".blah", { color: "red" })
* -> ".blah{color: red !important;}"
* generateCSSRuleset(".blah", { color: "red" }, {}, false)
* -> ".blah{color: red}"
* generateCSSRuleset(".blah", { color: "red" }, {color: c => c.toUpperCase})
* -> ".blah{color: RED}"
* generateCSSRuleset(".blah:hover", { color: "red" })
* -> ".blah:hover{color: red}"
*/
var generateCSSRuleset = function generateCSSRuleset(selector, declarations, stringHandlers, useImportant) {
var handledDeclarations = runStringHandlers(declarations, stringHandlers);
var prefixedDeclarations = (0, _inlineStylePrefixerStatic2['default'])(handledDeclarations);
var prefixedRules = (0, _util.flatten)((0, _util.objectToPairs)(prefixedDeclarations).map(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2);
var key = _ref2[0];
var value = _ref2[1];
if (Array.isArray(value)) {
var _ret = (function () {
// inline-style-prefix-all returns an array when there should be
// multiple rules, we will flatten to single rules
var prefixedValues = [];
var unprefixedValues = [];
value.forEach(function (v) {
if (v.indexOf('-') === 0) {
prefixedValues.push(v);
} else {
unprefixedValues.push(v);
}
});
prefixedValues.sort();
unprefixedValues.sort();
return {
v: prefixedValues.concat(unprefixedValues).map(function (v) {
return [key, v];
})
};
})();
if (typeof _ret === 'object') return _ret.v;
}
return [[key, value]];
}));
var rules = prefixedRules.map(function (_ref3) {
var _ref32 = _slicedToArray(_ref3, 2);
var key = _ref32[0];
var value = _ref32[1];
var stringValue = (0, _util.stringifyValue)(key, value);
var ret = (0, _util.kebabifyStyleName)(key) + ':' + stringValue + ';';
return useImportant === false ? ret : (0, _util.importantify)(ret);
}).join("");
if (rules) {
return selector + '{' + rules + '}';
} else {
return "";
}
};
exports.generateCSSRuleset = generateCSSRuleset;
},{"./util":3,"inline-style-prefixer/static":36}],2:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _asap = require('asap');
var _asap2 = _interopRequireDefault(_asap);
var _generate = require('./generate');
var _util = require('./util');
// The current <style> tag we are inserting into, or null if we haven't
// inserted anything yet. We could find this each time using
// `document.querySelector("style[data-aphrodite"])`, but holding onto it is
// faster.
var styleTag = null;
// Inject a string of styles into a <style> tag in the head of the document. This
// will automatically create a style tag and then continue to use it for
// multiple injections. It will also use a style tag with the `data-aphrodite`
// tag on it if that exists in the DOM. This could be used for e.g. reusing the
// same style tag that server-side rendering inserts.
var injectStyleTag = function injectStyleTag(cssContents) {
if (styleTag == null) {
// Try to find a style tag with the `data-aphrodite` attribute first.
styleTag = document.querySelector("style[data-aphrodite]");
// If that doesn't work, generate a new style tag.
if (styleTag == null) {
// Taken from
// http://stackoverflow.com/questions/524696/how-to-create-a-style-tag-with-javascript
var head = document.head || document.getElementsByTagName('head')[0];
styleTag = document.createElement('style');
styleTag.type = 'text/css';
styleTag.setAttribute("data-aphrodite", "");
head.appendChild(styleTag);
}
}
if (styleTag.styleSheet) {
styleTag.styleSheet.cssText += cssContents;
} else {
styleTag.appendChild(document.createTextNode(cssContents));
}
};
// Custom handlers for stringifying CSS values that have side effects
// (such as fontFamily, which can cause @font-face rules to be injected)
var stringHandlers = {
// With fontFamily we look for objects that are passed in and interpret
// them as @font-face rules that we need to inject. The value of fontFamily
// can either be a string (as normal), an object (a single font face), or
// an array of objects and strings.
fontFamily: function fontFamily(val) {
if (Array.isArray(val)) {
return val.map(fontFamily).join(",");
} else if (typeof val === "object") {
injectStyleOnce(val.fontFamily, "@font-face", [val], false);
return '"' + val.fontFamily + '"';
} else {
return val;
}
},
// With animationName we look for an object that contains keyframes and
// inject them as an `@keyframes` block, returning a uniquely generated
// name. The keyframes object should look like
// animationName: {
// from: {
// left: 0,
// top: 0,
// },
// '50%': {
// left: 15,
// top: 5,
// },
// to: {
// left: 20,
// top: 20,
// }
// }
// TODO(emily): `stringHandlers` doesn't let us rename the key, so I have
// to use `animationName` here. Improve that so we can call this
// `animation` instead of `animationName`.
animationName: function animationName(val) {
if (typeof val !== "object") {
return val;
}
// Generate a unique name based on the hash of the object. We can't
// just use the hash because the name can't start with a number.
// TODO(emily): this probably makes debugging hard, allow a custom
// name?
var name = 'keyframe_' + (0, _util.hashObject)(val);
// Since keyframes need 3 layers of nesting, we use `generateCSS` to
// build the inner layers and wrap it in `@keyframes` ourselves.
var finalVal = '@keyframes ' + name + '{';
Object.keys(val).forEach(function (key) {
finalVal += (0, _generate.generateCSS)(key, [val[key]], stringHandlers, false);
});
finalVal += '}';
injectGeneratedCSSOnce(name, finalVal);
return name;
}
};
// This is a map from Aphrodite's generated class names to `true` (acting as a
// set of class names)
var alreadyInjected = {};
// This is the buffer of styles which have not yet been flushed.
var injectionBuffer = "";
// A flag to tell if we are already buffering styles. This could happen either
// because we scheduled a flush call already, so newly added styles will
// already be flushed, or because we are statically buffering on the server.
var isBuffering = false;
var injectGeneratedCSSOnce = function injectGeneratedCSSOnce(key, generatedCSS) {
if (!alreadyInjected[key]) {
if (!isBuffering) {
// We should never be automatically buffering on the server (or any
// place without a document), so guard against that.
if (typeof document === "undefined") {
throw new Error("Cannot automatically buffer without a document");
}
// If we're not already buffering, schedule a call to flush the
// current styles.
isBuffering = true;
(0, _asap2['default'])(flushToStyleTag);
}
injectionBuffer += generatedCSS;
alreadyInjected[key] = true;
}
};
var injectStyleOnce = function injectStyleOnce(key, selector, definitions, useImportant) {
if (!alreadyInjected[key]) {
var generated = (0, _generate.generateCSS)(selector, definitions, stringHandlers, useImportant);
injectGeneratedCSSOnce(key, generated);
}
};
exports.injectStyleOnce = injectStyleOnce;
var reset = function reset() {
injectionBuffer = "";
alreadyInjected = {};
isBuffering = false;
styleTag = null;
};
exports.reset = reset;
var startBuffering = function startBuffering() {
if (isBuffering) {
throw new Error("Cannot buffer while already buffering");
}
isBuffering = true;
};
exports.startBuffering = startBuffering;
var flushToString = function flushToString() {
isBuffering = false;
var ret = injectionBuffer;
injectionBuffer = "";
return ret;
};
exports.flushToString = flushToString;
var flushToStyleTag = function flushToStyleTag() {
var cssContent = flushToString();
if (cssContent.length > 0) {
injectStyleTag(cssContent);
}
};
exports.flushToStyleTag = flushToStyleTag;
var getRenderedClassNames = function getRenderedClassNames() {
return Object.keys(alreadyInjected);
};
exports.getRenderedClassNames = getRenderedClassNames;
var addRenderedClassNames = function addRenderedClassNames(classNames) {
classNames.forEach(function (className) {
alreadyInjected[className] = true;
});
};
exports.addRenderedClassNames = addRenderedClassNames;
/**
* Inject styles associated with the passed style definition objects, and return
* an associated CSS class name.
*
* @param {boolean} useImportant If true, will append !important to generated
* CSS output. e.g. {color: red} -> "color: red !important".
* @param {Object[]} styleDefinitions style definition objects as returned as
* properties of the return value of StyleSheet.create().
*/
var injectAndGetClassName = function injectAndGetClassName(useImportant, styleDefinitions) {
// Filter out falsy values from the input, to allow for
// `css(a, test && c)`
var validDefinitions = styleDefinitions.filter(function (def) {
return def;
});
// Break if there aren't any valid styles.
if (validDefinitions.length === 0) {
return "";
}
var className = validDefinitions.map(function (s) {
return s._name;
}).join("-o_O-");
injectStyleOnce(className, '.' + className, validDefinitions.map(function (d) {
return d._definition;
}), useImportant);
return className;
};
exports.injectAndGetClassName = injectAndGetClassName;
},{"./generate":1,"./util":3,"asap":4}],3:[function(require,module,exports){
// {K1: V1, K2: V2, ...} -> [[K1, V1], [K2, V2]]
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var objectToPairs = function objectToPairs(obj) {
return Object.keys(obj).map(function (key) {
return [key, obj[key]];
});
};
exports.objectToPairs = objectToPairs;
// [[K1, V1], [K2, V2]] -> {K1: V1, K2: V2, ...}
var pairsToObject = function pairsToObject(pairs) {
var result = {};
pairs.forEach(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2);
var key = _ref2[0];
var val = _ref2[1];
result[key] = val;
});
return result;
};
var mapObj = function mapObj(obj, fn) {
return pairsToObject(objectToPairs(obj).map(fn));
};
exports.mapObj = mapObj;
// Flattens an array one level
// [[A], [B, C, [D]]] -> [A, B, C, [D]]
var flatten = function flatten(list) {
return list.reduce(function (memo, x) {
return memo.concat(x);
}, []);
};
exports.flatten = flatten;
var UPPERCASE_RE = /([A-Z])/g;
var MS_RE = /^ms-/;
var kebabify = function kebabify(string) {
return string.replace(UPPERCASE_RE, '-$1').toLowerCase();
};
var kebabifyStyleName = function kebabifyStyleName(string) {
return kebabify(string).replace(MS_RE, '-ms-');
};
exports.kebabifyStyleName = kebabifyStyleName;
var recursiveMerge = function recursiveMerge(a, b) {
// TODO(jlfwong): Handle malformed input where a and b are not the same
// type.
if (typeof a !== 'object') {
return b;
}
var ret = _extends({}, a);
Object.keys(b).forEach(function (key) {
if (ret.hasOwnProperty(key)) {
ret[key] = recursiveMerge(a[key], b[key]);
} else {
ret[key] = b[key];
}
});
return ret;
};
exports.recursiveMerge = recursiveMerge;
/**
* CSS properties which accept numbers but are not in units of "px".
* Taken from React's CSSProperty.js
*/
var isUnitlessNumber = {
animationIterationCount: true,
borderImageOutset: true,
borderImageSlice: true,
borderImageWidth: true,
boxFlex: true,
boxFlexGroup: true,
boxOrdinalGroup: true,
columnCount: true,
flex: true,
flexGrow: true,
flexPositive: true,
flexShrink: true,
flexNegative: true,
flexOrder: true,
gridRow: true,
gridColumn: true,
fontWeight: true,
lineClamp: true,
lineHeight: true,
opacity: true,
order: true,
orphans: true,
tabSize: true,
widows: true,
zIndex: true,
zoom: true,
// SVG-related properties
fillOpacity: true,
floodOpacity: true,
stopOpacity: true,
strokeDasharray: true,
strokeDashoffset: true,
strokeMiterlimit: true,
strokeOpacity: true,
strokeWidth: true
};
/**
* Taken from React's CSSProperty.js
*
* @param {string} prefix vendor-specific prefix, eg: Webkit
* @param {string} key style name, eg: transitionDuration
* @return {string} style name prefixed with `prefix`, properly camelCased, eg:
* WebkitTransitionDuration
*/
function prefixKey(prefix, key) {
return prefix + key.charAt(0).toUpperCase() + key.substring(1);
}
/**
* Support style names that may come passed in prefixed by adding permutations
* of vendor prefixes.
* Taken from React's CSSProperty.js
*/
var prefixes = ['Webkit', 'ms', 'Moz', 'O'];
// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
// infinite loop, because it iterates over the newly added props too.
// Taken from React's CSSProperty.js
Object.keys(isUnitlessNumber).forEach(function (prop) {
prefixes.forEach(function (prefix) {
isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
});
});
var stringifyValue = function stringifyValue(key, prop) {
if (typeof prop === "number") {
if (isUnitlessNumber[key]) {
return "" + prop;
} else {
return prop + "px";
}
} else {
return prop;
}
};
exports.stringifyValue = stringifyValue;
/**
* JS Implementation of MurmurHash2
*
* @author <a href="mailto:gary.court@gmail.com">Gary Court</a>
* @see http://github.com/garycourt/murmurhash-js
* @author <a href="mailto:aappleby@gmail.com">Austin Appleby</a>
* @see http://sites.google.com/site/murmurhash/
*
* @param {string} str ASCII only
* @return {string} Base 36 encoded hash result
*/
function murmurhash2_32_gc(str) {
var l = str.length;
var h = l;
var i = 0;
var k = undefined;
while (l >= 4) {
k = str.charCodeAt(i) & 0xff | (str.charCodeAt(++i) & 0xff) << 8 | (str.charCodeAt(++i) & 0xff) << 16 | (str.charCodeAt(++i) & 0xff) << 24;
k = (k & 0xffff) * 0x5bd1e995 + (((k >>> 16) * 0x5bd1e995 & 0xffff) << 16);
k ^= k >>> 24;
k = (k & 0xffff) * 0x5bd1e995 + (((k >>> 16) * 0x5bd1e995 & 0xffff) << 16);
h = (h & 0xffff) * 0x5bd1e995 + (((h >>> 16) * 0x5bd1e995 & 0xffff) << 16) ^ k;
l -= 4;
++i;
}
switch (l) {
case 3:
h ^= (str.charCodeAt(i + 2) & 0xff) << 16;
case 2:
h ^= (str.charCodeAt(i + 1) & 0xff) << 8;
case 1:
h ^= str.charCodeAt(i) & 0xff;
h = (h & 0xffff) * 0x5bd1e995 + (((h >>> 16) * 0x5bd1e995 & 0xffff) << 16);
}
h ^= h >>> 13;
h = (h & 0xffff) * 0x5bd1e995 + (((h >>> 16) * 0x5bd1e995 & 0xffff) << 16);
h ^= h >>> 15;
return (h >>> 0).toString(36);
}
// Hash a javascript object using JSON.stringify. This is very fast, about 3
// microseconds on my computer for a sample object:
// http://jsperf.com/test-hashfnv32a-hash/5
//
// Note that this uses JSON.stringify to stringify the objects so in order for
// this to produce consistent hashes browsers need to have a consistent
// ordering of objects. Ben Alpert says that Facebook depends on this, so we
// can probably depend on this too.
var hashObject = function hashObject(object) {
return murmurhash2_32_gc(JSON.stringify(object));
};
exports.hashObject = hashObject;
var IMPORTANT_RE = /^([^:]+:.*?)( !important)?;$/;
// Given a single style rule string like "a: b;", adds !important to generate
// "a: b !important;".
var importantify = function importantify(string) {
return string.replace(IMPORTANT_RE, function (_, base, important) {
return base + " !important;";
});
};
exports.importantify = importantify;
},{}],4:[function(require,module,exports){
"use strict";
// rawAsap provides everything we need except exception management.
var rawAsap = require("./raw");
// RawTasks are recycled to reduce GC churn.
var freeTasks = [];
// We queue errors to ensure they are thrown in right order (FIFO).
// Array-as-queue is good enough here, since we are just dealing with exceptions.
var pendingErrors = [];
var requestErrorThrow = rawAsap.makeRequestCallFromTimer(throwFirstError);
function throwFirstError() {
if (pendingErrors.length) {
throw pendingErrors.shift();
}
}
/**
* Calls a task as soon as possible after returning, in its own event, with priority
* over other events like animation, reflow, and repaint. An error thrown from an
* event will not interrupt, nor even substantially slow down the processing of
* other events, but will be rather postponed to a lower priority event.
* @param {{call}} task A callable object, typically a function that takes no
* arguments.
*/
module.exports = asap;
function asap(task) {
var rawTask;
if (freeTasks.length) {
rawTask = freeTasks.pop();
} else {
rawTask = new RawTask();
}
rawTask.task = task;
rawAsap(rawTask);
}
// We wrap tasks with recyclable task objects. A task object implements
// `call`, just like a function.
function RawTask() {
this.task = null;
}
// The sole purpose of wrapping the task is to catch the exception and recycle
// the task object after its single use.
RawTask.prototype.call = function () {
try {
this.task.call();
} catch (error) {
if (asap.onerror) {
// This hook exists purely for testing purposes.
// Its name will be periodically randomized to break any code that
// depends on its existence.
asap.onerror(error);
} else {
// In a web browser, exceptions are not fatal. However, to avoid
// slowing down the queue of pending tasks, we rethrow the error in a
// lower priority turn.
pendingErrors.push(error);
requestErrorThrow();
}
} finally {
this.task = null;
freeTasks[freeTasks.length] = this;
}
};
},{"./raw":5}],5:[function(require,module,exports){
(function (global){
"use strict";
// Use the fastest means possible to execute a task in its own turn, with
// priority over other events including IO, animation, reflow, and redraw
// events in browsers.
//
// An exception thrown by a task will permanently interrupt the processing of
// subsequent tasks. The higher level `asap` function ensures that if an
// exception is thrown by a task, that the task queue will continue flushing as
// soon as possible, but if you use `rawAsap` directly, you are responsible to
// either ensure that no exceptions are thrown from your task, or to manually
// call `rawAsap.requestFlush` if an exception is thrown.
module.exports = rawAsap;
function rawAsap(task) {
if (!queue.length) {
requestFlush();
flushing = true;
}
// Equivalent to push, but avoids a function call.
queue[queue.length] = task;
}
var queue = [];
// Once a flush has been requested, no further calls to `requestFlush` are
// necessary until the next `flush` completes.
var flushing = false;
// `requestFlush` is an implementation-specific method that attempts to kick
// off a `flush` event as quickly as possible. `flush` will attempt to exhaust
// the event queue before yielding to the browser's own event loop.
var requestFlush;
// The position of the next task to execute in the task queue. This is
// preserved between calls to `flush` so that it can be resumed if
// a task throws an exception.
var index = 0;
// If a task schedules additional tasks recursively, the task queue can grow
// unbounded. To prevent memory exhaustion, the task queue will periodically
// truncate already-completed tasks.
var capacity = 1024;
// The flush function processes all tasks that have been scheduled with
// `rawAsap` unless and until one of those tasks throws an exception.
// If a task throws an exception, `flush` ensures that its state will remain
// consistent and will resume where it left off when called again.
// However, `flush` does not make any arrangements to be called again if an
// exception is thrown.
function flush() {
while (index < queue.length) {
var currentIndex = index;
// Advance the index before calling the task. This ensures that we will
// begin flushing on the next task the task throws an error.
index = index + 1;
queue[currentIndex].call();
// Prevent leaking memory for long chains of recursive calls to `asap`.
// If we call `asap` within tasks scheduled by `asap`, the queue will
// grow, but to avoid an O(n) walk for every task we execute, we don't
// shift tasks off the queue after they have been executed.
// Instead, we periodically shift 1024 tasks off the queue.
if (index > capacity) {
// Manually shift all values starting at the index back to the
// beginning of the queue.
for (var scan = 0, newLength = queue.length - index; scan < newLength; scan++) {
queue[scan] = queue[scan + index];
}
queue.length -= index;
index = 0;
}
}
queue.length = 0;
index = 0;
flushing = false;
}
// `requestFlush` is implemented using a strategy based on data collected from
// every available SauceLabs Selenium web driver worker at time of writing.
// https://docs.google.com/spreadsheets/d/1mG-5UYGup5qxGdEMWkhP6BWCz053NUb2E1QoUTU16uA/edit#gid=783724593
// Safari 6 and 6.1 for desktop, iPad, and iPhone are the only browsers that
// have WebKitMutationObserver but not un-prefixed MutationObserver.
// Must use `global` or `self` instead of `window` to work in both frames and web
// workers. `global` is a provision of Browserify, Mr, Mrs, or Mop.
/* globals self */
var scope = typeof global !== "undefined" ? global : self;
var BrowserMutationObserver = scope.MutationObserver || scope.WebKitMutationObserver;
// MutationObservers are desirable because they have high priority and work
// reliably everywhere they are implemented.
// They are implemented in all modern browsers.
//
// - Android 4-4.3
// - Chrome 26-34
// - Firefox 14-29
// - Internet Explorer 11
// - iPad Safari 6-7.1
// - iPhone Safari 7-7.1
// - Safari 6-7
if (typeof BrowserMutationObserver === "function") {
requestFlush = makeRequestCallFromMutationObserver(flush);
// MessageChannels are desirable because they give direct access to the HTML
// task queue, are implemented in Internet Explorer 10, Safari 5.0-1, and Opera
// 11-12, and in web workers in many engines.
// Although message channels yield to any queued rendering and IO tasks, they
// would be better than imposing the 4ms delay of timers.
// However, they do not work reliably in Internet Explorer or Safari.
// Internet Explorer 10 is the only browser that has setImmediate but does
// not have MutationObservers.
// Although setImmediate yields to the browser's renderer, it would be
// preferrable to falling back to setTimeout since it does not have
// the minimum 4ms penalty.
// Unfortunately there appears to be a bug in Internet Explorer 10 Mobile (and
// Desktop to a lesser extent) that renders both setImmediate and
// MessageChannel useless for the purposes of ASAP.
// https://github.com/kriskowal/q/issues/396
// Timers are implemented universally.
// We fall back to timers in workers in most engines, and in foreground
// contexts in the following browsers.
// However, note that even this simple case requires nuances to operate in a
// broad spectrum of browsers.
//
// - Firefox 3-13
// - Internet Explorer 6-9
// - iPad Safari 4.3
// - Lynx 2.8.7
} else {
requestFlush = makeRequestCallFromTimer(flush);
}
// `requestFlush` requests that the high priority event queue be flushed as
// soon as possible.
// This is useful to prevent an error thrown in a task from stalling the event
// queue if the exception handled by Node.js’s
// `process.on("uncaughtException")` or by a domain.
rawAsap.requestFlush = requestFlush;
// To request a high priority event, we induce a mutation observer by toggling
// the text of a text node between "1" and "-1".
function makeRequestCallFromMutationObserver(callback) {
var toggle = 1;
var observer = new BrowserMutationObserver(callback);
var node = document.createTextNode("");
observer.observe(node, {characterData: true});
return function requestCall() {
toggle = -toggle;
node.data = toggle;
};
}
// The message channel technique was discovered by Malte Ubl and was the
// original foundation for this library.
// http://www.nonblocking.io/2011/06/windownexttick.html
// Safari 6.0.5 (at least) intermittently fails to create message ports on a
// page's first load. Thankfully, this version of Safari supports
// MutationObservers, so we don't need to fall back in that case.
// function makeRequestCallFromMessageChannel(callback) {
// var channel = new MessageChannel();
// channel.port1.onmessage = callback;
// return function requestCall() {
// channel.port2.postMessage(0);
// };
// }
// For reasons explained above, we are also unable to use `setImmediate`
// under any circumstances.
// Even if we were, there is another bug in Internet Explorer 10.
// It is not sufficient to assign `setImmediate` to `requestFlush` because
// `setImmediate` must be called *by name* and therefore must be wrapped in a
// closure.
// Never forget.
// function makeRequestCallFromSetImmediate(callback) {
// return function requestCall() {
// setImmediate(callback);
// };
// }
// Safari 6.0 has a problem where timers will get lost while the user is
// scrolling. This problem does not impact ASAP because Safari 6.0 supports
// mutation observers, so that implementation is used instead.
// However, if we ever elect to use timers in Safari, the prevalent work-around
// is to add a scroll event listener that calls for a flush.
// `setTimeout` does not call the passed callback if the delay is less than
// approximately 7 in web workers in Firefox 8 through 18, and sometimes not
// even then.
function makeRequestCallFromTimer(callback) {
return function requestCall() {
// We dispatch a timeout with a specified delay of 0 for engines that
// can reliably accommodate that request. This will usually be snapped
// to a 4 milisecond delay, but once we're flushing, there's no delay
// between events.
var timeoutHandle = setTimeout(handleTimer, 0);
// However, since this timer gets frequently dropped in Firefox
// workers, we enlist an interval handle that will try to fire
// an event 20 times per second until it succeeds.
var intervalHandle = setInterval(handleTimer, 50);
function handleTimer() {
// Whichever timer succeeds will cancel both timers and
// execute the callback.
clearTimeout(timeoutHandle);
clearInterval(intervalHandle);
callback();
}
};
}
// This is for `asap.js` only.
// Its name will be periodically randomized to break any code that depends on
// its existence.
rawAsap.makeRequestCallFromTimer = makeRequestCallFromTimer;
// ASAP was originally a nextTick shim included in Q. This was factored out
// into this ASAP package. It was later adapted to RSVP which made further
// amendments. These decisions, particularly to marginalize MessageChannel and
// to capture the MutationObserver implementation in a closure, were integrated
// back into ASAP proper.
// https://github.com/tildeio/rsvp.js/blob/cddf7232546a9cf858524b75cde6f9edf72620a7/lib/rsvp/asap.js
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],6:[function(require,module,exports){
module.exports = function chain(){
var len = arguments.length
var args = [];
for (var i = 0; i < len; i++)
args[i] = arguments[i]
args = args.filter(function(fn){ return fn != null })
if (args.length === 0) return undefined
if (args.length === 1) return args[0]
return args.reduce(function(current, next){
return function chainedFunction() {
current.apply(this, arguments);
next.apply(this, arguments);
};
})
}
},{}],7:[function(require,module,exports){
(function (process){
/**
* Copyright 2013-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 _assign = require('object-assign');
var emptyObject = require('fbjs/lib/emptyObject');
var _invariant = require('fbjs/lib/invariant');
if (process.env.NODE_ENV !== 'production') {
var warning = require('fbjs/lib/warning');
}
var MIXINS_KEY = 'mixins';
// Helper function to allow the creation of anonymous functions which do not
// have .name set to the name of the variable being assigned to.
function identity(fn) {
return fn;
}
var ReactPropTypeLocationNames;
if (process.env.NODE_ENV !== 'production') {
ReactPropTypeLocationNames = {
prop: 'prop',
context: 'context',
childContext: 'child context'
};
} else {
ReactPropTypeLocationNames = {};
}
function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
/**
* Policies that describe methods in `ReactClassInterface`.
*/
var injectedMixins = [];
/**
* Composite components are higher-level components that compose other composite
* or host 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 be available on the prototype.
*
* @interface ReactClassInterface
* @internal
*/
var ReactClassInterface = {
/**
* An array of Mixin objects to include when defining your component.
*
* @type {array}
* @optional
*/
mixins: '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: 'DEFINE_MANY',
/**
* Definition of prop types for this component.
*
* @type {object}
* @optional
*/
propTypes: 'DEFINE_MANY',
/**
* Definition of context types for this component.
*
* @type {object}
* @optional
*/
contextTypes: 'DEFINE_MANY',
/**
* Definition of context types this component sets for its children.
*
* @type {object}
* @optional
*/
childContextTypes: '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: '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: 'DEFINE_MANY_MERGED',
/**
* @return {object}
* @optional
*/
getChildContext: '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}
* @required
*/
render: '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: '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: '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: '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: '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: '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: '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: '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: '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 (process.env.NODE_ENV !== 'production') {
validateTypeDef(Constructor, childContextTypes, 'childContext');
}
Constructor.childContextTypes = _assign(
{},
Constructor.childContextTypes,
childContextTypes
);
},
contextTypes: function(Constructor, contextTypes) {
if (process.env.NODE_ENV !== 'production') {
validateTypeDef(Constructor, contextTypes, '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 (process.env.NODE_ENV !== 'production') {
validateTypeDef(Constructor, propTypes, 'prop');
}
Constructor.propTypes = _assign({}, Constructor.propTypes, propTypes);
},
statics: function(Constructor, statics) {
mixStaticSpecIntoComponent(Constructor, statics);
},
autobind: function() {}
};
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 only in __DEV__
if (process.env.NODE_ENV !== 'production') {
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(isAlreadyDefined, name) {
var specPolicy = ReactClassInterface.hasOwnProperty(name)
? ReactClassInterface[name]
: null;
// Disallow overriding of base class methods unless explicitly allowed.
if (ReactClassMixin.hasOwnProperty(name)) {
_invariant(
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 (isAlreadyDefined) {
_invariant(
specPolicy === 'DEFINE_MANY' || 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 classes.
*/
function mixSpecIntoComponent(Constructor, spec) {
if (!spec) {
if (process.env.NODE_ENV !== 'production') {
var typeofSpec = typeof spec;
var isMixinValid = typeofSpec === 'object' && spec !== null;
if (process.env.NODE_ENV !== 'production') {
warning(
isMixinValid,
"%s: You're attempting to include a mixin that is either null " +
'or not an object. Check the mixins included by the component, ' +
'as well as any mixins they include themselves. ' +
'Expected object but got %s.',
Constructor.displayName || 'ReactClass',
spec === null ? null : typeofSpec
);
}
}
return;
}
_invariant(
typeof spec !== 'function',
"ReactClass: You're attempting to " +
'use a component class or function as a mixin. Instead, just use a ' +
'regular object.'
);
_invariant(
!isValidElement(spec),
"ReactClass: You're attempting to " +
'use a component as a mixin. Instead, just use a regular object.'
);
var proto = Constructor.prototype;
var